<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Tim Docker</title>
    <link href="https://tim.dockerz.net/atom/programming.xml" rel="self" type="application/rss+xml" />
  <updated>2020-12-05T10:30:26Z</updated>
  <author>
      <name>Tim Docker</name>
  </author>
  <id>https://tim.dockerz.net/</id>

  <entry>
      <title>Homebrew flight simulator pedals</title>
      <link href="https://tim.dockerz.net//posts/2020-11-23-fsim-pedals.html"/>
      <id>https://tim.dockerz.net//posts/2020-11-23-fsim-pedals.html</id>
      <updated>2020-11-23T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>I plan to take some gliding lessons, and hope to accelerate my learning by spending some time on <a href="https://www.condorsoaring.com/">a simulator</a>. But I know this will only be worthwhile if the controls on the sim are a reasonable approximation of the real thing - you don't fly an aircraft with a keyboard and mouse. So I need some half decent controls: a joystick and pedals. It's not too hard to get an old but ok joystick on ebay, but flight sim pedals are expensive and hard to obtain here in Australia. So I set out to construct some of my own. Like all homebrew projects, this was more effort than I expected. But I'm happy with the results, and the project let me work on my 3D design and printing skills, and also some embedded rust development.</p>
<h1 id="the-hardware">The hardware</h1>
<p>A internet search for DIY flight pedals returns plenty of images, but few documented designs. I copied the simple mechanical arrangement commonly used, and set out to replicate it with a combination of aluminium tubing and 3D printed parts. 3D printing is excellent for small detailed components, but lacks the strength required for larger components, and takes too long to print them in any case. Hence I find that an approach using off-the-shelf dimensioned metal or timber from the local harware store, in combination with 3D printing parts works really well.</p>
<p>The photos below show the physical construction:</p>
<p><img src="/posts/2020-11-23-fsim-pedals/IMG_0022.JPEG" /> <img src="/posts/2020-11-23-fsim-pedals/IMG_0023.JPEG" /> <img src="/posts/2020-11-23-fsim-pedals/IMG_0024.JPEG" /></p>
<p>The 3D modelling was done with <a href="https://solvespace.com/index.pl">solvespace</a> for some components, and <a href="https://www.openscad.org/">openscad</a> for others. I favour open source cad tools for the same reason I prefer open source software tools: I want to own my creative efforts indefinitely, and only open source tooling can ensure this.</p>
<p>The 3D designs are relatively straightforward. If you have access to a 3D printer it's well worth lurking in places like <a href="https://hackaday.com">hackaday</a> to discover tips and trick - I use a couple here.</p>
<p>The <a href="https://github.com/timbod7/fsim-pedals/blob/master/3d-printing/lever-mount.stl">mounts</a> that attach to the baseboard embed M4 nuts inside them. The idea here is that you design the model with an internal void for the nut, and arrange for the 3D printer to pause for the nuts to be inserted, after which printing is resumed and the nut ends up completely encased. A photo of the paused print:</p>
<p><img src="/posts/2020-11-23-fsim-pedals/IMG_0007.JPEG" /></p>
<p>The ball joints connect the pedals to the lever arm via threaded rod. These are typically manufactured in metal, and are not inexpensive. The <a href="https://github.com/timbod7/fsim-pedals/blob/master/3d-printing/ball-joint.stl">3D printed design</a> I used came straight <a href="https://www.thingiverse.com/thing:4080588">from thingiverse</a>. It's clever in that the ball is printed within the socket that wraps it, with a gap that is tuned to be as tight as one's printer can support. In practice the ball end up slightly fused to the socket, but one simply snaps it loose one printing is completed. I'm surprised how well these joints works - they are smooth enough in operation, and there is little slack. The non-smooth plastic on plastic connection will almost certainly wear out with enough use, but in that case it would be a quick job to reprint replacements. In summary - good enough for this purpose!</p>
<h1 id="the-electronics">The electronics</h1>
<p>The electronics is so simple it doesn't warrant a schematic diagram. It is an off-the-shelf <a href="https://jeelabs.org/article/1649a/">blue pill development board</a>, with a 10k linear potentiometer wired as a voltage divider on to input pin A0. Power is supplied via the USB port.</p>
<h1 id="the-software">The software</h1>
<p>The <a href="https://www.rust-lang.org/">rust</a> programming language intrigues me. I love the idea of a statically typed, modern programming language that can fit into the niches currently dominated by C/C++. High performance code is one such niche, but another is the ability to run "bare metal" on cheap microcontrollers.</p>
<p>Hence while a common approach to building a custom USB <a href="https://en.wikipedia.org/wiki/USB_human_interface_device_class">HID controller</a> like this would be to use an arduino with a <a href="https://github.com/MHeironimus/ArduinoJoystickLibrary">usb joystick library</a> with code written in C++, I wanted to use rust, and chose the ubiquitous and cheap <a href="https://jeelabs.org/article/1649a/">"blue pill"</a> board. Getting an embedded development environment up and running can be a huge time suck - luckily this board is well supported in the embedded rust world, with the excellent <a href="https://github.com/TeXitoi/blue-pill-quickstart">blue-pill-quickstart</a> github template project. The project includes enough information to get up and running, and provides links to more detailed documentation. But at the end of it you've only made it as far as the "hello world" of embedded systems: a blinking led.</p>
<p>The requirements are simple, we need:</p>
<ul>
<li>Code to configure and manage the USB port so that it acts as a (single axis) HID joystick.</li>
<li>Code to measure the voltage from the potentiometer using the microcontrollers ADC (analog to digital converter), and supply it to the joystick interface</li>
</ul>
<p>But doing this from first principles would be a mammoth task. The reference manual for the microcontroller is 1100 pages, with the ADC documentation on pages 215-254, and the USB port on pages 622-652. And even if you studied that, you'd still need to read and understand large chunks of the USB specification to use it. The lesson here is that, even if the embedded computer is tiny, it's still highly complex and configurable, and just as on larger computers, we will need to leverage the libraries and code of others if we want to get things working in a reasonable amount of time.</p>
<p>The good news is that the embedded rust community is vibrant and has released a large collection of <a href="https://github.com/rust-embedded/awesome-embedded-rust">tools and libraries</a>. However, its a small community, and there's only limited examples and tutorials to act as guides. And this is one place where rust's programming power and expressiveness makes life harder for learners. In order to work with a wide range of microcontroller architectures, CPUs, and physical boards, the open source libraries are often quite abstract, and need to be composed in collections of abstract APIs and concrete implementations.</p>
<p>After research and trial and error I established that the following rust crates would be needed:</p>
<ul>
<li><a href="https://crates.io/crates/usb-device">usb-device</a> - abstract API for USB interfaces</li>
<li><a href="https://crates.io/crates/embedded-hal">embedded-hal</a> - Hardware Abstraction Layer for ADCs (and many other types of hardware)</li>
<li><a href="https://crates.io/crates/stm32f1xx-hal">stm32f1xx-hal</a>- implementations of the above abstractions for the cpu on the blue pill</li>
<li><a href="https://crates.io/crates/usbd-hid">usbd-hid</a> - protocol for HID USB devices</li>
</ul>
<p>with the overall project cargo dependencies being:</p>
<pre><code>[dependencies]
stm32f1xx-hal = { version = &quot;0.5.2&quot;, features = [&quot;rt&quot;, &quot;stm32-usbd&quot;, &quot;stm32f103&quot; ] }
cortex-m = &quot;0.6&quot;
cortex-m-rt = { version = &quot;0.6.8&quot;, features = [&quot;device&quot;] }
panic-semihosting = &quot;0.5.2&quot;
embedded-hal = &quot;0.2.4&quot;
usb-device = &quot;0.2.5&quot;
usbd-serial = &quot;0.1.0&quot;
usbd-hid = &quot;0.4.4&quot;</code></pre>
<p>My development strategy was somewhat simplistic - I started with the working blinking led demo, and mutated it by adding features one at at time, often cutting and pasting example code from elsewhere, and then incrementally changing it to what I needed. Whilst unsophisticated, this approach was quicker and easier than getting a deep understanding of each of the libraries I used. A blocker though was that I was unable to find an example of the usbd-hid library being used to implement a joystick. This meant that I had to gain sufficient understanding of the USB <a href="https://www.usb.org/document-library/device-class-definition-hid-111">HID specification</a> to write the <a href="https://github.com/timbod7/fsim-pedals/blob/master/software/fs-pedals/src/joystick.rs">descriptor</a> for a joystick.</p>
<p>Ultimately the <a href="https://github.com/timbod7/fsim-pedals/tree/master/software/fs-pedals/src">entire code</a> is currently only 160 lines of rust. But it was quite an effort to get there!</p>
<h1 id="more-details">More Details</h1>
<p>This project is not a design that I expect others to duplicate - there's several changes I'd make if I were to produce a second device. But in the interest of homebrew collaboration the code and 3d models are published in the project's <a href="https://github.com/timbod7/fsim-pedals">github repo</a>.</p>
<h1 id="future-plans">Future plans</h1>
<p>I was expecting to have to implement some calibration in the software, as the potentiometer only turns through a fraction of the total rotational range. And centering the pedals doesn't result in an exactly mid range value from the ADC. But it turns out that the standard PC joystick driver calibration deals with both these issues. I'd still like to sort this out in the embedded code, and not rely on the driver.</p>
<p>Also, I'd like to make an enclosure for the electronics with some additional desktop slider controls for glider trim, flaps, and airbrakes. But the setup works well enough to get some simulated flight time - and right now that's my priority.</p>
      ]]></content>
  </entry>
  <entry>
      <title>A typescript client for an ADL API</title>
      <link href="https://tim.dockerz.net//posts/2020-05-22-adl-example-typescript.html"/>
      <id>https://tim.dockerz.net//posts/2020-05-22-adl-example-typescript.html</id>
      <updated>2020-05-22T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <h1 id="introduction">Introduction</h1>
<p>This is the third post in a series where we use <a href="https://github.com/timbod7/adl">ADL</a> to build a multi-language system with consistent types. Previously, we have</p>
<ul>
<li><a href="/posts/2020-04-24-adl-example-api.html">defined the API in ADL</a></li>
<li><a href="/posts/2020-05-01-adl-example-haskell.html">implemented a server for the API in haskell</a></li>
</ul>
<p>Here we will implement a statically typed client for the API in typescript.</p>
<p>I think that typescript is presently a sweet spot for web development: it has a decent static type system; it integrates trivially with the rest of the javascript ecosystem; and it has achieved mainstream acceptance. Using ADL to ensure consistent types between the server and a typescript web application greatly boosts developer productivity, especially over time as the API grows.</p>
<h1 id="our-tools">Our tools</h1>
<p>In this post we will focus on a client library for the API, so our external dependencies will be limited. Later, we will create a full web application.</p>
<p>We'll keep our code small and leverage the typescript ecosystem, making use of just a <a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/typescript/package.json">few external dependencies</a>. At runtime:</p>
<ul>
<li><a href="https://www.npmjs.com/package/node-fetch">node-fetch</a> is used to so we can make API calls from the node VM (as well as the browser).</li>
<li><a href="https://www.npmjs.com/package/base64-js">base64-js</a> is required by the ADL typescript runtime</li>
</ul>
<h1 id="the-code-structure">The code structure</h1>
<p>For reference, the project code structure is as below. There are also the usual files to support typescript and yarn/npm.</p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">File</th>
<th style="text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/adl"><code>messageboard-api/adl/*</code></a></td>
<td style="text-align: left;">the ADL definitions</td>
</tr>
<tr class="even">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/scripts/generate-adl.sh"><code>messageboard-api/scripts/generate-adl.sh</code></a></td>
<td style="text-align: left;">script to generate code from ADL</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/typescript/src/adl"><code>messageboard-api/typescript/src/adl/*</code></a></td>
<td style="text-align: left;">typescript code generated from the ADL</td>
</tr>
<tr class="even">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/service.ts"><code>messageboard-api/typescript/src/service/service.ts</code></a></td>
<td style="text-align: left;">The service implementation</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/http.ts"><code>messageboard-api/typescript/src/service/http.ts</code></a></td>
<td style="text-align: left;">Abstraction for http communications</td>
</tr>
</tbody>
</table>
<h1 id="an-http-abstraction">An http abstraction</h1>
<p>We want to be able to make typed API requests from both the browser, and also from a nodejs VM. However the underlying machinery for making http requests differs in those environments. Hence we will build our typed API atop a trivial <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/http.ts">http abstraction</a>:</p>
<pre><code>export interface HttpFetch {
  fetch(request: HttpRequest): Promise&lt;HttpResponse&gt;;
}

export interface HttpHeaders {
  [index: string]: string;
}

export interface HttpRequest {
  url: string;
  headers: HttpHeaders;
  method: &quot;get&quot; | &quot;put&quot; | &quot;post&quot;;
  body?: string;
}

export interface HttpResponse {
  status: number;
  statusText: string;
  ok: boolean;
  text(): Promise&lt;string&gt;;
  json(): Promise&lt;{} | null&gt;;
}</code></pre>
<p>The two implementations of this are <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/node-http.ts">node-http.ts</a> and <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/browser-http.ts">browser-http.ts</a>.</p>
<h1 id="request-types-and-the-api-interface">Request types and the Api interface</h1>
<p>Referring back to the <a href="/posts/2020-04-24-adl-example-api.html">original API design</a>, there are two distinct types of requests: those that are public and don't require an auth token, and the authenticated requests that do. A public request in the ADL of type <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/adl/types.adl#L17"><code>HttpPost&lt;I,O&gt;</code></a> will be mapped to a <code>ReqFn&lt;I,O&gt;</code> in typescript:</p>
<pre><code>export type ReqFn&lt;I, O&gt; = (req: I) =&gt; Promise&lt;O&gt;;</code></pre>
<p>whereas an authenticated request in the ADL of type <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/adl/types.adl#L17"><code>HttpPost&lt;I,O&gt;</code></a> will be mapped to an <code>AuthReqFn&lt;I,O&gt;</code> in typescript:</p>
<pre><code>export type AuthReqFn&lt;I, O&gt; = (authToken: string, req: I) =&gt; Promise&lt;O&gt;;</code></pre>
<p>Given these types, our service matching the ADL type <code>Api</code> will meet this typescript interface:</p>
<pre><code>import * as API from &quot;../adl/api&quot;;

interface Api {
  login: ReqFn&lt;API.LoginReq, API.LoginResp&gt;;
  ping: ReqFn&lt;Empty, Empty&gt;;
  newMessage: AuthReqFn&lt;API.NewMessageReq,Empty&gt;;
  recentMessages: AuthReqFn&lt;API.RecentMessagesReq,API.Message[]&gt;;
  createUser: AuthReqFn&lt;API.CreateUserReq,API.CreateUserResp&gt;;
};</code></pre>
<p>The typescript code generated from the ADL contains sufficient metadata to be able to derive both the <code>ReqFn&lt;&gt;</code> or <code>AuthReqFn&lt;&gt;</code> without hand written code. As a concrete example, consider the the <code>recentMessages</code> ADL endpoint definition:</p>
<pre><code>  HttpPost&lt;RecentMessagesReq,Vector&lt;Message&gt;&gt; recentMessages = {
    &quot;path&quot; : &quot;/recent-messages&quot;,
    &quot;security&quot; : &quot;token&quot;
  };</code></pre>
<p>The typescript function that implements this will have type:</p>
<pre><code>AuthReqFn&lt;API.RecentMessagesReq,API.Message[]&gt;</code></pre>
<p>and needs to:</p>
<ul>
<li>Serialise the value of type <code>RecentMessagesReq</code> to json</li>
<li>Make an http post request to the <code>/recent-messages</code> path, with the json body and the provided auth token in the <code>Authorization</code> header.</li>
<li>Wait for the response</li>
<li>Deserialise the json response to a value of type <code>Message[]</code> and return as the result of the promise.</li>
</ul>
<p>We need equivalent logic for every authenticated request. The public requests are almost the same, leaving out the auth token and header.</p>
<p>In our typescript API client, we put the code for this abstracted request logic in the <code>ServiceBase</code> class:</p>
<pre><code>import { HttpFetch, HttpRequest } from &quot;./http&quot;;
import * as ADL from &quot;../adl/runtime/adl&quot;;
import { HttpPost } from &quot;../adl/types&quot;;

export class ServiceBase {
  
   constructor(
    private readonly http: HttpFetch,
    private readonly baseUrl: string,
    private readonly resolver: ADL.DeclResolver,
  ) {
  }
  
  mkPostFn&lt;I, O&gt;(rtype: HttpPost&lt;I, O&gt;): ReqFn&lt;I, O&gt; {...}

  mkAuthPostFn&lt;I, O&gt;(rtype: HttpPost&lt;I, O&gt;): AuthReqFn&lt;I, O&gt; {...}
};</code></pre>
<p>This class constructor needs the request abstraction <code>http</code>, the <code>baseUrl</code> to which requests will be made, and also the ADL <code>resolver</code>. A <code>DeclResolver</code> provides access to metadata for all ADL declarations. The class provides two member functions for constructing <code>ReqFn</code> or <code>AuthReqFn</code> values from ADL API endpoint definitions. The <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service/service-base.ts">implementation</a> of these two functions is straightforward.</p>
<h1 id="the-implementation">The implementation</h1>
<p>Given these functions in the <code>ServiceBase</code> class, the implementation of our client is straightforward. The entire code is:</p>
<pre><code>import { HttpFetch } from &quot;./http&quot;;
import * as ADL from &quot;../adl/runtime/adl&quot;;
import * as API from &quot;../adl/api&quot;;
import { AuthReqFn, ReqFn, ServiceBase } from &quot;./service-base&quot;;
import { Jwt, Empty } from &quot;../adl/types&quot;;

const api = API.makeApi({});

// Implements typed access to the authenticated API endpoints
export class Service extends ServiceBase {
  constructor(
    http: HttpFetch,
    baseUrl: string,
    resolver: ADL.DeclResolver,
  ) {
    super(http, baseUrl, resolver);
  }

  login: ReqFn&lt;API.LoginReq, API.LoginResp&gt; = this.mkPostFn(api.login);
  ping: ReqFn&lt;Empty, Empty&gt; = this.mkPostFn(api.ping);
  newMessage: AuthReqFn&lt;API.NewMessageReq,Empty&gt; = this.mkAuthPostFn(api.newMessage);
  recentMessages: AuthReqFn&lt;API.RecentMessagesReq,API.Message[]&gt; = this.mkAuthPostFn(api.recentMessages);
  createUser: AuthReqFn&lt;API.CreateUserReq,API.CreateUserResp&gt; = this.mkAuthPostFn(api.createUser);
};</code></pre>
<p>If a new endpoint is added to the API, then just a single line needs to be added to this implementation. And the end to end usage of ADL ensures that all of the types are consistent and compile time checked, from the server through to the client.</p>
<h1 id="testing">Testing</h1>
<p>First start the server, as per the <a href="/posts/2020-04-24-adl-example-api.html">previous post</a>:</p>
<pre><code>$ cd messageboard-api/haskell
$ stack run messageboard-server server-config.yaml

spock is running on port 8080</code></pre>
<p>Then we can write a simple typescript script to exercise our API from nodejs:</p>
<p>After some imports:</p>
<pre><code>import {Service} from &#39;./service/service&#39;;
import {NodeHttp} from &#39;./service/node-http&#39;;
import {RESOLVER} from &#39;./adl/resolver&#39;;
import * as API from &quot;./adl/api&quot;;</code></pre>
<p>we instantiate the service client:</p>
<pre><code>  const http = new NodeHttp();
  const service = new Service(http, &quot;http://localhost:8080&quot;, RESOLVER);</code></pre>
<p>and call the public ping endpoint:</p>
<pre><code>  await service.ping({});</code></pre>
<p>Logging in is also a public method, but on success returns a token so that we can subsequently call authenticated methods:</p>
<pre><code>  const resp = await service.login({
      email: &quot;admin@test.com&quot;,
      password: &quot;xyzzy&quot;,
    });
  assert(resp.kind == &#39;success&#39;);
  const adminToken = resp.value;</code></pre>
<p>Hence, as admin, we can post some messages:</p>
<pre><code>  await service.newMessage(adminToken, {body: &quot;Hello message board!&quot;});
  await service.newMessage(adminToken, {body: &quot;It&#39;s quiet around here!&quot;});```</code></pre>
<p>The <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/typescript/src/service-tests.ts"><code>service-tests.ts</code></a> script exercises the API more fully. You can run it directly using the <code>ts-node</code> command.</p>
<h1 id="summing-up">Summing Up</h1>
<p>We now have end-to-end type safety between our server and our client, despite the fact they are written in different languages. This is a big step forward in developer productivity. For example, one can extend or refactor the API using the same approach one would in any strongly statically typed environment: change it, and then be guided by the compiler errors to find and fix affected server and browser code.</p>
<p>I'm unsure what posts will follow in this series... I may look at:</p>
<ul>
<li>implementing the server in rust or typescript</li>
<li>using ADL to define a persistence layer behind the server</li>
<li>using this typescript API client in a react application</li>
</ul>
<p>Feel free to post questions and comments as issues on the <a href="https://github.com/timbod7/adl-demo">project repo</a>.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Implementing an ADL API in haskell</title>
      <link href="https://tim.dockerz.net//posts/2020-05-01-adl-example-haskell.html"/>
      <id>https://tim.dockerz.net//posts/2020-05-01-adl-example-haskell.html</id>
      <updated>2020-05-01T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <h1 id="introduction">Introduction</h1>
<p>This is the second post in a series where we use <a href="https://github.com/timbod7/adl">ADL</a> to build a multi-language system with consistent types. In the <a href="/posts/2020-04-24-adl-example-api.html">first post</a> we wrote the specification for the API. In this post we will implement a server for the API in haskell. This post presents key snippets of the server code - follow the links to the <a href="https://github.com/timbod7/adl-demo">source code repo</a> to see these in context.</p>
<h1 id="our-tools">Our tools</h1>
<p>We'll keep our code small and leverage the haskell ecosystem by making use of the following libraries:</p>
<ul>
<li>The <a href="https://hackage.haskell.org/package/Spock">Spock</a> web framework</li>
<li><a href="https://hackage.haskell.org/package/password-1.0.0.0">Data.Password</a> for secure password management</li>
<li><a href="https://hackage.haskell.org/package/jwt-0.10.0">Web.JWT</a> for Json Web Token functions</li>
</ul>
<h1 id="the-code-structure">The code structure</h1>
<p>For reference, the project code structure is as below. There are also the usual files to support stack and cabal.</p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">File</th>
<th style="text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/adl"><code>messageboard-api/adl/*</code></a></td>
<td style="text-align: left;">the ADL definitions</td>
</tr>
<tr class="even">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/scripts/generate-adl.sh"><code>messageboard-api/scripts/generate-adl.sh</code></a></td>
<td style="text-align: left;">script to generate code from ADL</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/haskell/src/ADL"><code>messageboard-api/haskell/src/ADL/*</code></a></td>
<td style="text-align: left;">haskell code generated from the ADL</td>
</tr>
<tr class="even">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Main.hs"><code>messageboard-api/haskell/src/Main.hs</code></a></td>
<td style="text-align: left;">startup and config parsing</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs"><code>messageboard-api/haskell/src/Server.hs</code></a></td>
<td style="text-align: left;">the server implementation</td>
</tr>
<tr class="even">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Utils.hs"><code>messageboard-api/haskell/src/Utils.hs</code></a></td>
<td style="text-align: left;">server helper functions</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/server-config.yaml"><code>messageboard-api/haskell/server-config.yaml</code></a></td>
<td style="text-align: left;">a server config file for testing</td>
</tr>
</tbody>
</table>
<h1 id="configuration-and-scaffolding">Configuration and scaffolding</h1>
<p>There's not much to do here. Our server <code>main</code> loads configuration, creates initial state, and launches spock. As described <a href="/posts/2020-05-01-adl-example-haskell.html">previously</a>, by defining our configuration in ADL:</p>
<pre><code>struct ServerConfig {

  /// The port which accepts http connections
  Int32 port = 8080;

  /// The secret used to sign the server&#39;s json web tokens
  String jwtSecret;
};</code></pre>
<p>we can use the ADL generated haskell code to validate and parse a YAML config file into a well typed <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/ADL/Config.hs#L17">haskell value</a>.</p>
<p>Loading the configuration is really the only point of interest in the scaffolding. After than, we just have to create our initial application state, and then launch spock:</p>
<pre><code>main :: IO ()
main = do
  args &lt;- getArgs
  case args of
    [configPath] -&gt; do
      eConfig &lt;- adlFromYamlFile configPath
      case eConfig of
        (Left emsg) -&gt; exitWithError (T.unpack emsg)
        (Right config) -&gt; startServer config
    _ -&gt; exitWithError &quot;Usage: server &lt;config.yaml&gt;&quot;
  
startServer :: ServerConfig -&gt; IO ()
startServer sc = do
  state &lt;- initAppState sc
  spockCfg &lt;- defaultSpockCfg EmptySession PCNoDatabase state
  runSpock (fromIntegral (sc_port sc)) (spock spockCfg serverApp)</code></pre>
<p>(see <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Main.hs#L29">Main.hs</a>)</p>
<h1 id="our-server-structure">Our server structure</h1>
<p>We are using the ADL API definition discussed in the <a href="/posts/2020-04-24-adl-example-api.html">previous post</a>. For the purpose of this example, we will keep the application state in server memory and use haskell <a href="https://hackage.haskell.org/package/stm">STM</a> to manage concurrent access. (In a future post I'll show how we can implement a persistence layer that leverages ADL to define the persisted data model). Our application needs to maintain a list of the users allows to login, and the messages that have been sent. Here's the core state declaration:</p>
<pre><code>data User = User {
  u_email :: T.Text,
  u_hashedPassword :: T.Text,
  u_isAdmin :: Bool
}

data MyAppState = MyAppState {
  mas_serverConfig :: ServerConfig,
  mas_users:: TVar [User],             -- the users that can login
  mas_messages:: TVar [API.Message]    -- the messages that have been posted
}</code></pre>
<p>(see <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L29">Server.hs</a>)</p>
<p>Our spock endpoint handlers will have a somewhat intimidating return type:</p>
<pre><code>type MyHandler o = ActionCtxT MyContext (WebStateM () MySession MyAppState) o</code></pre>
<p>I recommend reading the spock documentation to understand this in detail, but in the context of this post, it's enough to know that <code>MyHandler</code> is a Monad within which one can</p>
<ul>
<li>use <code>liftIO</code> to run <code>IO</code> actions.</li>
<li>use <code>getState</code> to access the <code>MyAppState</code> value</li>
</ul>
<p>Let's delve into to the details of the login API endpoint. It has the following ADL definition:</p>
<pre><code>  HttpPost&lt;LoginReq,LoginResp&gt; login = {
    &quot;path&quot; : &quot;/login&quot;,
    &quot;security&quot; : &quot;public&quot;
  };

struct LoginReq {
  Email email;
  String password;
};

union LoginResp {
  Jwt success;
  Void failure;
};</code></pre>
<p>which, thanks to the ADL compiler, results in haskell definitions for <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/ADL/Api.hs#L103">LoginReq</a>, <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/ADL/Api.hs#L124">LoginResp</a>, and the http request <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/ADL/Api.hs#L47">metadata</a>.</p>
<p>So our login handler will have the following signature:</p>
<pre><code>handleLogin :: API.LoginReq -&gt; MyHandler API.LoginResp</code></pre>
<p>We will write a helper function <code>adlPost</code> that, given the appropriate <code>HttpPost&lt;I,O&gt;</code> metadata connects our handler to the spock server. By "connects" I mean that it will:</p>
<ul>
<li>route post requests with the declared path</li>
<li>check authentication</li>
<li>deserialize and validate the post request body into the appropriate <code>I</code> value</li>
<li>call our handler implementation</li>
<li>serialize the <code>O</code> value, and send it as the post response body.</li>
</ul>
<p>The <code>adlPost</code> helper function will have the following signature:</p>
<pre><code>adlPost :: (AdlValue i, AdlValue o)
        =&gt; HttpPost i o
        -&gt; (i -&gt; MyHandler o)
        -&gt; SpockCtxM ctx conn sess MyAppState ()</code></pre>
<p>(The actual implementation will have a slightly more general type to avoid dependence on <code>MyAppState</code> - see below).</p>
<p>This helper function makes implement the spock API very easy. Our spock server is implemented simply by connecting each handler:</p>
<pre><code>serverApp :: SpockM () MySession MyAppState ()
serverApp = do
  let api = API.mkApi
  adlPost (API.api_login api) handleLogin
  adlPost (API.api_newMessage api) handleNewMessage
  adlPost (API.api_recentMessages api) handleRecentMessages
  adlPost (API.api_createUser api) handleCreateUser
  adlPost (API.api_ping api) handlePing</code></pre>
<p>(see <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L57">Server.hs</a>)</p>
<p>with each handler having the expected, strongly typed signature:</p>
<pre><code>handleLogin :: API.LoginReq -&gt; MyHandler API.LoginResp
handleNewMessage :: API.NewMessageReq -&gt; MyHandler Empty
handleRecentMessages :: API.RecentMessagesReq -&gt; MyHandler [API.Message]
handleCreateUser :: API.CreateUserReq -&gt; MyHandler API.CreateUserResp</code></pre>
<h1 id="implementing-adlpost">Implementing <code>adlPost</code></h1>
<p>As described above, the <code>adlPost</code> function will deal with the endpoint routing, authentication, validation and serialization, ie pretty much all of the boilerplate code typically required for an endpoint. Whilst it has quite a lot to do, it's relatively concise - lets show the code in full here:</p>
<pre><code>-- | Add a spock route implementing an http post request, with the specification for
-- the request supplied as a value of type HttpPost.
--
-- Assuming a request body of type i, and a response body of type o, the resulting
-- handler implements JWT based authorization checks, and request and response parsing
-- and serialization.
adlPost :: (AdlValue i, AdlValue o, HasJwtSecret st)
        =&gt; HttpPost i o
        -&gt; (i -&gt; ActionCtxT (Maybe JWTClaimsSet) (WebStateM conn sess st) o)
        -&gt; SpockCtxM ctx conn sess st ()
adlPost postmeta handler = prehook checkAuth $ post path runRequest
  where
    path = fromString (T.unpack (hp_path postmeta))

    checkAuth = do
      jwtSecret &lt;- getJwtSecret &lt;$&gt; getState
      case hp_security postmeta of
        HS_public -&gt; return Nothing
        HS_token -&gt; Just &lt;$&gt; getVerifiedJwtClaims jwtSecret
        HS_adminToken -&gt; do
          claims &lt;- getVerifiedJwtClaims jwtSecret
          when (not (isAdmin claims)) $ do
            error401 &quot;needs admin&quot;
          return (Just claims)

    runRequest = do
      mjv &lt;- jsonBody
      case mjv of
        Nothing -&gt; error400 &quot;json body not well formed&quot;
        (Just jv) -&gt; do
          let pv = runJsonParser jsonParser [] jv
          case decodeAdlParseResult &quot; from post body &quot; pv of
            Left e -&gt; error400 e
            Right i -&gt; do
              o &lt;- handler i
              json (adlToJson o)</code></pre>
<p>(see <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Utils.hs#L36">Utils.hs</a>)</p>
<p>It takes two parameters: <code>postmeta</code> is metadata describing the post request, and <code>handler</code> is the application handler function. The request and response bodies (type <code>i</code> and <code>o</code>) must be ADL values, (which they will be given that the postmeta value was generated by the ADL compiler). Our type signature is generalized from that show previously in that it can work with any spock state (type <code>st</code>) provided that we have a means of extracting a jwt secret from that state. This secret is needed to validate JWTs and hence check authorization.</p>
<p>It return a monadic value of type <code>SpockCtxM</code> which we used above to actually create the spock handler.</p>
<p><code>adlPost</code> works in two phases - it runs <code>checkAuth</code> as a <a href="http://hackage.haskell.org/package/Spock-core-0.13.0.0/docs/Web-Spock-Core.html#v:prehook">spock prehook</a>, and then runs the request as a <a href="http://hackage.haskell.org/package/Spock-core-0.13.0.0/docs/Web-Spock-Core.html#v:post">spock post action</a>.</p>
<p><code>checkAuth</code> performs case analysis to ensure that the incoming request meets the security requirements for the endpoint as per the <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/adl/api.adl">api spec</a>. If the endpoint is public there is no check to perform. If the endpoint requires a token, we verify that the request has a correctly signed Json Web Token. If the endpoint requires an admin token, we also verify that the valid JWT has an <code>isAdmin</code> claim. The prehook returns the JWT, which hence becomes the spock request context. This context is accessible in request handlers.</p>
<p>Assuming that we pass the authorization checks, <code>runRequest</code></p>
<ul>
<li>extracts the post request body as json</li>
<li>parses the json into a value of type <code>i</code></li>
<li>calls the application handler</li>
<li>serializes the result of type <code>o</code> into json</li>
<li>sends that response back to the API client (with a response code of 200)</li>
</ul>
<p>If either of the first two steps fails, a bad request (400) response code will result.</p>
<p>Whew! Quite a lot of explanatory text for a small function. But it's a tribute to haskell's expressiveness that we can write a function sufficiently abstract that that it implements the API boilerplate for our whole API.</p>
<h1 id="implementing-the-application-logic">Implementing the application logic</h1>
<p>Whilst the main goal for this post was to demonstrate ADL API definitions, let's complete the server by fleshing out the API application logic. We've got 4 methods to implement:</p>
<h2 id="handlelogin--apiloginreq---myhandler-apiloginresp"><code>handleLogin :: API.LoginReq -&gt; MyHandler API.LoginResp</code></h2>
<p>The login endpoint needs to</p>
<ul>
<li>verify that a user with the given email address exists</li>
<li>verify that the password supplied matches the stored scrypt hash</li>
<li>construct a JWT for the user that embeds the email address and login</li>
</ul>
<p>The JWT (<a href="https://jwt.io/introduction/">JSON Web Token</a>) is returned to the client, and is subequently provided to the server as proof that a login has succeeded.</p>
<p>See <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L69">Server.handleLogin</a> for the implementation code.</p>
<h2 id="handlenewmessage--apinewmessagereq---myhandler-empty"><code>handleNewMessage :: API.NewMessageReq -&gt; MyHandler Empty</code></h2>
<p>The new message endpoint simply accepts message text from the client, and appends it and some metadata to the message list in the server state. The implementation accesses the spock request context to recover the JWT (already validated by <code>postAdl</code>), in order to determine the email of the user posting the message.</p>
<p>See <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L94">Server.handleNewMessage</a> for the implementation code.</p>
<h2 id="handlerecentmessages--apirecentmessagesreq---myhandler-apimessage"><code>handleRecentMessages :: API.RecentMessagesReq -&gt; MyHandler [API.Message]</code></h2>
<p>This endpoint is trivial - the handler just needs to extract the requested number of messages from the application state, and return them to the client.</p>
<p>See <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L110">Server.handleRecentMessages</a> for the implementation code.</p>
<h2 id="handlecreateuser--apicreateuserreq---myhandler-apicreateuserresp"><code>handleCreateUser :: API.CreateUserReq -&gt; MyHandler API.CreateUserResp</code></h2>
<p>In our application, only admin users are authorized to create new users, but that is specified in the API definition, and hence is checked before the handler is called. The handler must:</p>
<ul>
<li>verify that there is not an existing user with the requested email address, and if this is the case, indicate it to the client.</li>
<li>hash the provided password, and add the new user to the application state.</li>
</ul>
<p>See <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/haskell/src/Server.hs#L117">Server.handleCreateUser</a> for the implementation code.</p>
<h1 id="testing">Testing</h1>
<p>If you've checked out the <a href="https://github.com/timbod7/adl-demo">project source code</a>, you can build and run the server with stack:</p>
<pre><code>$ cd messageboard-api/haskell
$ stack run messageboard-server server-config.yaml

spock is running on port 8080</code></pre>
<p>Whilst we plan to build a strongly typed client for the API, we can test it now via curl. For demo purposes the initial app state includes a test user. Let's try issuing a post login request with an empty body:</p>
<pre><code>$ curl http://localhost:8080/login -d &#39;{}&#39;
Unable to parse a value of type api.LoginReq from post body : expected field email at $</code></pre>
<p>OK - the 400 error tells us what is wrong with our request. Let's fill it in correctly with the test user's details (as per the ADL <code>LoginReq</code> type):</p>
<pre><code>$ curl http://localhost:8080/login -d &#39;{
  &quot;email&quot;: &quot;admin@test.com&quot;,
  &quot;password&quot;: &quot;xyzzy&quot;
}&#39;

{&quot;success&quot;:&quot;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkbWluQHRlc3QuY29tIiwiYWRtaW4iOnRydWV9.1mZfzhRO_hubbFI2LNBj7wnYUwThTMlSfVaawenX33Y&quot;}$ </code></pre>
<p>Success. We now have a JWT for future requests as the initial test user. Put it in a shell variable, and let's see if there are any messages:</p>
<pre><code>$ JWT=...token...
$ curl http://localhost:8080/recent-messages -H &quot;Authorization:Bearer $JWT&quot; -d &#39;{
  &quot;maxMessages&quot;: 10
}&#39;

[]</code></pre>
<p>No. So let's post a few:</p>
<pre><code>$ curl http://localhost:8080/new-message -H &quot;Authorization:Bearer $JWT&quot; -d &#39;{
  &quot;body&quot;: &quot;First post!&quot;
}&#39;

{}
$ curl http://localhost:8080/new-message -H &quot;Authorization:Bearer $JWT&quot; -d &#39;{
  &quot;body&quot;: &quot;and a followup&quot;
}&#39;

{}</code></pre>
<p>... and check that we can fetch them (using <a href="https://stedolan.github.io/jq/">jq</a> to tidy up the formatting):</p>
<pre><code>$ curl -s http://localhost:8080/recent-messages -H &quot;Authorization:Bearer $JWT&quot; -d &#39;{
  &quot;maxMessages&quot;: 10
}&#39; | jq .

[
  {
    &quot;body&quot;: &quot;and a followup&quot;,
    &quot;postedAt&quot;: &quot;2020-05-04T09:32:11.258139377&quot;,
    &quot;postedBy&quot;: &quot;admin@test.com&quot;,
    &quot;id&quot;: &quot;2&quot;
  },
  {
    &quot;body&quot;: &quot;First post!&quot;,
    &quot;postedAt&quot;: &quot;2020-05-04T09:31:04.024827574&quot;,
    &quot;postedBy&quot;: &quot;admin@test.com&quot;,
    &quot;id&quot;: &quot;1&quot;
  }
]</code></pre>
<p>Finally, let's create a new user, and excercise the API as that user:</p>
<pre><code>$ curl -s http://localhost:8080/create-user -H &quot;Authorization:Bearer $JWT&quot; -d &#39;{
  &quot;email&quot;: &quot;user@test.com&quot;,
  &quot;password&quot;: &quot;notmuchofapassword&quot;,
  &quot;isAdmin&quot;: false
}&#39;

{&quot;success&quot;:&quot;2&quot;}

$ curl http://localhost:8080/login -d &#39;{
  &quot;email&quot;: &quot;user@test.com&quot;,
  &quot;password&quot;: &quot;notmuchofapassword&quot;
}&#39;

{&quot;success&quot;:&quot;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXJAdGVzdC5jb20iLCJhZG1pbiI6ZmFsc2V9.48FYSck2FwaBwQgwhBIiQVH7ks5rmcvcPmSwoEpBZ6E&quot;}

$ JWT2=...token...
$ curl http://localhost:8080/new-message -H &quot;Authorization:Bearer $JWT2&quot; -d &#39;{
  &quot;body&quot;: &quot;Greetings!&quot;
}&#39;

{}

$ curl -s http://localhost:8080/recent-messages -H &quot;Authorization:Bearer $JWT2&quot; -d &#39;{
  &quot;maxMessages&quot;: 10
}&#39; | jq .

[
  {
    &quot;body&quot;: &quot;Greetings!&quot;,
    &quot;postedAt&quot;: &quot;2020-05-04T09:45:16.443301183&quot;,
    &quot;postedBy&quot;: &quot;user@test.com&quot;,
    &quot;id&quot;: &quot;3&quot;
  },
  {
    &quot;body&quot;: &quot;and a followup&quot;,
    &quot;postedAt&quot;: &quot;2020-05-04T09:32:11.258139377&quot;,
    &quot;postedBy&quot;: &quot;admin@test.com&quot;,
    &quot;id&quot;: &quot;2&quot;
  },
  {
    &quot;body&quot;: &quot;First post!&quot;,
    &quot;postedAt&quot;: &quot;2020-05-04T09:31:04.024827574&quot;,
    &quot;postedBy&quot;: &quot;admin@test.com&quot;,
    &quot;id&quot;: &quot;1&quot;
  }
]</code></pre>
<h1 id="summing-up">Summing up</h1>
<p>With only a small amount of code, we have implemented our API in haskell, and abstracted out all of the boilerplate code associated with:</p>
<ul>
<li>de/serialization</li>
<li>validation</li>
<li>authorization</li>
</ul>
<p>leaving us to implement the application logic in a strongly typed framework. Hopefully the utility of using ADL to specify the API and associated data types is apparent. ADL's value increases with a more realistic project where:</p>
<ul>
<li>multiple languages are involved</li>
<li>the API grows, with more endpoints and more complex data types</li>
<li>the API evolves over time</li>
</ul>
<p>In my next post, I will demonstrate how we can build a typescript client for this API.</p>
<p>Feel free to post questions and comments as issues on the <a href="https://github.com/timbod7/adl-demo">project repo</a>.</p>
      ]]></content>
  </entry>
  <entry>
      <title>API specifications in ADL</title>
      <link href="https://tim.dockerz.net//posts/2020-04-24-adl-example-api.html"/>
      <id>https://tim.dockerz.net//posts/2020-04-24-adl-example-api.html</id>
      <updated>2020-04-24T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <h1 id="introduction">Introduction</h1>
<p>This post is the first of a series where I will demonstrate using the <a href="https://github.com/timbod7/adl">ADL</a> system to specify an HTTP based API, and implement conforming servers and clients in different programming languages.</p>
<p>In this post, I will explore how ADL can be used to specify APIs, and do this for a simple application. The API will be small enough for demonstration purposes, but will include login, authorization, and basic application functions.</p>
<p>Future posts will implement servers for this API in haskell and rust, and an API client in typescript (for use in the browser). The ADL type definitions will "glue" the multi-language system together, ensuring consistent static types between languages. Hence ADL's mantra:</p>
<blockquote>
<p>Consistent types everywhere!</p>
</blockquote>
<h1 id="why-not-use-">Why not use ...?</h1>
<p>In this post we are using ADL to define a API as one would with other API definition languages such as <a href="https://swagger.io/docs/specification/about/">openapi</a>, <a href="https://grpc.io/">grpc</a> and similar tools. ADL has some key benefits compared with such tools including:</p>
<ul>
<li>parameterized types (aka generics)</li>
<li><a href="https://github.com/timbod7/adl/blob/master/docs/backend-haskell.md#custom-types">custom type mappings</a></li>
<li>general purpose <a href="https://github.com/timbod7/adl/blob/master/docs/language.md#annotations">annotations</a></li>
</ul>
<p>More importantly ADL differs in that it is intended as a general purpose tool for data modelling. Here we are using in to specify an API, but it also appropriate for other purposes (eg specifying relational data models, automatically generated forms, <a href="https://tim.dockerz.net/posts/2019-09-17-hadl-haskell.html">type checked configuration files</a>, etc)</p>
<h1 id="our-application-and-its-api">Our application and it's API</h1>
<p>Our sample application is somewhat of a cliche: a multi-user message board. It will have the following features:</p>
<ul>
<li>Users must login to access the application</li>
<li>Once logged in, users can view recent messages and post new messages</li>
<li>Certain users will have "admin" privileges and they are able to create new users.</li>
</ul>
<p>Our API will be implemented conventionally: as JSON messages passed over HTTP. Given a specification of the API in ADL, the ADL compiler will be used to translate that specification into types and values in our programming languages of choice (here: haskell, rust and typescript). Then, in each of those programming languages we will write generic library code to interpret that specification and implement the boilerplate associated with serialization, validation, and authorization. We will be left to implement just the application logic itself.</p>
<p>ADL doesn't have any baked in knowledge of the HTTP protocol. So we must start by declaring a data type that captures our specification for an HTTP request. In our simplified API, all requests will be HTTP post requests. If one desired a more "<a href="https://en.wikipedia.org/wiki/Representational_state_transfer">RESTy</a>" api then there would be similar definitions for the other HTTP methods.</p>
<pre><code>// A post request with request body of type I, and response
// body of type O
struct HttpPost&lt;I,O&gt; {
  String path;
  HttpSecurity security;
  TypeToken&lt;I&gt; reqType = null;
  TypeToken&lt;O&gt; respType = null;
};

union HttpSecurity {
  // The endpoint is publically accessible
  Void public;

  // A JWT is required in a bearer authoration header
  Void token;

  // A JWT with an admin claim is required in a bearer authoration header
  Void adminToken;
};</code></pre>
<p>Let's pull this definition apart. For each API request we can make we need to specify:</p>
<ul>
<li>the type of the request body sent to the server: <code>I</code></li>
<li>the type of the response returned to the client: <code>O</code></li>
<li>the http path for this request</li>
<li>the authorization rules for this endpoint.</li>
</ul>
<p>As per the subsequent <code>HttpSecurity</code> definition, in our simple security model API endpoints can be public, or require a token (proving that a user has logged in), or requiring an admin token (proving that a user has logged in and has admin rights).</p>
<p>The <code>HttpPost</code> structure captures all this information as a runtime value which we will interpret with library code to implement all of the boilerplate for our the endpoints. Hence we will need access to a runtime representation of the <code>I</code> and <code>O</code> types using the ADL <code>TypeToken&lt;&gt;</code> primitive.</p>
<p>This all probably seems a bit abstract, so lets now use <code>HttpPost</code> to define our first endpoint:</p>
<pre><code>struct Api {

  HttpPost&lt;LoginReq,LoginResp&gt; login = {
    &quot;path&quot; : &quot;/login&quot;,
    &quot;security&quot; : &quot;public&quot;
  };
  
  ...
};

struct LoginReq {
  Email email;
  String password;
};

union LoginResp {
  Jwt success;
  Void failure;
};

type Jwt = String;
type Email = String;</code></pre>
<p>Our runtime inspectable API will be a value of type <code>Api</code>. This is a struct, with a field for each request endpoint. We use the ADL <a href="https://github.com/timbod7/adl/blob/master/docs/language.md#default-values">defaulting mechanism</a> to specify the values associated with each endpoint.</p>
<p>As you can see above, the login endpoint will accept a Json serialized value of type <code>LoginReq</code>, and return a <code>LoginResp</code> sum type value, with a <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">Json Web Token</a> on success. It's a public endpoint, so doesn't require authentication to call.</p>
<p>Let's flesh out the remaining API methods to complete our API definition:</p>
<pre><code>struct Api {
  /// Login to obtain an authorization token
  HttpPost&lt;LoginReq,LoginResp&gt; login = {
    &quot;path&quot; : &quot;/login&quot;,
    &quot;security&quot; : &quot;public&quot;
  };

  /// Retrieve recent messages posted to the server
  HttpPost&lt;RecentMessagesReq,Vector&lt;Message&gt;&gt; recentMessages = {
    &quot;path&quot; : &quot;/recent-messages&quot;,
    &quot;security&quot; : &quot;token&quot;
  };

  /// Post a new message
  HttpPost&lt;NewMessageReq,Empty&gt; newMessage = {
    &quot;path&quot; : &quot;/new-message&quot;,
    &quot;security&quot; : &quot;token&quot;
  };

  /// Create a new user, recording their hashed password
  HttpPost&lt;CreateUserReq,CreateUserResp&gt; createUser = {
    &quot;path&quot; : &quot;/create-user&quot;,
    &quot;security&quot; : &quot;adminToken&quot;
  };

  /// Trivial public method to test server liveness
  HttpPost&lt;Empty,Empty&gt; ping = {
    &quot;path&quot; : &quot;/ping&quot;,
    &quot;security&quot; : &quot;public&quot;
  };
};

...

struct NewMessageReq {
  String body;
};

struct RecentMessagesReq {
  Int32 maxMessages;
};

struct CreateUserReq {
  Email email;
  Password password;
  Bool isAdmin;
};

union CreateUserResp {
  UserId success;
  Void duplicateEmail;
};

struct Message {
  String id;
  Email postedBy;
  TimeStamp postedAt;
  String body;
};</code></pre>
<p>Hopefully these methods should be fairly self explanatory.</p>
<p>The <a href="https://github.com/timbod7/adl-demo">timbod7/adl-demo</a> github repository will host the code for this blog post series. It currently contains</p>
<ul>
<li>the <a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/adl">ADL definitions</a></li>
<li>the <a href="https://github.com/timbod7/adl-demo/blob/master/messageboard-api/scripts/generate-adl.sh">script</a> to do the code generation</li>
<li>the generated <a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/haskell/src/ADL">haskell</a> and <a href="https://github.com/timbod7/adl-demo/tree/master/messageboard-api/typescript/src/adl">typescript</a></li>
</ul>
<p>Feel free to ask questions in this repo's issue tracker.</p>
<h1 id="next">Next...</h1>
<p>The API is defined, my next post will implement a compliant server in haskell. My previous post on <a href="https://tim.dockerz.net/posts/2019-09-17-hadl-haskell.html">using ADL from haskell</a> may be useful background reading.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Optionality and defaulting in ADL</title>
      <link href="https://tim.dockerz.net//posts/2020-04-17-optionality-in-adl.html"/>
      <id>https://tim.dockerz.net//posts/2020-04-17-optionality-in-adl.html</id>
      <updated>2020-04-17T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p><a href="https://github.com/timbod7/adl">ADL</a> is a data modeling language, which also specifies a <a href="https://github.com/timbod7/adl/blob/master/docs/serialization.md">serialization schema</a>. Values can be be optional in the data model, and independently defaulted in deserialization and value construction.</p>
<p>In ADL, optionality in the data model is part of a value's type. One uses either the <code>Nullable&lt;T&gt;</code> <a href="https://github.com/timbod7/adl/blob/master/docs/language.md#primitive-types">primitive</a> or the <code>Maybe&lt;T&gt;</code> type from the <a href="https://github.com/timbod7/adl/blob/master/adl/stdlib/sys/types.adl">adl standard library</a>. For example:</p>
<pre><code>struct Person {
  String name;
  Nullable&lt;String&gt; phoneNumber;
};</code></pre>
<p>In our model, every person has a name, but a having phone number is optional. But according to the ADL serialization <a href="https://github.com/timbod7/adl/blob/master/docs/serialization.md">specification</a>, both fields must still be present in the serialized value. Hence <code>{"name":"Tim"}</code> is invalid. If Tim doesn't have a phone, you'd need to serialize as <code>{"name":"Tim": "phoneNumber": null}</code>.</p>
<p>If you want a field to be defaulted in the serialized form, you must provide a default value in the ADL type, ie:</p>
<pre><code>struct Person {
  String name;
  Nullable&lt;String&gt; phoneNumber = null;
};</code></pre>
<p>With this type, <code>{"name":"Tim"}</code> would be a valid value. (Note that defaults can be fully structured values, not just primitives)</p>
<p>This distinction is important, as it's often useful to have default values that are not optional. Consider when we need to extend Person with gender information. If we do it in this way:</p>
<pre><code>struct Person {
  String name;
  Nullable&lt;String&gt; phoneNumber = null;
  Gender gender = &quot;unspecified&quot;;
};

union Gender {
  Void female;
  Void male;
  Void unspecified;
};</code></pre>
<p>then every pre-existing serialized Person value will still be valid, and will assume a gender value of unspecified.</p>
<p>Another use for defaults without optionality is where we have large data types with many fields values, most of which are defaulted. As a concrete example, consider a configuration for an application web server:</p>
<pre><code>struct MyAppServerConfig {
  DbConnectionConfig dbConnection;
  
  Word16 httpPort = 8080;
  LogLevel logLevel = &quot;error&quot;;
};

struct DbConnectionConfig {
  String host;
  Word16 port = 5432;
  String dbName = &quot;myapp&quot;;
  String username;
  String password;
  Word16 connectionPoolMinSize = 4;
  Word16 connectionPoolMaxSize = 16;
};</code></pre>
<p>In this case one only needs to provide values for the db host, username and password and can rely on the defaults for the other fields:</p>
<pre><code>{
  &quot;dbConnection&quot; : {
    &quot;host&quot;: &quot;localhost&quot;,
    &quot;username&quot;: &quot;test&quot;,
    &quot;password&quot;: &quot;test&quot;
  }
}</code></pre>
<p>Note that defaults are not only used in deserialization. In the ADL language backends only the non defaulted fields need to be specified when constructing an in memory ADL value.</p>
<h2 id="on-maybet-vs-nullablet">on Maybe&lt;T&gt; vs Nullable&lt;T&gt;</h2>
<p>As mentioned above, ADL has two parameterized types representing optionality: the <code>Nullable&lt;T&gt;</code> <a href="https://github.com/timbod7/adl/blob/master/docs/language.md#primitive-types">primitive</a> or the <code>Maybe&lt;T&gt;</code> type from the <a href="https://github.com/timbod7/adl/blob/master/adl/stdlib/sys/types.adl">adl standard library</a>.</p>
<p>Originally ADL didn't have the Nullable primitive, relying on <code>Maybe&lt;T&gt;</code> from the ADL standard library, with the expect definition as a and ADL union (ie sum type). A consequence with <code>Maybe&lt;T&gt;</code> defined in ADL that way is that the serialised Json is as it would be for any other union: <code>"nothing"</code> or <code>{"just": t}</code>. I was fine with this, but some users strongly prefer to see <code>null</code> or <code>t</code> in the json. So the <code>Nullable&lt;T&gt;</code> primitive was added, that serializes in the way that people expect.</p>
<p>Note that <code>Nullable&lt;T&gt;</code> is less expressive than <code>Maybe&lt;T&gt;</code> in that you can't usefully nest it. <code>Maybe&lt;Maybe&lt;T&gt;&gt;</code> is semantically useful, where as <code>Nullable&lt;Nullable&lt;T&gt;&gt;</code> is not, as the serialized representation can't represent all of the types values.</p>
<p>Hence <code>Nullable&lt;T&gt;</code> should only be used when <code>T</code> does not permit a serialized <code>null</code>. (TODO: make this a type check in the ADL compiler).</p>
      ]]></content>
  </entry>
  <entry>
      <title>A new home for my content</title>
      <link href="https://tim.dockerz.net//posts/2020-04-09-new-blog.html"/>
      <id>https://tim.dockerz.net//posts/2020-04-09-new-blog.html</id>
      <updated>2020-04-09T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>I'm planning to write more over the next few months, and want to move away from the wordpress free tier that has hosted this blog until now. So, I've migrated all existing content from</p>
<p><a href="https://twdkz.wordpress.com/">https://twdkz.wordpress.com/</a></p>
<p>to my new site at</p>
<p><a href="https://tim.dockerz.net/">https://tim.dockerz.net/</a></p>
<p>This is now hosted at github pages, and uses Chris Penner's <a href="https://github.com/ChrisPenner/slick">slick website generator</a>. slick is a</p>
<blockquote>
<p>a static site generator written and configured using Haskell... (it) provides a small set of tools and combinators for building static websites on top of the Shake build system</p>
</blockquote>
<p>It's worked out well for me so far.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Using ADL from haskell</title>
      <link href="https://tim.dockerz.net//posts/2019-09-17-hadl-haskell.html"/>
      <id>https://tim.dockerz.net//posts/2019-09-17-hadl-haskell.html</id>
      <updated>2019-09-17T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>The <a href="https://github.com/timbod7/adl">ADL</a> system has proven valuable at <a href="https://www.helixta.com.au/">Helix</a>. We use it in most of our projects, as a strongly typed schema language for specifying:</p>
<ul>
<li>http apis (in lieu of <a href="https://swagger.io/specification/">openapi/swagger</a>)</li>
<li>database schemas (in lieu of sql)</li>
<li>configuration files</li>
<li>user interface forms</li>
</ul>
<p>and then as the base for code generation in haskell, java, rust, c++ and typescript.</p>
<p>But, because ADL has a variety of uses, the path to getting started can be unclear. As a small stand alone example, this post shows how ADL can be used to specify the syntax of a <a href="https://en.wikipedia.org/wiki/YAML">yaml</a> configuration file, and automate its parsing into haskell.</p>
<p>To follow along with this project, you'll need the ADL compiler <a href="https://github.com/timbod7/adl/blob/master/docs/install.md">installed</a> and on your shell PATH.</p>
<p>We'll assume that our project is some sort of server which will load a yaml configuration at startup. Jumping right in, we can specify the config schema in a file <code>adl/config.adl</code>:</p>
<pre><code>module config {

struct ServerConfig {
  Int32 port;
  Protocol protocol = &quot;http&quot;;
  LogLevel logLevel = &quot;info&quot;;
};

union Protocol {
  Void http;
  SslConfiguration https;
};

struct SslConfiguration {
  FilePath certificate;
  FilePath certificateKey;
};

type FilePath = String;

union LogLevel {
  Void error;
  Void warn;
  Void info;
  Void debug;
  Void trace;
};

};</code></pre>
<p>Being minimal, our <code>ServerConfig</code> has a port, some protocol information, and a logging level. The port has no default value, so is required in the configuration. The other fields are optional, with the given defaults being used in their absence. Note the protocol field is a union (aka a sum type). If it is <code>http</code> then no other information is required. However, if the protocol is <code>https</code> then paths for ssl certificate details are required. The full syntax and meaning of ADL is in the <a href="https://github.com/timbod7/adl/blob/master/docs/language.md">language documentation</a>.</p>
<p>We've specified the data type for the server configuration, and we could now run the compiler to generate the corresponding haskell types and support code. The compiler does its best to generate idiomatic code in the target languages, but additional language specific information can improve the generated code. <a href="https://github.com/timbod7/adl/blob/master/docs/language.md#annotations">ADL annotations</a> are used for this. Such annotations can be included in-line in the adl source code, though this get a little noisy when annotations are included for multiple targets - it gets hard to see the core type definitions themselves in a sea of annotations.</p>
<p>Hence ADL has a standard pattern for language specific annotations: such annotations for an ADL file x.adl are kept in the file x.adl-lang. Hence the adl compiler, when reading <code>config.adl</code> to generate haskell code, will look for and include the adl file <code>config.adl-hs</code> for haskell related annotations.</p>
<p>In this example, <code>config.adl-hs</code> is straightforward:</p>
<pre><code>module config {

import adlc.config.haskell.*;

annotation ServerConfig HaskellFieldPrefix &quot;sc_&quot;;
annotation Protocol HaskellFieldPrefix &quot;p_&quot;;
annotation SslConfiguration HaskellFieldPrefix &quot;ssl_&quot;;
annotation LogLevel HaskellFieldPrefix &quot;log_&quot;;
};</code></pre>
<p>Recent language extensions notwithstanding, haskell's record system is somewhat primitive (try a google search for "haskell record problem"). A key issue is that record field names need to be unique in their containing module. To ensure this, by default, the haskell ADL code generator prefixes each field with its type name. Hence the <code>ServerConfig</code> declaration would generate:</p>
<pre><code>data ServerConfig = ServerConfig
    { serverConfig_port :: Data.Int.Int32
    , serverConfig_protocol :: Protocol
    , serverConfig_logLevel :: LogLevel
    }</code></pre>
<p>Whilst this guarantees that the generated code will compile, those field names are unwieldy. Hence the <a href="https://github.com/timbod7/adl/blob/master/haskell/compiler/lib/adl/adlc/config/haskell.adl#L3">HaskellFieldPrefix</a> annotation allows a custom (or no) prefix to be used. With the above <code>config.adl-hs</code> annotations, we get a more friendly:</p>
<pre><code>data ServerConfig = ServerConfig
    { sc_port :: Data.Int.Int32
    , sc_protocol :: Protocol
    , sc_logLevel :: LogLevel
    }</code></pre>
<p>With the ADL written it's time to run the ADL compiler to generate the haskell code:</p>
<pre><code>adlc haskell \
  --outputdir src \
  --package ADL \
  --rtpackage ADL.Core \
  --include-rt \
  --searchdir adl \
  adl/*.adl</code></pre>
<p>The <code>--include-rt</code> and <code>--rtpackage</code> arguments tell the code generator to include the runtime support files, making the generated code self contained. See the haskell backend <a href="https://github.com/timbod7/adl/blob/master/docs/backend-haskell.md">documentation</a> for details.</p>
<p>I generally check the generated code into the source repository. Whilst this approach has some drawbacks, it has benefits too:</p>
<ul>
<li>you don't need the ADL compiler installed to build the package</li>
<li>you can build with your off-the shelf standard build system (<a href="https://www.haskell.org/cabal/">cabal</a>, <a href="https://doc.rust-lang.org/cargo/">cargo</a>, <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html">tsc</a> etc)</li>
</ul>
<p>The main downside is that changing the source ADL requires explicitly rerunning the ADL compiler. In most projects I have a <code>scripts/generate-adl.sh</code> script to automate this step. Of course, if your build system is up to it, you may wish to generate the ADL derived code on demand.</p>
<p>We can now write some haskell code!</p>
<p>ADL's core serialization schema is json (a alternate binary scheme is planned). In the generated haskell, every ADL value is an instance of the <a href="https://github.com/timbod7/adl/blob/master/haskell/runtime/src/ADL/Core/Value.hs#L67">AdlValue</a> type class, and then the library has helper functions to automate deserialization:</p>
<pre><code>adlFromByteString :: AdlValue a =&gt; LBS.ByteString -&gt; ParseResult a
adlFromJsonFile :: AdlValue a =&gt; FilePath -&gt; IO (ParseResult a)
decodeAdlParseResult :: AdlValue a =&gt; T.Text -&gt; ParseResult a -&gt; Either T.Text a</code></pre>
<p>If one wished to have a configuration file in json format, the latter two functions are sufficient to read and parse such a file. But json is less than ideal for human written configuration, due to its lack of support for comments, and its rigid syntax. The ADL core doesn't have yaml support, but conveniently the haskell <a href="http://hackage.haskell.org/package/yaml">Data.Yaml</a> package can parse yaml into json values, which the ADL core can then parse into ADL values. This is the approach we will take, and we write a yaml specific function to load an arbitrary ADL value:</p>
<pre><code>import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as T
import qualified Data.Yaml as Y
import ADL.Core(runJsonParser, decodeAdlParseResult, AdlValue(..), ParseResult(..))

adlFromYamlFile :: AdlValue a =&gt; FilePath -&gt; IO (Either T.Text a)
adlFromYamlFile file = (decodeAdlParseResult from . adlFromYamlByteString) &lt;$&gt; (LBS.readFile file)
  where
    adlFromYamlByteString :: (AdlValue a) =&gt; LBS.ByteString -&gt; (ParseResult a)
    adlFromYamlByteString lbs = case Y.decodeEither&#39; (LBS.toStrict lbs) of
      (Left e) -&gt; ParseFailure (&quot;Invalid yaml:&quot; &lt;&gt; T.pack (Y.prettyPrintParseException e)) []
      (Right jv) -&gt; runJsonParser jsonParser [] jv

    from = &quot; from &quot; &lt;&gt; T.pack file</code></pre>
<p>Hopefully this is fairly self explanatory. It:</p>
<ul>
<li>reads the input file contents as a bytestring</li>
<li>parses the yaml parser into a in-memory json value</li>
<li>parses the in memory json value into an adl value</li>
</ul>
<p>whilst turning parse failures at either level into user friendly error messages.</p>
<p>With this helper function, the scaffolding for our server process is straightforward. We read an environment variable for the configuration file path, use the <code>adlFromYamlFile</code> written previously, and launch our (dummy) server code.</p>
<pre><code>main :: IO ()
main = do
  let configEnvVar = &quot;CONFIG_PATH&quot;
  mEnvPath &lt;- lookupEnv configEnvVar
  case mEnvPath of
    Nothing -&gt; exitWithError (configEnvVar &lt;&gt; &quot; not set in environment&quot;)
    (Just envPath) -&gt; do
      eConfig &lt;- adlFromYamlFile envPath
      case eConfig of
        (Left emsg) -&gt; exitWithError (T.unpack emsg)
        (Right config) -&gt; startServer config

exitWithError :: String -&gt; IO ()
exitWithError emsg = do
  hPutStrLn stderr emsg
  exitFailure
  
startServer :: ServerConfig -&gt; IO ()
startServer sc = do
  case sc_protocol sc of
    P_http -&gt; putStrLn (&quot;Starting http server on port &quot; ++ (show (sc_port sc)))
    P_https{} -&gt; putStrLn (&quot;Starting https server on port &quot; ++ (show (sc_port sc)))
  threadDelay 1000000000</code></pre>
<p>The simplest configuration yaml specifies just the port, relying on the ADL defaults for other fields:</p>
<pre><code>port: 8080</code></pre>
<p>An example that overrides the protocol, and hence must provide additional information:</p>
<pre><code>port: 8443
protocol:
  https:
    certificate: /tmp/certificate.crt
    certificateKey: /tmp/certificate.key</code></pre>
<p>The ADL json/yaml serialization schema is straightforward. One point of note is that ADL unions (like <code>Protocol</code> in the example) are serialized as single element objects. See the <a href="https://github.com/timbod7/adl/blob/master/docs/serialization.md">serialisation documentation</a> for details.</p>
<p>The parser provides helpful error messages. In the above example config, if you leave out the last line and fail to set the SSL key, the error is:</p>
<pre><code>Unable to parse a value of type config.ServerConfig from demo-server-example3.yaml:
expected field certificateKey at protocol.https</code></pre>
<p>Hopefully this post has given a simple but useful demonstration of ADL usage from haskell. It's really only a starting point - the ADL system's value increases dramatically when used to ensure consist types between systems written in multiple languages.</p>
<p>The complete code for this demonstration, include build and dependency configuration can be found in its <a href="https://github.com/timbod7/adl-demo-hs">github repo</a>.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Algebraic Data Types in Java</title>
      <link href="https://tim.dockerz.net//posts/2017-11-14-adl-java.html"/>
      <id>https://tim.dockerz.net//posts/2017-11-14-adl-java.html</id>
      <updated>2017-11-14T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>At <a href="http://www.helixta.com.au/">Helix</a> we often code backend services in java. I find modern java <em>acceptable</em> as a language for getting things done. As a long time haskell developer, however, I find java's facilities for data types frustrating indeed. These frustrations are twofold. Java lacks support for algebraic data types (<a href="https://en.wikipedia.org/wiki/Algebraic_data_type">ADTs</a>), and requires large amounts of boilerplate to define even simple types.</p>
<p>When designing systems, I place great value in applying the "make illegal states unrepresentable" principle[^1]. Using ADTs to more accurately model data is a excellent step in this direction. However, it's a burden to do in languages like java that lack support for <a href="https://en.wikipedia.org/wiki/Tagged_union">sum types</a>.</p>
<p>Even for regular product types (ie records of fields) java can be tedious. Defining a record of a few fields should really only take a corresponding few lines of code. Yet for a useful value type in java one will generally need to write: constructors, accessors, a comparison function, a hash implementation, serialisation logic etc. It's common in the java world to use IDEs to automatically generate this kind of boilerplate, but subtle bugs can creep in over time as the once generated code isn't manually updated to reflect subsequent changes in the data model.</p>
<p>Hence, at Helix we now often use my <a href="https://github.com/timbod7/adl">ADL language</a> to define data types, and generate the corresponding java code from them. As a tiny example, these adl definitions (see complete file <a href="https://github.com/timbod7/adl/blob/master/haskell/compiler/tests/demo1/input/picture.adl">here</a>):</p>
<pre><code>    struct Rectangle
    {
        Double width;
        Double height;
    };

    union Picture
    {
        Circle circle;
        Rectangle rectangle;
        Vector&lt;Picture&gt; composed;
        Translated&lt;Picture&gt; translated;
    };</code></pre>
<p>result in the corresponding <a href="https://github.com/timbod7/adl/blob/master/haskell/compiler/tests/demo1/java-output/adl/picture/Rectangle.java">Rectangle.java</a> and <a href="https://github.com/timbod7/adl/blob/master/haskell/compiler/tests/demo1/java-output/adl/picture/Translated.java">Picture.java</a>. These two definitions alone correspond to 280 lines of java code (that you really don't want to write and maintain). As can be seen in the <code>Translated&lt;&gt;</code> type, <a href="https://en.wikipedia.org/wiki/Parametric_polymorphism">parametric polymorphism</a> is supported.</p>
<p>I find that being able to define data types concisely encourages me to build more accurate data models, resulting in systems that are more robust and better reflect the problem domain. And ADL's multi language support (<a href="https://github.com/timbod7/adl/blob/master/doc/backend-java.md">java</a>, <a href="https://github.com/timbod7/adl/blob/master/doc/backend-haskell.md">haskell</a>, <a href="https://github.com/timbod7/adl/blob/master/doc/backend-typescript.md">typescript</a>) allows us to easily serialize and transfer the corresponding data values between our java services, and our typescript web and mobile UIs.</p>
      ]]></content>
  </entry>
  <entry>
      <title>An executable specification for voteflux</title>
      <link href="https://tim.dockerz.net//posts/2016-05-16-voteflux-spec.html"/>
      <id>https://tim.dockerz.net//posts/2016-05-16-voteflux-spec.html</id>
      <updated>2016-05-16T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p><a href="https://voteflux.org/">voteflux</a> is an interesting new political party, that will field senate candidates at the Australian federal election in July. It's sole policy is to implement <a href="https://en.wikipedia.org/wiki/Delegative_democracy">delegative democracy</a>, and to do this within the existing Australian political system. It intends to use blockchain technology to provide cryptographic guarantees to the voting process.</p>
<p>At the time of writing the voteflux software is incomplete, and there is not yet a rigorous specification for how the voting system will work. The voteflux website explains the system at a high level, but leaves questions unanswered. Discussions in the group's slack forums fill in some details, and the parties founders have answered some questions of my own.</p>
<p>In an effort to improve my own understanding of the voteflux ideas, and provide a basis for discussion with others, I've attempted to write an <a href="https://github.com/timbod7/flux-model">executable specification</a> for the system in Haskell. All of the key logic is in <a href="https://github.com/timbod7/flux-model/blob/master/src/Flux.hs">Flux.hs</a>. This was a worthwhile exercise - having to write concrete types and corresponding code made me consider many questions which weren't apparent when thinking less rigourously. Going forward, I intend to build some simulations based upon this code.</p>
<p>Note that this code has no endorsement from the voteflux party - it represents my own efforts to understand the proposed system. But I like their plans, and hope they do well in the election.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Haskell on Yosemite (OSX 10.10)</title>
      <link href="https://tim.dockerz.net//posts/2015-02-25-ghc-yosemite.html"/>
      <id>https://tim.dockerz.net//posts/2015-02-25-ghc-yosemite.html</id>
      <updated>2015-02-25T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <h1 id="update-2016-05-16">Update (2016-05-16)</h1>
<p>Most of the information below is now out of date. The <a href="http://docs.haskellstack.org/en/stable/README/">stack</a> build tool has made everything <em>much</em> simpler. Getting started just a case of installing with</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a><span class="ex">brew</span> install haskell-stack</span></code></pre></div>
<p>... and then leaving the management of ghc installations up to stack.</p>
<hr />
<h1 id="haskell-on-yosemite-osx-1010">Haskell on Yosemite (OSX 10.10)</h1>
<p>Nearly all my development has been done under linux. Only occasionally have I worked under osx. This is all to change - osx is to be my primary development platform. In the past, my experiences with ghc on osx have been a little fraught. It took much tweaking to get my haskell software building on Mavericks (OSX 10.9). Problems I had included:</p>
<ul>
<li><a href="https://ghc.haskell.org/trac/ghc/ticket/8197">issues</a> with ghc 7.6 and the xcode c preprocessor</li>
<li>manual management of the c dependencies of various packages, and then getting cabal to find them</li>
<li>getting gtk to build</li>
</ul>
<p>etc, etc.</p>
<p>I'm pleased to discover that things have improved immensely. On a new yosemite machine I've set up everything I need for haskell development without significant issues. A combination of 3 things work together:</p>
<ul>
<li>The <a href="https://ghcformacosx.github.io">"ghcformacosx"</a> minimal distribution</li>
<li>The <a href="http://brew.sh">brew</a> OSX package manager</li>
<li>Cabal sandboxes</li>
</ul>
<p>What follows is an overview of the steps I took to get up and running in haskell on osx 10.10.</p>
<h1 id="1-install-the-xcode-command-line-tools">1. Install the xcode command line tools</h1>
<p>Everything (including ghc) seems to depend on these.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="ex">xcode-select</span> --install</span></code></pre></div>
<h1 id="2-install-brew">2. Install Brew</h1>
<p>This is quick and easy, following the instructions on the <a href="http://brew.sh">brew homepage</a>.</p>
<h1 id="3-install-ghcformacosx">3. Install ghcformacosx</h1>
<p><a href="https://ghcformacosx.github.io">"ghcformacosx"</a> is a "drag and drop" installation of ghc 7.8.4 and cabal 1.22.0.0. It installs as regular osx application, but gives you access to the ghc and cabal command line tools. A nice feature is that if you run the application, it tells you what you need to do to set your environment up correctly, and shows a dashboard indicating whether you have done so:</p>
<p><img src="/posts/2015-02-25-ghc-yosemite/ghcformacosx.png" /></p>
<p>Once this is done you need to bring the local package database up to date:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1"></a><span class="ex">cabal</span> update</span></code></pre></div>
<h1 id="4-use-brew-to-install-some-key-tools-and-libraries">4. Use brew to install some key tools and libraries</h1>
<p>One of my libraries has <a href="https://hackage.haskell.org/package/pcre-light">pcre-light</a> as a transitive dependency. It needs a corresponding c library. Also cairo is the fastest rendering backend for my <a href="http://hackage.haskell.org/package/Chart">haskell charting library</a>, and gtk is necessary if you want to show charts in windows. Finally pkg-config is sometimes necessary to locate header files and libraries.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1"></a><span class="ex">brew</span> install pkg-config</span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="ex">brew</span> install pcre</span>
<span id="cb4-3"><a href="#cb4-3"></a></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="co"># gtk and cairo need xquartz</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="ex">brew</span> tap Caskroom/cask</span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="ex">brew</span> install Caskroom/cask/xquartz</span>
<span id="cb4-7"><a href="#cb4-7"></a></span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="co"># later steps in the build processes need to find libraries</span></span>
<span id="cb4-9"><a href="#cb4-9"></a><span class="co"># like xcb-shm via package config. Tell pkg-config</span></span>
<span id="cb4-10"><a href="#cb4-10"></a><span class="co"># where they are.</span></span>
<span id="cb4-11"><a href="#cb4-11"></a><span class="bu">export</span> <span class="va">PKG_CONFIG_PATH=</span>/opt/X11/lib/pkgconfig</span>
<span id="cb4-12"><a href="#cb4-12"></a></span>
<span id="cb4-13"><a href="#cb4-13"></a><span class="ex">brew</span> install cairo</span>
<span id="cb4-14"><a href="#cb4-14"></a><span class="ex">brew</span> install gtk</span></code></pre></div>
<p>A nice feature of brew is that whilst it installs libraries and headers to versioned directories in /usr/local/Cellar, it symlinks these back into the expected locations in /usr/local. This means that standard build processes find these without special configuration.</p>
<h1 id="5-setup-some-favorite-command-line-tools">5. Setup some favorite command line tools</h1>
<p>I use <a href="http://johnmacfarlane.net/pandoc/">pandoc</a> and <a href="https://hackage.haskell.org/package/ghc-mod">ghc-mod</a> alot, and still need <a href="http://darcs.net">darcs</a> sometimes. Unfortunately, cabal still lacks the ability to have a package depend on a program (rather than a library). Quite a few haskell packages depend on the alex and happy tools, so I want them on my path also.</p>
<p>I'm not sure it's idiomatic on osx, but I continue my linux habit of putting personal command line tools in ~/bin. I like to build all of these tools in a single cabal sandbox, and then link them into ~/bin. Hence, assuming ~/bin is on my path:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1"></a><span class="bu">cd</span> ~/bin</span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="fu">mkdir</span> hackage</span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="kw">(</span><span class="bu">cd</span> hackage <span class="kw">&amp;&amp;</span> <span class="ex">cabal</span> sandbox init<span class="kw">)</span></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="kw">(</span><span class="bu">cd</span> hackage <span class="kw">&amp;&amp;</span> <span class="ex">cabal</span> sandbox install alex happy<span class="kw">)</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/alex</span>
<span id="cb5-6"><a href="#cb5-6"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/happy</span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="kw">(</span><span class="bu">cd</span> hackage <span class="kw">&amp;&amp;</span> <span class="ex">cabal</span> sandbox install pandocc darcs ghc-mod<span class="kw">)</span></span>
<span id="cb5-8"><a href="#cb5-8"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/pandoc</span>
<span id="cb5-9"><a href="#cb5-9"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/darcs</span>
<span id="cb5-10"><a href="#cb5-10"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/ghc-mod</span></code></pre></div>
<p>(In the sequence above I had to make sure that alex and happy were linked onto the PATH before building ghc-mod)</p>
<h1 id="6-build-gtk2hs-in-its-own-sandbox">6. Build gtk2hs in its own sandbox</h1>
<p>The hard work is already done by brew. We can use build gtk2hs following the standard build instructions:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1"></a><span class="bu">export</span> <span class="va">PKG_CONFIG_PATH=</span>/opt/X11/lib/pkgconfig</span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="bu">export</span> <span class="va">PATH=</span>.cabal-sandbox/bin:<span class="va">$PATH</span></span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="fu">mkdir</span> gtk2hs</span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="bu">cd</span> gtk2hs</span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="ex">cabal</span> sandbox init</span>
<span id="cb6-6"><a href="#cb6-6"></a><span class="ex">cabal</span> install gtk2hs-buildtools</span>
<span id="cb6-7"><a href="#cb6-7"></a><span class="ex">cabal</span> install gtk</span></code></pre></div>
<p>Note how we need to ensure that the sandbox is on the path, so that the command line tools built in the first call to <code>cabal install</code> can be found in the second.</p>
<h1 id="summary">Summary</h1>
<p>All in all, this process was much smoother than before. Both ghcformacosx and brew are excellent pieces of work - kudos to their developers. ghc is, of course, as awesome as ever. When used with sandboxes cabal works well (despite the "cabal hell" reputation). However, having to manually resolve dependencies on build tools is tedious, I'd really like to see <a href="https://github.com/haskell/cabal/issues/220">this cabal issue</a> resolved.</p>
<h2 id="update-2015-03-01">Update [2015-03-01]</h2>
<p>One issue cropped up after this post. It turns out that ghc-mod has some <a href="https://github.com/kazu-yamamoto/ghc-mod/wiki/InconsistentCabalVersions">constraints on the combinations of ghc and cabal versions</a>, and unfortunately the combination provided in <a href="https://ghcformacosx.github.io">ghcformacosx</a> is not supported. I worked around this by installing a older version of cabal in ~/bin:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1"></a><span class="bu">cd</span> ~/bin/hackage</span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="ex">cabal</span> install --constraint <span class="st">&quot;Cabal &lt; 1.22&quot;</span> cabal-install</span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="bu">cd</span> ~/bin</span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="fu">ln</span> -s hackage/.cabal-sandbox/bin/cabal</span></code></pre></div>
      ]]></content>
  </entry>
  <entry>
      <title>A new charting API</title>
      <link href="https://tim.dockerz.net//posts/2014-09-06-chart-api.html"/>
      <id>https://tim.dockerz.net//posts/2014-09-06-chart-api.html</id>
      <updated>2014-09-06T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>One of the challenges with building a library like <a href="https://github.com/timbod7/haskell-chart">Chart</a> is the tension between ease of use and flexibility. Users want to produce charts with a minimum of code up front, but later want to refine the details. The chart library addresses this through the use of "defaulted records" using <a href="https://hackage.haskell.org/package/data-default-class-0.0.1/docs/Data-Default-Class.html">Data.Default.Class</a>. Because such records are often nested, we rely on the somewhat intimidating <a href="https://hackage.haskell.org/package/lens-1.2">lens</a> library to modify the default values. We end up with code to create chart elements like this:</p>
<pre><code>sinusoid2 = plot_points_title .~ &quot;fn(x)&quot;
          $ plot_points_values .~ mydata
          $ plot_points_style . point_color .~ opaque red
          $ def</code></pre>
<p>This is much simpler and cleaner that the corresponding code using native record accessors, but it still has a certain amount of syntactic overhead.</p>
<p>I've added a simple state monad to the library to further clean up the syntax. The state of the monad is the value being constructed, allowing the use of the monadic lens operators. The above code sample becomes:</p>
<pre><code>sinusoid2 = execEC $ do
    plot_points_title .= &quot;fn(x)&quot; 
    plot_points_values .= mydata
    plot_points_style . point_color .= opaque red</code></pre>
<p>This may seem only a minor syntactic improvement, but it adds up over an typical chart definition.</p>
<p>A few other changes further reduce the clutter in charting code:</p>
<ul>
<li>A new <a href="https://hackage.haskell.org/package/Chart-1.3/docs/Graphics-Rendering-Chart-Easy.html">Easy</a> module that includes helper functions and key dependencies</li>
<li>Simpler "toFile" functions in the rendering backends</li>
<li>Automatic sequencing of colours for successive plots</li>
</ul>
<p>All this means that a simple plot can now be a one liner:</p>
<pre><code>import Graphics.Rendering.Chart.Easy
import Graphics.Rendering.Chart.Backend.Cairo

mydata :: [Double,Double]
mydata = ...

main = toFile def &quot;test.png&quot; $ plot $ points &quot;lines&quot; mydata</code></pre>
<p>But this extends naturally to more complex charts. The code differences between the new stateful API versus the existing API can been seen in <a href="https://github.com/timbod7/haskell-chart/wiki/example-2">this example</a>.</p>
<p>The stateful API is available in <a href="https://hackage.haskell.org/package/Chart">chart v1.3</a> It is a thin layer over the existing API - both will be continue to be available in the future.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Teenage haskell</title>
      <link href="https://tim.dockerz.net//posts/2014-06-26-teenage-haskell.html"/>
      <id>https://tim.dockerz.net//posts/2014-06-26-teenage-haskell.html</id>
      <updated>2014-06-26T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>I've been inspired by the efforts of others (<a href="http://cdsmith.wordpress.com/2011/08/16/haskell-for-kids-week-1/">Chris Smith</a>, <a href="http://justtesting.org/post/70871612766/lets-program">Manuel Chakravarty</a>) to try teaching children haskell as a first experience of programming. Haskell has a reputation of being a "hard" language, but I suspect this stems from the challenges faced by software developers transitioning from an imperative programming paradigm to a functional one. There's anecdotal evidence that, for first steps into programming, a functional programming language may be easier for many students, and allow a class to focus more quickly on interesting aspects of programming.</p>
<p>With any group of beginners, and especially children, simple tooling is really important. Being able to run examples in minutes of turning on the computer is really important. But running even the simplest of traditional toolchains requires at least a rudimentary understanding of:</p>
<ul>
<li>a text editor</li>
<li>the file system</li>
<li>a command line</li>
<li>an interpreter/compiler</li>
</ul>
<p>And there's platform issues here also - even when the language is platform independent the other items will vary. It would be very easy to get bogged down in all this well before actually writing a program that does something interesting...</p>
<p>Hence I was excited several weeks ago when Chris <a href="http://cdsmith.wordpress.com/2014/06/03/codeworld-rises-again/">announced the reimplementation</a> of his codeworld environment. In a nutshell, it's a web site where:</p>
<p>1) you edit haskell code in your browser 2) it gets compiled to java script on the remote server using ghcjs 3) the javascript runs back in the browser</p>
<p>and it comes with a <a href="http://codeworld.info/doc/Prelude.html">beginner-friendly prelude</a> focussed on creating pictures, animations, and simple games (no monads required!).</p>
<p>This was just in time for school holidays here in Sydney - my own children to be my "guinea pig" students. Nick (aged 14) is in year 9 at school, whereas Sam (aged 12) is in year 7. At school they have covered simple algebra, number planes, and other math ripe to be used for something more fun than drill exercises! They have a younger brother Henry (aged 10), who has being observing with interest.</p>
<p>Our goal is to learn to draw pictures, then move on to animations, and, further down the track (if we get there) write some games. After a couple of 2 hour sessions, it has gone remarkably well.</p>
<p>So what have we done? Here's a short outline of our two sessions so far:</p>
<h2 id="session-1-25-hours">Session 1 (2.5 hours):</h2>
<p>We discussed the nature of computers, programming languages, compilers.</p>
<p>We launched the codeworld environment, and played with the demos. We tried changing them, mostly by adjusting various constants, and found they broke in often entertaining ways.</p>
<p>We typed in a trivial 2 line program to draw a circle, and made it work. We observed how problems were reported in the log window.</p>
<p>We talked about what a function is, and looked at a few of the builtin functions:</p>
<pre><code>solidCircle :: Number -&gt; Picture
color :: Color -&gt; Picture -&gt; Picture
(&amp;) :: Picture -&gt; Picture -&gt; Picture</code></pre>
<p>... and looked at how they can be composed using haskell syntax.</p>
<p>Then we played!</p>
<p>After this, we introduced some extra functions:</p>
<pre><code>solidRectangle :: Number -&gt; Number -&gt; Picture
translate :: Number -&gt; Number -&gt; Picture -&gt; Picture
rotate :: Number -&gt; Picture -&gt; Picture
scale :: Number -&gt; Number -&gt; Picture -&gt; Picture</code></pre>
<p>which let us draw much more interesting stuff. The rest of this session was spent seeing what cool stuff we could draw with these 7 functions.</p>
<p>Nick programmed some abstract art:</p>
<p><img src="/posts/2014-06-26-teenage-haskell/art.png" /></p>
<p>Sam coded up a sheep:</p>
<p><img src="/posts/2014-06-26-teenage-haskell/sheep.png" /></p>
<p>That ended the session, though the boys found some unsupervised time on the computer the next day, when Nick built a castle:</p>
<p><img src="/posts/2014-06-26-teenage-haskell/castle.png" /></p>
<p>and Sam did some virtual surfing:</p>
<p><img src="/posts/2014-06-26-teenage-haskell/boards.png" /></p>
<h2 id="session-2-2-hours">Session 2 (2 hours):</h2>
<p>In the second session, we started by talked about organising code for clarity and reuse.</p>
<p>The transformation functions introduced in the previous session caused some confusion when used in combination. We talked about how each primitive worked, and how they combined - the different between rotating and then translating versus translating then rotating was investigated.</p>
<p>The boys were keen to move on to animations. I thought we'd leave this for a few sessions, but their enthusiasm overruled. This required that we looked at how to write our own functions for the first time. (In codeworld an animation is a function from time to a picture). This is quite a big step, as we needed to get at least a basic idea of scoping also.</p>
<p>Nevertheless we battled on, and got some movement on the screen. It was soon discovered that rotations are the most interesting transform to animate, as you don't lose you picture elements off the screen as time goes to infinity!</p>
<p>Nick and Sam needed more assistance here, but still managed to get some ideas working. I've only got single frames of their results. Sam produced his space race:</p>
<p><img src="/posts/2014-06-26-teenage-haskell/space-race.png" /></p>
<p>and Nick made a working clock (which tells the right time if you push the run button at 12 oclock!):</p>
<p><img src="/posts/2014-06-26-teenage-haskell/clock.png" /></p>
<p>In the next session we are going to have to look at numerical functions in a bit more detail in order to produce more types of animations. Time for some graph paper perhaps...</p>
<h2 id="summary">Summary</h2>
<p>For a beta (alpha?) piece of software, relying on some fairly advanced and new technology, Codeworld works remarkably well. And Chris has plans for it - there's a long list of proposed enhancements in the github issue tracker, and a mailing list has just been created.</p>
<p>Right now the main issue is documentation. It works well with an already haskell-literate tutor. Others may want to wait for the documentation, course guides, etc to be written.</p>
<p>If you are a haskell enthusiast, Give it a try!</p>
      ]]></content>
  </entry>
  <entry>
      <title>Cabal version consistency</title>
      <link href="https://tim.dockerz.net//posts/2013-11-04-cabal-version-consistency.html"/>
      <id>https://tim.dockerz.net//posts/2013-11-04-cabal-version-consistency.html</id>
      <updated>2013-11-04T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>Thanks to some great work done over the google summer of code, the <a href="https://github.com/timbod7/haskell-chart/wiki">chart library</a> has gained much new functionality over the last 6 months. A consequence of this is that it has gained plenty of dependencies on other software. Furthermore, where the library previously had 2 cabal files to build the system, it now has 4. It's important the the versioning of dependencies is consistent across these cabal files, but manually checking is tedious. As best I could tell there is not yet a tool to facilitate this.</p>
<p>Hence, I spend a little time learning about the cabal API, and wrote a short script that:</p>
<ol>
<li>reads several cabal files specified on the command line</li>
<li>merges these into one overall set of dependencies</li>
<li>displays the depencies in such a way that inconsistent version constrains are obvious</li>
</ol>
<p>Here's some example output:</p>
<pre><code>$ runghc ~/repos/merge-cabal-deps/mergeCabalDeps.hs `find . -name &#39;*.cabal&#39;`
* loaded Chart-gtk-1.1
* loaded Chart-1.1
* loaded Chart-tests-1.1
* loaded Chart-cairo-1.1
* loaded Chart-diagrams-1.1
Chart:
    &gt;=1.1 &amp;&amp; &lt;1.2 (Chart-cairo,Chart-diagrams,Chart-gtk,Chart-tests)
Chart-cairo:
    &gt;=1.1 &amp;&amp; &lt;1.2 (Chart-gtk,Chart-tests)
Chart-diagrams:
    &gt;=1.1 &amp;&amp; &lt;1.2 (Chart-tests)
Chart-gtk:
    &gt;=1.1 &amp;&amp; &lt;1.2 (Chart-tests)
SVGFonts:
    &gt;=1.4 &amp;&amp; &lt;1.5 (Chart-diagrams)
array:
    -any (Chart,Chart-cairo,Chart-gtk,Chart-tests)
base:
    &gt;=3 &amp;&amp; &lt;5 (Chart,Chart-cairo,Chart-diagrams,Chart-gtk,Chart-tests)
blaze-svg:
    &gt;=0.3.3 (Chart-diagrams,Chart-tests)
bytestring:
    &gt;=0.9 &amp;&amp; &lt;1.0 (Chart-diagrams,Chart-tests)
cairo:
    &gt;=0.9.11 (Chart-cairo,Chart-gtk,Chart-tests)
colour:
    &gt;=2.2.0 (Chart-diagrams)
    &gt;=2.2.1 &amp;&amp; &lt;2.4 (Chart,Chart-cairo,Chart-gtk,Chart-tests)
containers:
    &gt;=0.4 &amp;&amp; &lt;0.6 (Chart-diagrams,Chart-tests)
data-default-class:
    &lt;0.1 (Chart,Chart-cairo,Chart-diagrams,Chart-tests)
diagrams-cairo:
    &gt;=0.7 &amp;&amp; &lt;0.8 (Chart-tests)
diagrams-core:
    &gt;=0.7 &amp;&amp; &lt;0.8 (Chart-diagrams,Chart-tests)
diagrams-lib:
    &gt;=0.7 &amp;&amp; &lt;0.8 (Chart-diagrams,Chart-tests)
...
$ </code></pre>
<p>As should be evident, all of the imported cabal packages are referenced with consistent version constraints except for colour (which is lacking an upper bound in Chart-diagrams).</p>
<p>The script is pretty straightforward:</p>
<pre><code>import Control.Monad
import Data.List(intercalate)
import System.Environment(getArgs)

import qualified Data.Map as Map
import qualified Data.Set as Set

import Distribution.Package
import Distribution.Version
import Distribution.Verbosity
import Distribution.Text(display)
import Distribution.PackageDescription
import Distribution.PackageDescription.Parse
import Distribution.PackageDescription.Configuration

type VersionRangeS = String

type DependencyMap = Map.Map PackageName (Map.Map VersionRangeS (Set.Set PackageName))

getDependencyMap :: PackageDescription -&gt; DependencyMap
getDependencyMap pd = foldr f Map.empty (buildDepends pd)
  where
    f :: Dependency -&gt; DependencyMap  -&gt; DependencyMap
    f (Dependency p vr) = Map.insert p (Map.singleton (display vr) (Set.singleton (pkgName (package pd))))

printMergedDependencies :: [PackageDescription] -&gt; IO ()
printMergedDependencies pds = do
  forM_ (Map.toList dmap) $ \(pn,versions) -&gt; do
    putStrLn (display pn ++ &quot;:&quot;)
    forM_ (Map.toList versions) $ \(version,pnset) -&gt; do
       putStrLn (&quot;    &quot; ++ version ++ &quot; (&quot; ++ intercalate &quot;,&quot; (map display (Set.toList pnset)) ++ &quot;)&quot;)
  where
    dmap :: DependencyMap
    dmap = Map.unionsWith (Map.unionWith Set.union) (map getDependencyMap pds)

scanPackages :: [FilePath] -&gt; IO ()
scanPackages fpaths = do
    pds &lt;- mapM loadPackageDescription fpaths
    printMergedDependencies pds
  where
    loadPackageDescription path = do
      pd &lt;- fmap flattenPackageDescription (readPackageDescription silent path)
      putStrLn (&quot;* loaded &quot; ++ display (package pd))
      return pd

main = getArgs &gt;&gt;= scanPackages      </code></pre>
<p>I'd be interested in other tools used for managing suites of cabal configurations.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Data analysis with Monoids</title>
      <link href="https://tim.dockerz.net//posts/2013-05-31-data-analysis-with-monoids.html"/>
      <id>https://tim.dockerz.net//posts/2013-05-31-data-analysis-with-monoids.html</id>
      <updated>2013-05-31T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>This post expresses the key ideas of a talk I gave at FP-SYD this week.</p>
<p><a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html">Monoids</a> are a pretty simple concept in haskell. Some years ago I learnt of them through the excellent <a href="http://www.haskell.org/haskellwiki/Typeclassopedia">Typeclassopedia</a>, looked at the examples, and understood them quickly (which is more than can be said for many of the new ideas that one learns in haskell). However that was it. Having learnt the idea, I realised that monoids are everywhere in programming, but I'd not found much use for the Monoid typeclass abstraction itself. Recently, I've found they can be a useful tool for data analysis...</p>
<h2 id="monoids">Monoids</h2>
<p>First a quick recap. A monoid is a type with a binary operation, and an identity element:</p>
<pre><code>class Monoid a where
  mempty :: a
  mappend :: a -&gt; a -&gt; a</code></pre>
<p>It must satisfy a simple set of laws, specifically that the binary operation much be associative, and the identity element must actually be the identity for the given operation:</p>
<pre><code>mappend a (mappend b c) = mappend (mappend a b) c
mappend mempty x = x
mappend x mempty = x</code></pre>
<p>As is hinted by the names of the typeclass functions, lists are an obvious Monoid instance:</p>
<pre><code>instance Monoid [a] where
  mempty  = []
  mappend = (++)</code></pre>
<p>However, many types can be Monoids. In fact, often a type can be a monoid in multiple ways. Numbers are monoids under both addition and multiplication, with 0 and 1 as their respective identity elements. In the haskell standard libraries, rather than choose one kind of monoid for numbers, newtype declarations are used to given instances for both:</p>
<pre><code>newtype Sum a = Sum { getSum :: a }
  deriving (Eq, Ord, Read, Show, Bounded)

instance Num a =&gt; Monoid (Sum a) where
  mempty = Sum 0
  Sum x `mappend` Sum y = Sum (x + y)

newtype Product a = Product { getProduct :: a }
  deriving (Eq, Ord, Read, Show, Bounded)

instance Num a =&gt; Monoid (Product a) where
  mempty = Product 1
  Product x `mappend` Product y = Product (x * y)</code></pre>
<p>We've now established and codified the common structure for a few monoids, but it's not yet clear what it has gained us. The Sum and Product instances are unwieldly - you are unlikely to want to use Sum directly to add two numbers:</p>
<pre><code>Prelude&gt; :m Data.Monoid
Prelude Data.Monoid&gt; 5+4
9
Prelude Data.Monoid&gt; getSum (mappend (Sum 5) (Sum 4))
9</code></pre>
<p>Before we progress, however, let's define a few more monoid instances, potentially useful for data analysis.</p>
<pre><code>data Min a = Min a | MinEmpty deriving (Show)
           
data Max a = Max a | MaxEmpty deriving (Show)

newtype Count = Count Int deriving (Show)

instance (Ord a) =&gt; Monoid (Min a) where
  mempty = MinEmpty
  mappend MinEmpty m = m
  mappend m MinEmpty = m
  mappend (Min a) (Min b) = (Min (P.min a b))

instance (Ord a) =&gt; Monoid (Max a) where
  mempty = MaxEmpty
  mappend MaxEmpty m = m
  mappend m MaxEmpty = m
  mappend (Max a) (Max b) = (Max (P.max a b))

instance Monoid Count where
  mempty = Count 0
  mappend (Count n1) (Count n2) = Count (n1+n2)</code></pre>
<p>Also some helper functions to construct values of all these monoid types:</p>
<pre><code>sum :: (Num a) =&gt; a -&gt; Sum a
sum = Sum

product :: (Num a) =&gt; a -&gt; Product a
product = Product

min :: (Ord a) =&gt; a -&gt; Min a
min = Min

max :: (Ord a) =&gt; a -&gt; Max a
max = Max

count :: a -&gt; Count
count _ = Count 1</code></pre>
<p>These functions are trivial, but they put a consistent interface on creating monoid values. They all have a signature (a -&gt; m) where m is some monoid. For lack of a better name, I'll call functions with such signatures "monoid functions".</p>
<h2 id="foldable">Foldable</h2>
<p>It's time to introduce another typeclass, <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Foldable.html">Foldable</a>. This class abstracts the classic foldr and foldl functions away from lists, making them applicable to arbitrary structures. (There's a robust debate going on right now about the merits of replacing the list specific fold functions in the standard prelude with the more general versions from Foldable.) Foldable is a large typeclass - here's the key function of interest to us:</p>
<pre><code>class Foldable t where
  ...
  foldMap :: Monoid m =&gt; (a -&gt; m) -&gt; t a -&gt; m
  ...</code></pre>
<p>foldMap takes a monoid function and a Foldable structure, and reduces the structure down to a single value of the monoid. Lists are, of course, instances of foldable, so we can demo our helper functions:</p>
<pre><code>*Examples&gt; let as = [45,23,78,10,11,1]
*Examples&gt; foldMap count as
Count 6
*Examples&gt; foldMap sum as
Sum {getSum = 168}
*Examples&gt; foldMap max as
Max 78</code></pre>
<p>Notice how the results are all still wrapped with the newtype constructors. We'll deal with this later.</p>
<h2 id="composition">Composition</h2>
<p>As it turns out, tuples are already instances of Monoids:</p>
<pre><code>instance (Monoid a,Monoid b) =&gt; Monoid (a,b) where
  mempty = (mempty,mempty)
  mappend (a1,b1) (a2,b2) = (mappend a1 a2,mappend b1 b2)</code></pre>
<p>A pair is a monoid if it's elements are monoids. There are similar instances for longer tuples. We need some helper monoid functions for tuples also:</p>
<pre><code>a2 :: (a -&gt; b) -&gt; (a -&gt; c) -&gt; a -&gt; (b,c)
a2 b c = (,) &lt;$&gt; b &lt;*&gt; c

a3 :: (a -&gt; b) -&gt; (a -&gt; c) -&gt; (a -&gt; d) -&gt; a -&gt; (b,c,d)
a3 b c d = (,,) &lt;$&gt; b &lt;*&gt; c &lt;*&gt; d</code></pre>
<p>These are implemented above using <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html">Applicative</a> operators, though I've given them more restrictive types to make their intended use here clearer. Now I can compose monoid functions:</p>
<pre><code>*Examples&gt; let as = [45,23,78,10,11,1]
*Examples&gt; :t (a2 min max)
(a2 min max) :: Ord a =&gt; a -&gt; (Min a, Max a)
*Examples&gt; foldMap (a2 min max) as
(Min 1,Max 78)
*Examples&gt; :t (a3 count (a2 min max) (a2 sum product))
(a3 count (a2 min max) (a2 sum product))
  :: (Num a, Ord a) =&gt;
     a -&gt; (Count, (Min a, Max a), (Sum a, Product a))
*Examples&gt; foldMap (a3 count (a2 min max) (a2 sum product)) as
(Count 6,(Min 1,Max 78),(Sum {getSum = 168},Product {getProduct = 8880300}))</code></pre>
<p>It's worth noting here that the composite computations are done in a single traversal of the input list.</p>
<h2 id="more-complex-calculations">More complex calculations</h2>
<p>Happy with this, I decide to extend my set of basic computations with the arithmetic mean. There is a problem, however. The arithmetic mean doesn't "fit" as a monoid - there's no binary operation such that a mean for a combined set of data can be calculated from the mean of two subsets.</p>
<p>What to do? Well, the mean is the sum divided by the count, both of which are monoids:</p>
<pre><code>newtype Mean a = Mean (Sum a,Count) deriving (Show)

instance (Num a) =&gt; Monoid (Mean a) where
  mempty = Mean mempty
  mappend (Mean m1) (Mean m2) = Mean (mappend m1 m2)

mean v = Mean (Sum v,Count 1)</code></pre>
<p>So I can calculate the mean if I am prepared to do a calculation after the foldMap:</p>
<pre><code>*Examples&gt; let as = [45,23,78,10,11,1.5]
*Examples&gt; foldMap mean as
Mean (Sum {getSum = 168.5},Count 6)
*Examples&gt; let (Mean (Sum t,Count n)) = foldMap mean as in t / fromIntegral n
28.083333333333332</code></pre>
<h2 id="the-aggregation-type-class">The Aggregation type class</h2>
<p>For calculations like <code>mean</code>, I need something more than a monoid. I need a monoid for accumulating the values, and then, once the accumulation is complete, a postprocessing function to compute the final result. Hence a new typeclass to extend Monoid:</p>
<pre><code>{-# LANGUAGE TypeFamilies #-}

class (Monoid a) =&gt; Aggregation a where
  type AggResult a :: *
  aggResult :: a -&gt; AggResult a</code></pre>
<p>This makes use of the <a href="http://www.haskell.org/haskellwiki/GHC/Type_families">type families ghc extension</a>. We need this to express the fact that our postprocessing function aggResult has a different return type to the type of the monoid. In the above definition:</p>
<ul>
<li>aggResult is a function that gives you the <em>value</em> of the final result from the <em>value</em> of the monoid</li>
<li>AggResult is a <em>type</em> function that gives you the <em>type</em> of the final result from the <em>type</em> of the monoid</li>
</ul>
<p>We can write an instance of Aggregation for Mean:</p>
<pre><code>instance (Fractional a) =&gt; Aggregation (Mean a) where
  type AggResult (Mean a) = a
  aggResult (Mean (Sum t,Count n)) = t/fromIntegral n</code></pre>
<p>and test it out:</p>
<pre><code>*Examples&gt; let as = [45,23,78,10,11,1.5]
*Examples&gt; aggResult (foldMap mean as)
28.083333333333332
*Examples&gt; </code></pre>
<p>Nice. Given that <code>aggResult (foldMap ...)</code> will be a common pattern, lets write a helper:</p>
<pre><code>afoldMap :: (Foldable t, Aggregation a) =&gt; (v -&gt; a) -&gt; t v -&gt; AggResult a
afoldMap f vs = aggResult (foldMap f vs)</code></pre>
<p>In order to use the monoids we defined before (sum,product etc) we need to define Aggregation instances for them also. Even though they are trivial, it turns out to be useful, as we can make the aggResult function strip off the newtype constructors that were put there to enable the Monoid typeclass:</p>
<pre><code>instance (Num a) =&gt; Aggregation (Sum a)  where
  type AggResult (Sum a) = a
  aggResult (Sum a) = a
    
instance (Num a) =&gt; Aggregation (Product a)  where
  type AggResult (Product a) = a
  aggResult (Product a) = a

instance (Ord a) =&gt; Aggregation (Min a)  where
  type AggResult (Min a) = a
  aggResult (Min a) = a

instance (Ord a) =&gt; Aggregation (Max a)  where
  type AggResult (Max a) = a
  aggResult (Max a) = a

instance Aggregation Count where
  type AggResult Count = Int
  aggResult (Count n) = n

instance (Aggregation a, Aggregation b) =&gt; Aggregation (a,b) where
  type AggResult (a,b) = (AggResult a, AggResult b)
  aggResult (a,b) = (aggResult a, aggResult b)

instance (Aggregation a, Aggregation b, Aggregation c) =&gt; Aggregation (a,b,c) where
  type AggResult (a,b,c) = (AggResult a, AggResult b, AggResult c)
  aggResult (a,b,c) = (aggResult a, aggResult b, aggResult c)</code></pre>
<p>This is mostly boilerplate, though notice how the tuple instances delve into their components in order to postprocess the results. Now everything fits together cleanly:</p>
<pre><code>*Examples&gt; let as = [45,23,78,10,11,1.5]
*Examples&gt; :t (a3 count (a2 min max) mean)
(a3 count (a2 min max) mean)
  :: Ord a =&gt; a -&gt; (Count, (Min a, Max a), Mean a)
*Examples&gt; afoldMap (a3 count (a2 min max) mean) as
(6,(1.5,78.0),28.083333333333332)
*Examples&gt; </code></pre>
<p>The 4 computations have been calculated all in a single pass over the input list, and the results are free of the type constructors that are no longer required once the aggregation is complete.</p>
<p>Another example of an Aggregation where we need to postprocess the result is counting the number of unique items. For this we will keep a set of the items seen, and then return the size of this set at the end:</p>
<pre><code>newtype CountUnique a = CountUnique (Set.Set a)

instance Ord a =&gt; Monoid (CountUnique a) where
  mempty = CountUnique Set.empty
  mappend (CountUnique s1) (CountUnique s2) = CountUnique (Set.union s1 s2)

instance Ord a =&gt; Aggregation (CountUnique a) where
  type AggResult (CountUnique a) = Int
  aggResult (CountUnique s1) = Set.size s1

countUnique :: Ord a =&gt; a -&gt; CountUnique a
countUnique a = CountUnique (Set.singleton a)</code></pre>
<p>.. in use:</p>
<pre><code>*Examples&gt; let as = [5,7,8,7,11,10,11]
*Examples&gt; afoldMap (a2 countUnique count) as
(5,7)</code></pre>
<h2 id="higher-order-aggregation-functions">Higher order aggregation functions</h2>
<p>All of the calculations seen so far have worked consistently across all values in the source data structure. We can make use of the <code>mempty</code> monoid value in order to filter our data set, and or aggregate in groups. Here's a couple of higher order monoid functions for this:</p>
<pre><code>afilter :: Aggregation m =&gt; (a -&gt; Bool) -&gt; (a -&gt; m) -&gt; (a -&gt; m)
afilter match mf = \a -&gt; if match a then mf a else mempty

newtype MMap k v = MMap (Map.Map k v)
  deriving Show

instance (Ord k, Monoid v) =&gt; Monoid (MMap k v) where
  mempty = MMap (Map.empty)
  mappend (MMap m1) (MMap m2) = MMap (Map.unionWith mappend m1 m2)

instance (Ord k, Aggregation v) =&gt; Aggregation (MMap k v) where
  type AggResult (MMap k v) = Map.Map k (AggResult v)
  aggResult (MMap m) = Map.map aggResult m

groupBy :: (Ord k, Aggregation m) =&gt; (a -&gt; k) -&gt; (a -&gt; m) -&gt; (a -&gt; MMap k m)
groupBy keyf valuef = \a -&gt; MMap (Map.singleton (keyf a) (valuef a))</code></pre>
<p><code>afilter</code> restricts the application of a monoid function to a subset of the input data. eg to calculate the sum of all the values, and the sum of values less than 20:</p>
<pre><code>*Examples&gt; let as = [5,10,20,45.4,35,1,3.4]
*Examples&gt; afoldMap (a2 sum (afilter (&lt;=20) sum)) as
(119.8,39.4)</code></pre>
<p><code>groupBy</code> takes a key function and a monoid function. It partitions the data set using the key function, and applies a monoid function to each subset, returning all of the results in a map. Non-numeric data works better as an example here. Let's take a set of words as input, and for each starting letter, calculate the number of words with that letter, the length of the shortest word, and and the length of longest word:</p>
<pre><code>*Examples&gt; let as = words &quot;monoids are a pretty simple concept in haskell some years ago i learnt of them through the excellent typeclassopedia looked at the examples and understood them straight away which is more than can be said for many of the new ideas that one learns in haskell&quot;
*Examples&gt; :t groupBy head (a3 count (min.length) (max.length))
groupBy head (a3 count (min.length) (max.length))
  :: Ord k =&gt; [k] -&gt; MMap k (Count, Min Int, Max Int)
*Examples&gt; afoldMap (groupBy head (a3 count (min.length) (max.length))) as
fromList [(&#39;a&#39;,(6,1,4)),(&#39;b&#39;,(1,2,2)),(&#39;c&#39;,(2,3,7)),(&#39;e&#39;,(2,8,9)),(&#39;f&#39;,(1,3,3)),(&#39;h&#39;,(2,7,7)),(&#39;i&#39;,(5,1,5)),(&#39;l&#39;,(3,6,6)),(&#39;m&#39;,(3,4,7)),(&#39;n&#39;,(1,3,3)),(&#39;o&#39;,(3,2,3)),(&#39;p&#39;,(1,6,6)),(&#39;s&#39;,(4,4,8)),(&#39;t&#39;,(9,3,15)),(&#39;u&#39;,(1,10,10)),(&#39;w&#39;,(1,5,5)),(&#39;y&#39;,(1,5,5))]</code></pre>
<p>Many useful data analysis functions can be written through simple function application and composition using these primitive monoid functions, the product combinators a2 and a3 and these new filtering and grouping combinators.</p>
<h2 id="disk-based-data">Disk-based data</h2>
<p>As pointed out before, regardless of the complexity of the computation, it's done with a single traversal of the input data. This means that we don't need to limit ourselves to lists and other in memory Foldable data structures. Here's a function similar to foldMap, but that works over the lines in a file:</p>
<pre><code>foldFile :: Monoid m =&gt; FilePath -&gt; (BS.ByteString -&gt; Maybe a) -&gt; (a -&gt; m) -&gt; IO m
foldFile fpath pf mf = do
  h &lt;- openFile fpath ReadMode
  m &lt;- loop h mempty
  return m
  where
    loop h m = do
      eof &lt;- hIsEOF h
      if eof
        then (return m)
        else do
          l &lt;- BS.hGetLine h
          case pf l of
            Nothing -&gt; loop h m
            (Just a) -&gt; let m&#39; = mappend m (mf a)
                        in loop h m&#39;

afoldFile :: Aggregation m =&gt; FilePath -&gt; (BS.ByteString -&gt; Maybe a) -&gt; (a -&gt; m) -&gt; IO (AggResult m)
afoldFile fpath pf mf = fmap aggResult (foldFile fpath pf mf)</code></pre>
<p>foldFile take two parameters - a function to parse each line of the file, the other is the monoid function to do the aggregation. Lines that fail to parse are skipped. (I can here questions in the background "What about strictness and space leaks?? - I'll come back to that). As an example usage of aFoldFile, I'll analyse some stock data. Assume that I have it in a CSV file, and I've got a function to parse one CSV line into a sensible data value:</p>
<pre><code>import qualified Data.ByteString.Char8 as BS
import Data.Time.Calendar

data Prices = Prices {
  pName :: String,          -- The stock code
  pDate :: Day,             -- The historic date
  pOpen :: Double,          -- The price at market open
  pHigh :: Double,          -- The highest price on the date
  pLow :: Double,           -- The lowest price on the date
  pClose :: Double,         -- The price at market close
  pVolume :: Double         -- How many shares were traded
  } deriving (Show)

  parsePrices :: BS.ByteString -&gt; Maybe Prices
  parsePrices = ...</code></pre>
<p>Now I can use my monoid functions to analyse the file based data. How many google prices do I have, over what date range:</p>
<pre><code>*Examples&gt; let stats =  afilter ((&quot;GOOG&quot;==).pName) (a3 count (min.pDate) (max.pDate))
*Examples&gt; :t stats
stats
  :: Prices
     -&gt; (Count,
         Min time-1.4:Data.Time.Calendar.Days.Day,
         Max time-1.4:Data.Time.Calendar.Days.Day)
*Examples&gt; afoldFile &quot;prices.csv&quot; parsePrices stats
(1257,2008-05-29,2013-05-24)
*Examples&gt; </code></pre>
<p>Perhaps I want to aggregate my data per month, getting traded price range and total volume. We need a helper function to work out the month of each date:</p>
<pre><code>startOfMonth :: Day -&gt; Day
startOfMonth t = let (y,m,d) = toGregorian t
                 in fromGregorian y m 1</code></pre>
<p>And then we can use groupBy to collect data monthly:</p>
<pre><code>:*Examples&gt; let stats =  afilter ((&quot;GOOG&quot;==).pName) (groupBy (startOfMonth.pDate) (a3 (min.pLow) (max.pHigh) (sum.pVolume)))
*Examples&gt; :t stats
stats
  :: Prices
     -&gt; MMap
          time-1.4:Data.Time.Calendar.Days.Day
          (Min Double, Max Double, Sum Double)
*Examples&gt; results &lt;- afoldFile &quot;prices.csv&quot; parsePrices stats
*Examples&gt; mapM_ print (Map.toList results)
(2008-05-01,(573.2,589.92,8073107.0))
(2008-06-01,(515.09,588.04,9.3842716e7))
(2008-07-01,(465.6,555.68,1.04137619e8))
...
(2013-03-01,(793.3,844.0,4.2559856e7))
(2013-04-01,(761.26,827.64,5.3574633e7))
(2013-05-01,(816.36,920.6,4.1080028e7))</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>So, I hope I've shown that monoids are useful indeed. They can form the core of a framework for cleanly specifing quite complex data analysis tasks.</p>
<p>An additional typeclass which I called "Aggregation" extends Monoid and provides for a broader range of computations and also cleaner result types (thanks to type families). There was some discussion when I presented this talk as to whether a single method typeclass like Aggregation was a "true" abstraction, given it has no associated laws. This is a valid point, however using it simplifies the syntax and usage of monoidal calculations significantly, and for me, this makes it worth having.</p>
<p>There remains an elephant in the room, however, and this is space leakage. Lazy evalulation means that, as written, most of the calculations shown run in space proportional to the input data set. Appropriate strictness annotations and related modifications will fix this, but it turns out to be slightly irritating. This blog post is already long enough, so I'll address space leaks in in a subsequent post...</p>
      ]]></content>
  </entry>
  <entry>
      <title>Composable Value Editor code</title>
      <link href="https://tim.dockerz.net//posts/2012-09-16-composable-value-editor-code.html"/>
      <id>https://tim.dockerz.net//posts/2012-09-16-composable-value-editor-code.html</id>
      <updated>2012-09-16T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>I've made the code for this library (previously <a href="2012-05-10-composable-value-editors.html">described here</a>) available via a repository on github: <a href="https://github.com/timbod7/veditor" class="uri">https://github.com/timbod7/veditor</a> It's still experimental, so I don't intend to put it on hackage until I have (or someone else has) a dependency on it. The actual VE GADT in the source has an extra type parameter intended to let the generated UIs depend on context. Where this is not necessary, the ConstE type may be supplied. Hence, in the actual code the type <code>VE ConstE a</code> corresponds to <code>VE a</code> in the previous blog post.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Composable Value Editors</title>
      <link href="https://tim.dockerz.net//posts/2012-05-10-composable-value-editors.html"/>
      <id>https://tim.dockerz.net//posts/2012-05-10-composable-value-editors.html</id>
      <updated>2012-05-10T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>Graphical User Interfaces (GUIs) in haskell are frustrating. It's not yet clear what is the cleanest model for fitting GUIs into functional programming. Currently there are two main approaches:</p>
<ul>
<li><p>Various effort at applying Functional Reactive Programming (FRP) to GUIs. These are somewhat experimental, and tend to be proof of concepts implementing a small range of GUI features (several of these libraries are listed <a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/GUI_libraries#High-level">here</a>).</p></li>
<li><p>The full blown toolkits which provide a comprehensive imperative binding to mainstream toolkits. The two key contenders here are <a href="http://projects.haskell.org/gtk2hs/">gtk2hs</a> and <a href="http://www.haskell.org/haskellwiki/WxHaskell">wxHaskell</a>.</p></li>
</ul>
<p>Whilst enticing, the FRP approach doesn't currently look appropriate for building rich GUI applications. wxHaskell and gtk2hs at least provide the functionality required, but the low level imperative approach based in the IO monad is tedious to a fluent haskell developer. Here's a code snippet:</p>
<pre><code>b &lt;- buttonNew
image &lt;- imageNewFromStock stockAdd IconSizeSmallToolbar
containerAdd b image
set b [buttonRelief := ReliefNone]
on b buttonActivated {
     ... button activated action ...
}</code></pre>
<p>It's not hard to write this sort of code, but it is tedious, especially considering the amount that is required to build a whole application.</p>
<p>This post outlines my experiments to reduce the amount of imperative code required for GUIs, yet retaining compatibility with the imperative toolkits. Initially I've been focussed on "value editors" (VEs) aka "forms". These are GUI components to capture/edit values of ideally arbitrary complexity. I've two key goals, composability and abstraction.</p>
<p><em>Composability</em>: I want to be able to compose my value editors effortlessly. Whilst the existing toolkits let you compose widgets using containers and glue code, it's verbose indeed.</p>
<p><em>Abstraction</em>: I'd like to define my VEs independently from the underlying toolkit. But I'm looking for something more than a thin layer over the existing toolkits. I want to define my VEs in terms of the structure of the values involved, and worry about the formatting and layout later, if at all.</p>
<p>If we take this abstraction far enough, it should be possible to reuse our structural VEs definitions beyond gtk2hs and wxWindows. For example, a JSON generator+parser pair can be considered a VE - in the sense that to edit a value, one can generate the json text, edit the text, and then parse to recover the new value. Of course, it's likely to be a balancing act between abstraction and functionality - we'll have to see how this pans out.</p>
<h1 id="an-abstract-ui">An Abstract UI</h1>
<p>OK, enough preamble, here's a GADT I've devised to capture VEs:</p>
<pre><code>-- | A GADT describing abstracted, user interface components for manipulating
-- values of type a.
data VE a where
    -- | A String field
    Entry :: VE String

    -- | An enumeration. A list of label string are supplied,
    -- the VE value is the integer index of the selected label.
    EnumVE :: [String] -&gt; VE Int

    -- | Annotate a VE with a text label
    Label :: String -&gt; VE a -&gt; VE a

    -- | A &quot;product&quot; VE that combines values from two other VEs
    AndVE :: (VE a) -&gt; (VE b) -&gt; VE (a,b)

    -- | A &quot;sum&quot; VE that captures the value from either of two other VEs
    OrVE  :: (VE a) -&gt; (VE b) -&gt; VE (Either a b)

    -- | A VE for manipulating  a list of values. The supplied function lets the
    -- the VE display the list items to the user (eg for selection).
    ListVE :: (a-&gt;String) -&gt; VE a -&gt; VE [a]

    -- | Convert a VE over a type a, to a VE over a type b, given
    -- the necessary mappings. Either String captures the potential
    -- failure in the mapping.
    MapVE :: (a -&gt; Either String b) -&gt; (b -&gt; a) -&gt; VE a -&gt; VE b

    -- | Annotate a VE with a default value
    DefaultVE :: a -&gt; VE a -&gt; VE a

-- A typeclass to build VEs
class HasVE a where
  mkVE :: VE a

(.*.) = AndVE
(.+.) = OrVE
infixr 5 .*.
infixr 5 .+.</code></pre>
<p>And here's an example usage for a simple data type:</p>
<pre><code>data Gender = Male | Female deriving (Show,Enum)

data Person = Person {
    st_name :: String,
    st_age :: Int,
    st_gender :: Gender
} deriving (Show)

instance HasVE Person
  where
    mkVE = MapVE toStruct fromStruct
        (   Label &quot;Name&quot; nonEmptyString
        .*. Label &quot;Age&quot;   mkVE
        .*. Label &quot;Gender&quot;   mkVE
        )
      where
        toStruct (a,(b,c)) = Right (Person a b c)
        fromStruct (Person a b c) = (a,(b,c))

nonEmptyString :: VE String
nonEmptyString = ...

instance HasVE Int ...
instance HasVE String ...
instance HasVE Gender ...</code></pre>
<p>This captures in some sense the abstract semantics for an editor of Person values. We need to capture:</p>
<ul>
<li>a non-empty string for the name,</li>
<li>an integer for the age</li>
<li>a gender enumeration</li>
</ul>
<p>and know how to pack/unpack these into a person value.</p>
<h1 id="a-gtk-ui">A GTK UI</h1>
<p>But what can we do with this? We need to turn this abstruct VE into a concrete UI. There's a library function to do this for an arbitrary VE:</p>
<pre><code>data GTKWidget a = GTKWidget {
    ui_widget :: Widget,
    ui_set :: a -&gt; IO (),
    ui_get :: IO (ErrVal a),
    ui_reset :: IO ()
}

uiGTK  :: VE  a -&gt; IO (GTKWidget a)</code></pre>
<p>The uiGTK function turns our abstract VE a into GTK component for editing a value of type a. In addition to building the compound widget, it gives us functions to:</p>
<ul>
<li>put a value into the widget</li>
<li>recover a value from the widget</li>
<li>restore the widget to a default value</li>
</ul>
<p>A higher level function constructs a modal dialog to get a value of type a from the user.</p>
<pre><code>data ModalDialog e a = ModalDialog {
    md_dialog :: Dialog,
    md_gw :: GTKWidget a,
    md_run :: IO (Maybe a)
}

modalDialogNew :: String -&gt; VE a -&gt; IO (ModalDialog a)</code></pre>
<p>Hence running this:</p>
<pre><code>dialog &lt;- modalDialogNew &quot;Example 2&quot; (mkVE :: Person)
ma &lt;- md_run dialog</code></pre>
<p>Results in this:</p>
<p><img src="/posts/2012-05-10-composable-value-editors/example2.png" alt="Example 2" /></p>
<p>The automatically generated dialog is simple, but quite functional:</p>
<ul>
<li>invalid fields have a red background, dynamically updated with each keystroke</li>
<li>Fields have sensible defaults - often invalid to force entry from a user</li>
</ul>
<p>More complex UIs are of course possible. As should be clear from the VE GADT above we support sum and product types, lists, etc, and can map these with arbitrary code. Hence we can construct GTK UIs for a very large range of haskell values. A slightly more complex example composes the previous VE:</p>
<pre><code>data Team = Team {
    t_leader :: Person,
    t_followers :: [Person]
} deriving (Show)

instance HasVE Team ...</code></pre>
<p>Resulting in:</p>
<p><img src="/posts/2012-05-10-composable-value-editors/example3.png" alt="Example 3" /></p>
<p>Recursive types are supported, so its possible to build GTK VEs for expression trees, etc.</p>
<h1 id="json-serialisation">JSON Serialisation</h1>
<p>As I alluded to previously, given VE a, we can automatically generate a JSON generator and parser for values of type a:</p>
<pre><code>data VEJSON a = VEJSON {
        uj_tojson ::  a -&gt; DA.Value,
        uj_fromjson :: DA.Value -&gt; Maybe a
}

uiJSON :: VE ConstE a -&gt; VEJSON a</code></pre>
<h1 id="related-work">Related Work</h1>
<p>Well into working on these ideas, I was reminded of two somewhat similar haskell projects: <a href="http://www.sandr.dds.nl/FunctionalForms/">Functional Forms</a> and <a href="http://www.haskell.org/haskellwiki/TV">Tangible Values</a>. Functional Forms aims to ease the creation of wxHaskell dialogs to edit values. The exact purpose Tangeable Values is a little unclear to me, but it appears to be about automatically generating UIs suitable for visualising function behaviour and exploring functional programming.</p>
<h1 id="future-work">Future Work</h1>
<p>Currently I have a library that implements the VE GADT to automatically build GTK editors and JSON serialisers. There's many ways to progress this work. Some of my ideas follow...</p>
<p>Whilst the generated GTK editor is a sensible default, there are only very limited ways in which the editor can be customised. I envisage a model where the uiGTK function takes an extra parameter akin to a style sheet, given extra information controlling the UI layout and formatting, etc.</p>
<p>I can envisage many other useful things that could automatically be derived from VE definitions:</p>
<ul>
<li>equivalent functionality for wxHaskell</li>
<li>console GUIs</li>
<li>Funky UIs implemented with primitives more interesting than the standard toolkit widgets: eg zoomable UIs, or UIs more suited to table based platforms.</li>
<li>web GUIs. This could be done by automatically generating javascript and corresponding server side haskell code.</li>
</ul>
<p>Finally, It might be worth investigate whether the <a href="http://www.haskell.org/haskellwiki/GHC.Generics">GHC Generic</a> mechansism might be used to automatically generate VE definitions.</p>
<p>So there's plenty of directions this work can go, but right now I want to put it to the test and build an application!</p>
      ]]></content>
  </entry>
  <entry>
      <title>Installing ghc 7.03 and the haskell platform on RHEL 5.6</title>
      <link href="https://tim.dockerz.net//posts/2011-12-21-ghc-on-rhel65.html"/>
      <id>https://tim.dockerz.net//posts/2011-12-21-ghc-on-rhel65.html</id>
      <updated>2011-12-21T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>The current haskell platform requires ghc 7.0.3. I need this to run on some RHEL 5.6 machines. Whilst this OS update was released in Jan 2011, it's based on old software. In particular, it's built with libc 2.5, which was released back in 2006. It's not able to use the prebuilt generic binary release from the <a href="http://haskell.org/ghc/download_ghc_7_0_3" title="ghc downloads page">ghc downloads page</a>. It says:</p>
<blockquote>
<p>NOTE: If you have too old a version of libc, then you will get an error like "floating point exception" from the binaries in these bindists. You will need to either upgrade your libc (we're not sure what the minimum version required is), or use a binary package built for your distribution instead.</p>
</blockquote>
<p>I sure don't want to upgrade libc, and to the best of my knowledge there's no binary package built for RHEL. So, I'll need to build it myself from source. But we need ghc to compile ghc, and to make it worse, we need a version &gt;= 6.10, and the binaries for these won't work with libc 2.5 either. So, our approach needs to be:</p>
<ol>
<li>Compile and install 6.10.4 using 6.8.3</li>
<li>Compile a binary distribution of 7.0.3 using 6.10.4</li>
<li>Install the 7.0.3 binary distribution</li>
<li>Compile and install the haskell platform 2011.2.0.1</li>
</ol>
<p>But wait, as it turns out, the RHEL 5.6 C compiler (gcc 4.1.2) doesn't seem to be compatible with recent ghc builds either, giving errors like:</p>
<pre><code>rts/dist/build/RtsStartup.dyn_o: relocation R_X86_64_PC32 against `StgRun&#39; can
not be used when making a shared object; recompile with -fPIC</code></pre>
<p>(there are some details on the <a href="http://hackage.haskell.org/trac/ghc/wiki/Building/Troubleshooting">building and troubleshooting ghc page</a>) So, you need a more recent gcc also. I could have build this from source also, but luckily I had a working gcc 4.4.3 build already present. For reference, I needed to download:</p>
<ul>
<li>ghc-6.10.4-src.tar.bz2</li>
<li>ghc-6.8.3-x86_64-unknown-linux.tar.bz2</li>
<li>ghc-7.0.3-src.tar.bz2</li>
<li>haskell-platform-2011.2.0.1.tar.gz</li>
</ul>
<p>And here's the commands used:</p>
<pre><code># General setup
# Assumes downloaded files are in $BASE/downloads
BASE=/tmp/ghc-dev
GCC443DIR=/opt/gcc4.4.3/bin
mkdir -p $BASE/install
mkdir -p $BASE/build

# Start with a 6.8.3 binary
cd $BASE/build
tar -xjf $BASE/downloads/ghc-6.8.3-x86_64-unknown-linux.tar.bz2
export PATH=/usr/bin:/sbin:/bin
cd $BASE/build/ghc-6.8.3
./configure --prefix $BASE/install/ghc-6.8.3
make install

# Build 6.10.4 from src
cd $BASE/build
tar -xjf $BASE/downloads/ghc-6.10.4-src.tar.bz2 
export PATH=$BASE/install/ghc-6.8.3/bin:/usr/sbin:/usr/bin:/sbin:/bin
cd $BASE/build/ghc-6.10.4
./configure --prefix $BASE/install/ghc-6.10.4
make
make install

# Build 7.0.3 from src, using 6.10.4 and gcc 4.4.3
# (gcc 4.1.2 from RHEL doesn&#39;t seem to work)
cd $BASE/build
tar -xjf $BASE/downloads/ghc-7.0.3-src.tar.bz2 
export PATH=$BASE/install/ghc-6.10.4/bin:$GCC443DIR:/usr/sbin:/usr/bin:/sbin:/bin
cd $BASE/build/ghc-7.0.3
./configure
make
make binary-dist
 
# Unpack and install the 7.0.3 bin-dist
cd /tmp
rm -rf /tmp/ghc-7.0.3
tar -xjf $BASE/build/ghc-7.0.3/ghc-7.0.3-x86_64-unknown-linux.tar.bz2
cd /tmp/ghc-7.0.3
./configure --prefix $BASE/install/ghc-7.0.3
make install

# Unpack and install the haskell platform
cd $BASE/build
export PATH=$BASE/install/ghc-7.0.3/bin:$GCC443DIR:/usr/sbin:/usr/bin:/sbin:/bin
tar -xzf $BASE/downloads/haskell-platform-2011.2.0.1.tar.gz
cd $BASE/build/haskell-platform-2011.2.0.1
./configure --prefix $BASE/install/ghc-7.0.3
make
make install</code></pre>
<p>Be prepared to chew up some CPU cycles! Pleasingly, once I sorted out the gcc version issue, all of the above worked without problems.</p>
      ]]></content>
  </entry>
  <entry>
      <title>HBeat Lives</title>
      <link href="https://tim.dockerz.net//posts/2011-11-29-hbeat-lives.html"/>
      <id>https://tim.dockerz.net//posts/2011-11-29-hbeat-lives.html</id>
      <updated>2011-11-29T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>Reorganising my projects home, I copied in the old documentation for my <a href="http://dockerz.net/twd/hBeat">hbeat</a> program. The docs needed some updating, so I decided to check it all still works ok. Fearing bitrot, I was pleased and a little suprised to see that on my recently rebuilt ubuntu machine, all I needed was</p>
<pre><code>sudo apt-get install libsdl1.2-dev
sudo apt-get install libsdl-mixer1.2-dev
cabal-dev install hbeat</code></pre>
<p>Or at least that's what I first thought. The program fired up ok, but failed to respond to mouse clicks as expected. It turns out that this was a pre-existing bug - if the screen redraws don't happen fast enough, hbeat gets further and further behind in it's event processing eventually ignoring everything. A small code fix (now published to hackage) causes out-of-date redraw requests to be dropped. But why was I seeing this problem now? It seems that since I wrote the software, openGL via SDL seems to have got alot slower. The compositing window manager (compiz) seems to be the culprit - it's consuming significant cpu time whilst hbeat is running. Some references to this can be found <a href="http://forums.libsdl.org/viewtopic.php?t=6511&amp;sid=19ba7791909f191ef4959cf13841caec">here</a>. I guess there's a downside to all those fancy compositing effects. It's a shame hbeat is now a fair bit glitchier than it was before. Maybe sometime I'll look at this, but for now at least it still works.</p>
      ]]></content>
  </entry>
  <entry>
      <title>Accessing the cabal version from an application</title>
      <link href="https://tim.dockerz.net//posts/2011-11-21-cabal-version-access.html"/>
      <id>https://tim.dockerz.net//posts/2011-11-21-cabal-version-access.html</id>
      <updated>2011-11-21T00:00:00Z</updated>
      <content type="html"><![CDATA[
        <p>I wanted the --version flag in an application to return the version from the cabal file. Unable to find solution for this on the net, I ventured into the darcs source code to for a solution. It's actually pretty easy:</p>
<h2 id="step-1">Step 1</h2>
<p>Change the Build-Type field in the cabal file to be "Custom". This means cabal will look for a Setup.hs file to control the build.</p>
<h2 id="step-2">Step 2</h2>
<p>Create a Setup.hs that autogenerates a haskell module containing the version number. Here's mine:</p>
<pre><code>import Distribution.Simple(defaultMainWithHooks, UserHooks(..), simpleUserHooks )
import Distribution.Simple.Utils(rewriteFile)
import Distribution.Package(packageVersion)
import Distribution.Simple.BuildPaths(autogenModulesDir)
import System.FilePath((&lt;/&gt;))
import Data.Version(showVersion)
generateVersionModule pkg lbi = do
let dir = autogenModulesDir lbi
let version = packageVersion pkg

rewriteFile (dir &lt;/&gt; &quot;Version.hs&quot;) $ unlines
[&quot;module Version where&quot;
,&quot;version :: String&quot;
,&quot;version = \&quot;&quot; ++ showVersion version ++ &quot;\&quot;&quot;
]

myBuildHook pkg lbi hooks flags = do
generateVersionModule pkg lbi
buildHook simpleUserHooks pkg lbi hooks flags

main = defaultMainWithHooks simpleUserHooks {
buildHook=myBuildHook
}</code></pre>
<h2 id="step-3">Step 3</h2>
<p>Change your program to access the created Version module. It's actually generated in the ./dist/build./autogen directory, but this seems to be correctly on the source path by default.</p>
      ]]></content>
  </entry>
</feed>
