First Month of Haskell

| Comments

I’ve been excpetionally fortunate in the past month to accomplish a long held goal of mine. As of the 13th of April I’ve been employed full time as a functional programmer. In particular I’ve taken the deepest of dives into Haskell. I thought it might be interesting, at least for me, to write up my thoughts after completing a month of Haskell.

First the depth of the dive has been overwhelming and the learning curve more equivalent to a vertical rock climb. But the entire time, no matter the exhaustion and believe me there was a lot of that, has been extrodinary. When I take a moment to reflect, I’ve had a smile on my face.

First thing, the degree to which types are ingrained in Haskell. That might seem surprising in itself, Haskell is afterall a strongly typed langauge and it was surprising to me too. I’ve used Erlang, with dialyzer, and OCaml a great deal before starting, and both these languages have reasonable type systems. Ocaml is even described as strongly typed. So what am I getting at?

Everything in Haskell feels typed to the nth degree. Every possible abstraction is pulled out into a common place, either Applicatives, Monads, Bimaps or Monad Transformers. Which is great that you can abstract like that. Using any Haskell library will require you to know about some of these things.

Coming from a background where I’d done Lisp, Erlang and OCaml, and some Haskell I thought I was totally prepared to start working in Haskell full time.

Learning Haskell the language is a good first step, but knowing the syntax and being comfortable reading code is one thing. What really surprised me was that knowing Haskell isn’t sufficient, you need to learn the set of typical Haskell libraries before you can really start making progress and feel at home in Haskell. Of course I’d used things like Monads in OCaml and read

No equivalent to Monad, Monad transformers, lenses, applicative, traversable library eco-system in OCaml. I naievely wonder why this hasn’t been built before and whether it’s even a good idea. The parallels to Scala and scalaz are all too apparent to me. Scala is a mixed OO/FP langauge in a similar way to OCaml. It also doesn’t enforce the same level of strictness with respect to side effects that Haskell does. So in both langauges if you want you can create a mess of side effectey code if you;re not careful. Also both langauges allow mutation, again another side effect, without tracking this via the type system.

I want to thank Mark Hibberd and Charles O’Farrell for being such great mentors over the last month, may they never grow tired of my endless questions.

Unreliable Guide to OCaml Modules

| Comments

Being on the curious side of things I have been interested lately in the dualities between programming languages. Like how one feature say Type Classes in Haskell compares to what is available in Scala or OCaml. This has lead to me reading a substantial amount of academic papers about the subject.

So with that in mind I would like to give a brief introduction to OCaml style modules. Perhaps in another post going into how can you encode something like rank n types from Haskell in OCaml which natively doesn’t support them.

Preface, the use of the word module can be confusing, and it sometimes seems that module is used to refer to structures interchangeably. I’ve tried to avoid that but it’s helpful to keep in mind for further reading. Look at what’s on the right hand side of the equals in the code. Let start.

Terminology

OCaml is a member of the ML family of languages, sharing common features like modules, Hindley-Milner type sytem and strict evaluation. OCaml as a language can be though of 2 distinct part; one a core language that’s values and types and a second module language that revolves around modules and signatures. While OCaml does provide some support for bridging these parts in the form of First Class Modules, I won’t cover them here.

The key parts of the module system in OCaml are:

Structures

Structures provide a way for grouping together related declarations like data types and functions the operate on them; they also provide the values in the module langauge. Below is a module for integer Sets:

1
2
3
4
5
6
7
module IntSet = struct
  type t = int
  type set = t list
  let empty = []
  let member i s = List.exists (fun x -> x = i) s
  let insert i s = if member i s then s else (i::s)
end

This code defines a new structure using the struct keyword and binds it to a name using module. It’s useful to note that OCaml types are written in lowercase (t, list and set) and type variables are written with a single quote 'a. Also type constructors are written differently to Haskell, in Haskell you’d have List a while in OCaml the order is reveresed t list.

Basically a struct is an opening struct followed by a bunch of type and let bindings, and closed with an end.

At the call site exposed declarations are referred to by dot notation:

1
2
IntSet.t
IntSet.empty

If no module name is defined within a file, say you have a file called set.ml with:

1
2
3
4
5
  type t = int
  type set = t list
  let empty = []
  let member i s = List.exists (fun x -> x = i) s
  let insert i s = if member i s then s else (i::s)

It will implicitly be given a structure name derived from the file name Set but as you may have worked out module names are not bound to file names. Further structures can be nested within other structures, leading to more freedom than just having 1 file becoming 1 module.

1
2
3
4
5
6
module IntSet = struct
  module Compare = struct
     type t = int
     let eql x y = x = y
  end
end;;

The values within the nested module are referred to like so:

1
IntSet.Compare.eql 1 1;;

While it is great to have functions namespaced like so, it would become tedious if you needed to use the longer name to refer to a nested module. OCaml provides a couple of solutions, first local opens.

Rather than having an open statement at the top of the file and bringing every thing into scope for that file we can do a local open and restrict the scope to between the two brackets.

1
 IntSet.Compare.(eql 1 1);;

The other option available is aliasing the module name to something shorter

1
2
 module X = IntSet.Compare;;
 X.eql 1 1;;

I mentioned open before without saying what it does. Simply open brings the contents of a module within another module, so they can be referred to without the module name prefix.

Signatures

Signatures are the interfaces for structures, a signature defines what parts of a structure is visable from the outside. A signature can be used to hide components of a structure or export some definitions with more general types.

A signature is introduced with the sig keyword

1
2
3
4
5
6
7
8
9
module type Set =
  sig
    type elt
    type t

    val empty : t
    val member : elt -> t -> bool
    val insert : elt-> t -> t
  end

As you can see looking at our definition of Set, it lists a type and function signatures without specifying a concrete implementation. It’s also bound to a name Set using module type.

As I metnioned before signatures are typically used to hide or change the interface a module exposes. By default all types and functions are exported from a module. Useful for doing things like hiding implementation details or only construct the data type via the invariant-preserving operations that the module provides.

Typically in OCaml you’ll define your struct in one file set.ml and then create a second file set.mli which contains the signature for the module set. Only occasionally will you see the signature and structure defined together.

Functors

Now to the functors, they’re not exactly like Haskell’s though they do perform a kind of mapping.

Functors are for lifting functions into the module language, or another way they are functions from structures to structures. Which brings the abstract idea of functors from category theory back to 2 concrete examples, where Haskell functors are functions from types to types, OCaml’s functors are functions from structures to structures.

Following out set example we can make set operations abstract across both the type inside the set and the equality comparison.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
module type ORDERING =
  sig
    type t
    val compare : t -> t -> int
  end;;

module type Set =
  sig
    type elt
    type t
    val empty : t
    val member : elt -> t -> bool
    val insert : elt-> t -> t
  end;;

module MkSet (Ord : ORDERING) : (Set with type elt := Ord.t) =
  struct
    type elt = Ord.t
    type t = Empty | Node of t * elt * t

    let empty = Empty

    let rec insert x = function
      | Empty -> Node(Empty, x, Empty)
      | Node(a, y, b) when Ord.compare x y < 0 -> Node(insert x a, y, b)
      | Node(a, y, b) when Ord.compare x y > 0 -> Node(a, y, insert x b)
      | Node(a, y, b) as s -> s

    let rec member x = function
      | Empty -> false
      | Node(l, v, r) ->
          let c = Ord.compare x v in
          c = 0 || member x (if c < 0 then l else r)
end;;

module IntOrdering = struct
    type t = int
    let compare x y = Pervasives.compare x y
  end;;

module IntSet' = MkSet(IntOrdering);;

Here we define ORDERING and Set as signatures, similar to our previous definitons. Then a functor is defined MkSet that takes the ORDERING signature and defines the types and functions for set based off that interface. So the definition of MkSet is completely abstracted away from the type used in the set and the functions used on those types. As long as it implements ORDERING.

The last part defines a particular ordering for int using, binding t to int and compare to Int.compare.

Using Modules

After covering what is in the OCaml module system, what exactly do we use it for. At the very basic level we collect together types and functions, which is pretty much what all modules do. Outside of that we can:

  1. Hide implementation details, like the types exported by the module. If we wanted to hide how our Set was implemented we could redefine the functor as:
1
2
3
4
5
6
7
8
9
module type SETFUNCTOR =
    functor (O: ORDERING) ->
      sig
        type t = O.t      (* concrete *)
        type set          (* abstract *)
        val empty : set
        val add : t -> set -> set
        val member : t -> set -> bool
      end;;

Here we expose the elements within the set via type t = O.t so they’re a concrete type, while set isn’t given a definition so the consumers of this module can’t look into that type without using the functions provided in the Set module. This hiding using abstract types lets us swap out different implementations for testing purposes or if requirements change.

  1. Namespace functions and type, all types and functions live within some module.

  2. Extending existing modules in a type safe way. You may want to extend a module from a library with extra derived functions. For example the Core library from Jane Street extends the built in OCaml library with a number of new and different functions. eg Say Lists didn’t provide a transpose function.

  3. Instantiating modules with State, OCaml allows modules to include mutable state (while we may not particularly like mutable things) sometimes it’s necessary and you may want multiple instances of a particular module with their own state. Functors make doing this more succinct.

  4. Collecting definitions and exporting as a single module, e.g. Core.Std inside Jane Street Core library.

Further Reading

The best reference is really Real World OCaml. If you’ve got some Haskell experience and don’t mind reading a paper then “ML Modules and Haskell Type Classes: A Constructive Comparison” by Stefan Wehr and Manuel Chakravarty gives a thorough coverage of how ML modules stack up to Type Classes.

Lenses in OCaml

| Comments

Lenses have been on my mind since encountering them last year in the context of Haskell. Much of the literature on lenses has a very Haskell slant so show how they can be used in OCaml.

The theory of lenses and their accompanying prisms and traversals, have been better described by other people. This article at FPComplete was a particularly good one. I’m just going to cover how to use ocaml-lens as a minimal lens implementation.

First since ocaml-lens isn’t in opam, clone the repo locally and open up utop. Then load the lens.ml file into utop.

1
2
utop # #use "lens.ml";;
..

Starting with a few record types for a car, editor and book.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type car = {
    make : string;
    model: string;
    mileage: int;
  };;

type editor = {
    name: string;
    salary: int;
    car: car;
};;

type book = {
    name: string;
    author: string;
    editor: editor;
};;

Creating a new book is as simple as.

1
2
3
4
5
6
7
8
9
10
11
12
13
let scifi_novel = {
   name =  "Metro 2033";
   author = "Dmitry Glukhovsky";
   editor =  {
     name = "Vitali Gubarev";
     salary =  1300;
     car =  {
       make = "Lada";
       model = "VAZ-2103";
       mileage = 310000
    }
  }
};;

Given our scifi_novel we can access the editor’s car mileage:

1
let mileage = scifi_novel.editor.car.mileage;;

Setting the mileage is a bit trickier, we need to unpack each record:

1
2
3
let second_edition = { scifi_novel with editor =
                { scifi_novel.editor with car =
                    { scifi_novel.editor.car with mileage = 1000 } } };;

That’s not really an appealing prospect, can we do better?

Enter lenses, at the most simple level a lense is a pair of functions for getting and setting a property.

1
2
3
4
5
6
7
(** Lens type definition *)
type ('a, 'b) t = {
  get : 'a -> 'b;
  (** Functional getter *)
  set : 'b -> 'a -> 'a
  (** Functional setter *)
}

With this definition of a lens, modifying the mileage is now:

1
2
let a = compose mileage_lens (compose car_lens editor_lens) in
 _set 10 scifi_novel a;;

In the background we need to define some lenses for the records above:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let car_lens = {
      get = (fun x -> x.car);
      set = (fun v x -> { x with car = v })
    };;

let editor_lens = {
      get = (fun x -> x.editor);
      set = (fun v x -> { x with editor = v })
  };;

let mileage_lens = {
      get = (fun x -> x.mileage);
      set = (fun v x -> { x with mileage = v })

  };;

Using these definitions the original lens version of modify the editor’s car mileage works.

The compose operator we used allows us to combine 2 lenses to go from the novel into the editor and then into the car. And compose can be combined with itself to build up arbitarily deep lenses into a structure.

1
let editor_car_lens = compose car_lens editor_lens;;

This way of composing can seem backwards, you supply the inner lens first then the outer lens. We can fix that by using the infix operators, open the Infix module and define the same lens:

1
let editor_car_lens = editor_lens |-- car_lens;;

This feels more intuative reading it left to right. Revisiting our original _set mileage example we can now write it.

1
2
3
_set 10 scifi_novel (editor_lens |-- car_lens |-- mileage_lens);;
(* or even *)
((editor_lens |-- car_lens |-- mileage_lens) ^= 10) @@ scifi_novel;;

The infix module comes with some other helpful operators like |. for get and ^= for set. All these operators avoid mutation so our code remains pure and referentially transparent.

Conclusion

There are a heap more things that lenses can do, and while this ocaml-lens package is pretty basic, looking at the hundreds of functions exported by Control.Lens in Haskell you can get a good idea of the possibilities. Control.Lens includes all the basic lens functions plus things like:

Resources

I made use of the following resources to write this and took some of the examples and definitions from the following articles. All mistakes are my own and probably accidental.

Lambdajam Talks

| Comments

Earlier this year I spoke at Yow! LambdaJam about RAFT and Erlang. I thought I should link to my talk descriptions and slides here.

On the first morning of the conference I spoke about the RAFT distributed consensus algorithm and how it could be implemented in Erlang/OTP. The slides are here with the video to follow sometime later. I was very happy with how the talk went despite many pre-conference nerves and will surely be submitting something next year.

In the final workshop slot of the conference I presented an Erlang workshop on building a Webmachine system for shortening urls. The source code on github here.

Yow! LambdaJam is a great conference that brings together the functional programmers from across Australia. I personally had a great time and would encourage anyone who is interested in functional programming to come along next year. We had talks on Erlang, Haskell, Idris, Scala and Clojure. I’m hoping next year we see something on OCaml and F#.

Ember.js and Google Analytics

| Comments

Update

As iStefo pointed out in the comments the code I gave has a bug in it. The observes('currentPath') on an application controller doesn’t fire when you transition between paths in the same route. eg ‘/lesson/1/activity/1’ to ‘/lesson/1/activity/2’

A better approach is to add the code to your router.

1
2
3
4
5
6
7
8
9
10
App.Router.reopen

  didTransition: (infos) ->
    @_super(infos);
    return unless window.ga
    Em.run.next ->
      ga('send', 'pageview', {
         'page': window.location.hash,
         'title': window.location.hash
      });

Matthew Beale also pointed out below that there may be a new API coming on the router to achieve the same result. PR#3452 and PR#3453


Original

Single Page Javascript Applications and specifically Ember.js applications don’t always expose the right information to Google Analytics. Usually you’ll see 100% traffic to / and nothing else.

What I wanted to be able to see what areas of the site people were using in real time. A bit of searching led to various solutions with this post having the most upto date solution. Working in Ember you quickly become wary of older solutions posted and start filtering search results based on time. Hopefully now that 1.0 is out the correct solutions will start bubbling to the top of Google searches.

To make your Ember.js application more visible to Google Analytics you need to expose the value of your application state. I’m using the hash scheme (eg #/album) so whatever is after the hash in the url shows where a person is in the application.

First you’ll need to have the Google Analytics Javascript library loaded, I’ve been using the more recent analytics.js library which has a different API to the older ga.js library. After you’ve followed Google’s instructions the library is available at ga.

Next you want to observe whenever the hash path changes within your app. The code below assumes you’re using hashes rather than HTML5 pushState.

1
2
3
4
5
6
7
8
9
10
App.ApplicationController = Em.Controller.extend

    routeChanged: (->
        return unless window.ga
        Em.run.next ->
            ga('send', 'pageview', {
                'page': window.location.hash,
                'title': window.location.hash
                });
    ).observes('currentPath')

The routeChanged function gets called when currentPath changes; it checks whether ga is defined and if it is it sends a pageview event with the current value of location.hash. The Em.run.next is there to make sure all the routing has occured and the hash value is final before using it.

page and title are just strings so you could provide meaningful formatting based on what your application does. The next obvious step is to add event tracking to really see how people interact with the app.

Erlang Hot Code Loading

| Comments

Nearly every posting about Erlang that you come across mentions the hot code loading feature, aka dynamic code loading. But so far I have had problems finding a simple example of how to add this to my code. So here is one.

Copy this code into an editor. I’m using Emacs here, so all instructions use it’s keybindings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
%% A process whose only job is to keep a counter.
-module(counter).
-export([start/0, codeswitch/1]).

start() -> loop(0).

loop(Sum) ->
    receive
        {increment, Count} ->
            loop(Sum+Count);
  {print} ->
      io:format("Sum is ~p~n", [Sum]),
      loop(Sum);
        {counter, Pid} ->
            Pid ! {counter, Sum},
            loop(Sum);
        code_switch ->
            ?MODULE:codeswitch(Sum);
  M ->
      io:format("Unhandled message ~p~n", [M])
    end.

codeswitch(Sum) -> loop(Sum).

Compile and start a new erlang shell, Ctrl-C Ctrl-K.

Now we want to start a new process running this code. Startup and enter the following code into the erlang shell.

1
2
3
4
5
Erlang R15B (erts-5.9) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
1> Pid = spawn(fun() -> counter:start() end).
<0.37.0>

Send the process a message to make sure it’s alive and working.

1
2
3
4
5
3> Pid ! {increment, 3}.
{increment,3}
4> Pid ! {print}.
Sum is 3
{print}

Now that we have the first version of the process running, add a new clause to the receive like so.

1
2
3
4
5
6
7
8
        {print} ->
      io:format("Sum is ~p~n", [Sum]),
      loop(Sum);
  {reset} ->
      loop(0);
        {counter, Pid} ->
            Pid ! {counter, Sum},
            loop(Sum);

Compile this version, Ctrl-C Ctrl-K and send a message to the process that only the new version can handle.

1
2
3
6> Pid ! {reset}.
Unhandled message {reset}
{reset}

So we are still running the previous version of the code.

1
2
3
4
5
6
7
8
9
10
6> Pid ! code_switch.
code_switch
7> Pid ! {print}.
Sum is 3
{print}
8> Pid ! {reset}.
{reset}
9>  Pid ! {print}.
Sum is 0
{print}

The ‘code_switch’ message makes the process load the new version of code. So using this you can upgrade the running process without losing state. Cool.

Getting Started With Sinan

| Comments

Background

When I started with Erlang I used a simple Makefile to call erlc and pretty much did things by hand. After a number of years in the wilderness I found out about rebar from Basho and started using that to compile my code. Everything was good, rebar knew how to compile OTP apps and pull down external dependencies. Except when I needed to generate releases. It’s not necessarily straight forward to get rebar to build you a nice release, not that it’s impossible it’s just not as simple as I’d like.

Enter Sinan, the somewhat forgotten erlang build tool.

Sinan is a build tool designed to build Erlang/OTP projects, releases and applications. It claims to be more OTP than rebar and uses the OTP metadata artefacts to build your project with little configuration needed.

Let’s see how well it delivers on the promise.

Sinan From Scratch

First you’ll need Erlang installed, which your friendly local package management tool should provide. I’m using Homebrew on OSX so I just did:

1
2
3
4
5
6
7
$ brew install erlang
...
$ erl -v
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1>

Linux should be similarly straight forward and Windows well you’re on your own.

Grab sinan from the downloads page on github, I’m using version 4.1.1. Put it somewhere on your PATH, I’ve got mine in ~/bin which is on my PATH, and chmod +x it so it’s executable.

Now for the fun bit, type sinan gen and fill in the details.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Please specify your name
your name> Tim McGilchrist
Please specify your email address
your email> timmcgil@gmail.com
Please specify the copyright holder
copyright holder ("Tim McGilchrist")>
Please specify name of your project
project name> sinan_demo
Please specify version of your project
project version> 0.0.1
Please specify the ERTS version ("5.9.1")>
Is this a single application project ("n")> y
Would you like a build config? ("y")> y
Project was created, you should be good to go!

From that Sinan has generated a project, filling in your details, with an OTP application and some build configuration. Your directories should look something similar to this.

1
2
3
4
5
6
7
8
9
10
11
12
sinan_demo
  |-- config
  |    |-- sys.config
  |-- doc
  |-- ebin
  |    |-- overview.edoc
  |-- include
  |-- sinan.config
  |-- src
  |    |-- sinan_demo.app.src
  |    |-- sinan_demo_app.erl
  |    |-- sinan_demo_sup.erl

It includes all the standard directories you’d expect plus a sinan.config file.

First a little diversion, we need to add a line to the sinan config file, which tells sinan to include the erlang runtime system when it generates a release. Open sinan.config and add {include_erts, true}. as the last line. It should look like this:

1
2
3
4
5
6
7
8
9
10
{project_name, sinan_demo}.
{project_vsn, "0.0.1"}.

{build_dir,  "_build"}.

{ignore_dirs, ["_", "."]}.

{ignore_apps, []}.

{include_erts, true}.

Back to making our generated code runnable.

By default the generated supervisor doesn’t point to a valid module so you’ll need to remedy that before trying to startup the application. Create a new file called sinan_demo_server.erl in src and drop the following code in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
-module(sinan_demo_server).

-behaviour(gen_server).

%% API
-export([start_link/0, add_one/0, total/0]).

%% Callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-record(state, {count}).

%%%===================================================================
%%% API functions
%%%===================================================================

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

total() ->
    gen_server:call(?MODULE, total).

add_one() ->
    gen_server:call(?MODULE, add).

%%%===================================================================
%%% Callbacks
%%%===================================================================

init([]) ->
    io:format("starting~n", []),
    {ok, #state{count = 0}, 0}.

handle_call(add, _From, State) ->
    NewCount = State#state.count + 1,
    NewState = State#state{count = NewCount},
    Reply    = {ok, NewState},
    {reply, Reply, NewState};
handle_call(total, _From, State = #state{ count = Count }) ->
    {reply, Count, State};
handle_call(Msg, _From, State) ->
    {reply, {ok, Msg}, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

It’s a pretty standard OTP gen_server application with 2 API methods. add_one/0 adds 1 to the counter and total/0 returns the value of the counter. The record definition setups up the state record for this server with just a count attribute. The 2 API functions use the gen_server:call/2 method to hit the OTP callback for handle_call/3.

Next we need to fix the supervisor so it starts the correct module. Change sinan_demo_sup.erl so it looks like the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================

%% @private
-spec init(list()) -> {ok, {SupFlags::any(), [ChildSpec::any()]}} |
                            ignore | {error, Reason::any()}.
init([]) ->
    RestartStrategy = one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {sinan_demo_server, {sinan_demo_server, start_link, []},
              Restart, Shutdown, Type, [sinan_demo_server]},

    {ok, {SupFlags, [AChild]}}.

The 2 changes we have make is to start_link/0 so we can call the server directly, and fix the child spec so it starts our new module.

Now we need to add the sinan_demo_server module to sinan_demo.app.src so we know about it when generating the OTP application. Just add it to the list of modules like so:

1
2
3
4
5
6
7
8
9
10
11
12
%% This is the application resource file (.app file) for the,
%% application.
{application, sinan_demo,
 [{description, "Sinan demo application."},
  {vsn, "0.0.1"},
  {modules, [sinan_demo_app,
             sinan_demo_sup,
             sinan_demo_server]},
  {registered,[sinan_demo_sup]},
  {applications, [kernel, stdlib]},
  {mod, {sinan_demo_app,[]}},
  {start_phases, []}]}.

Compile with sinan build and hopefully everything works.

From here you’ve got a few options to get your application running, but the easiest is just to use the sinan shell and start your application from there.

1
2
3
4
5
6
7
8
9
10
11
12
13
$ sinan shell
Eshell V5.9.1  (abort with ^G)
1> application:which_applications().
[{parsetools,"XLATETOOLS  CXC 138 xx","2.0.7"},
 {syntax_tools,"Syntax tools","1.6.8"},
 {compiler,"ERTS  CXC 138 10","4.8.1"},
 {getopt,"Command-line options parser for Erlang","0.4.2"},
 {erlware_commons,"Additional standard library for Erlang",
                  "0.6.1"},
 {stdlib,"ERTS  CXC 138 10","1.18.1"},
 {kernel,"ERTS  CXC 138 10","2.15.1"}]
2> application:start(sinan_demo).
ok

We’ve started a shell and checked what applications are started with application:which_applications(). Now start the demo application with:

1
2
3> application:start(sinan_demo).
ok

Now lets test that we can call the application.

1
2
3
4
4> sinan_demo_server:add_one().
{ok,{state,1}}
5> sinan_demo_server:add_one().
{ok,{state,2}}

As you can see it’s calling the server and incrementing the call count.

The next step is to create a release, which is as simple as running sinan release

Sinan has created a number of new directories under _build

1
2
3
4
5
6
7
8
9
10
11
$ tree -d _build/
    _build/
    `-- sinan_demo
        |-- bin
        |-- erts-5.9.1
        |-- lib
        |   |-- kernel-2.15.1
        |   |-- sinan_demo-0.0.1
        |   `-- stdlib-1.18.1
        `-- releases
            `-- 0.0.1

The bin directory is still there from last time but now we have an erts, lib and releases directories. erts is there because earlier we asked sinan to include an erlang runtime, so you can copy everything under _build/sinan_demo to another machine without erlang installed and run this application. The limitation being that the CPU and OS needs to match the machine you’ve built on. lib includes all the applications you asked sinan to include, they’ll match what you have in your collective .app.src files. releases contains configuration files specific to a particular release of the application.

Starting the release generated is as simple as

1
2
3
4
5
6
7
8
9
10
$ ./_build/sinan_demo/bin/sinan_demo
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

starting
Eshell V5.9.1  (abort with ^G)
1> application:which_applications().
 [{sinan_demo,"Sinan demo application.","0.0.1"},
  {stdlib,"ERTS  CXC 138 10","1.18.1"},
  {kernel,"ERTS  CXC 138 10","2.15.1"}]
2>

We’ll leave it there for now, but if you’re curious like me you’ll probably have a bunch of questions of where to take sinan next.

Next time I’m going to cover:

But if you’ve got other suggestions please leave them in the comments.

WebMachine Talk

| Comments

I finally posting my slides for the WebMachine talk I gave at ErlSyd.

The content was fairly general WebMachine and REST stuff, going into how to setup, build and structure a WebMachine application.

I’m planning on putting together something more detailed in the future, as the current WebMachine resources are rather spartan. The plan is to do an extended series of posts or a github/ebook site ala learnyousomeerlang.

Again the slides are up on github @ github.com/tmcgilchrist/webmachine_talk/.

Riak, Ruby and Ripple Talk

| Comments

I recently presented a talk to RoRo Sydney, the local Ruby UG, on Riak and Ripple.

The content was more on the general side of things, with my purpose being to introduce the core Riak ideas and give some Ruby code for interacting with Riak.

The slides are up on github @ github.com/tmcgilchrist/riak_ripple_talk/.

Git Rebase Workflow

| Comments

New gist for using a rebase workflow with git.

Again probably not interesting to everyone but it gives the bare bones of what you need to do.