Using F# on both the frontend and the backend

10 December 2016

Note: This post was written in 2016. Since then, the introduction of the SAFE stack has significantly improved the sitation in F#, but the basic ideas of this blog post are still valid - they are just a lot nicer now :)

When the call for the F# Advent Calendar came up I thought that this would be a great opportunity to finally check out a technology stack that intrigued me for quite a while now: Using F# on the backend (which by now works well on linux/osx as well as windows) and also on the frontend, via Fable, the F# to Javascript compiler backend. I have played a bit with F# in the past but I wanted to see how well this particular combination works in practice.

The same language on the backend and the frontend

Using the same language on the server and the client has many benefits in my opinion, chief among them the ability to reuse data definitions and business logic. Even though many modern web sites shoulder a lot of complexity on the client to guide the user and give immediate feedback, the backend usually has to replicate most of this logic to verify the client submissions and guard against malicious clients. Discount rules are a prime example of such code that is often replicated in both the frontend and the backend.

The first language that will probably come to mind for this job is Javascript. Since the advent of Node, Javascript is available on the backend as well as in the browser, and, with Electron, even for desktop apps with a native feel. Heavy performance tuning has made Javascript reasonably fast. However, I think that its dynamically typed nature makes Javascript a very problematic choice for non-trivial software projects. Static type checking can catch many bugs before they ever hit production and it can free your developers to concentrate on testing the properties of their code that are actually interesting.

A very desirable property for a type system is for it to have Algebraic Data Types. This means that, in addition to Product types (think classes or records) where ALL stated fields exist for every instance, they also support Sum types (Discriminated Unions in F#) where every value adheres to exactly one of several strictly predefined layouts. Together, Product and Sum types allow a much richer modelling where you can make illegal states irrepresentable (see this recent article by Marc Seemann on the benefits of ADTs). Having Sum types also allows languages to get rid of nulls - a very desirable trait since a big fraction of errors in dynamically typed languages or such with weak type systems are NullReferenceExceptions or the infamous “undefined is not a function”.

Possible languages

Ok, now that I have outlined desirable feature, let us look for languages that meet these two core requirements (a strong, static type system with ADTs and being usable via cross-compilation to Javascript on both the browser frontend and the backend). Not a lot of options remain. The ones I know are:

All of these are interesting languages. Here is my very personal reasoning for choosing among these languages: Typescript is a superset of Javascript with type annotations that, since version 2.0, has support for union types. It is a big improvement over raw Javascript, but I think that one still feels a lot of the odd language design decisions underneath it, so I will disregard it for now.

The javascript compiler backends for OCaml and Haskell have a relatively small set of Javascript library bindings available and are IMHO harder to interface with native Javascript libraries - for now I don’t think that they are immediately usable if you want to write user interfaces with them.

This leaves me with F#/Fable and Purescript. Purescript was designed from the beginning with Javascript as the compile target in mind. Quite a few important Javascript libraries have been annotated with type definitions for Purescript and are thus readily usable, and if they are not, the Purescript FFI was built for Javascript and is very straightforward to use. Additionally, the type system of Purescript is very powerful and feels a bit like a modern refresh of Haskell’s type system.

So what about F#/Fable? The basic story is similar to OCaml/Haskell in that you have to create FFI definitions and these are only available for a few libraries so far. What is really neat about Fable though is that there is a way to bootstrap Fable FFI files from Typescript definitions via ts2fable - and those are available for a huge number of important Javascript libraries. I think that this lowers the pain of interfacing with native Javascript libraries enough for F#/Fable to be a reasonable choice.

F# versus Purescript

Purescript is definitely an interesting contender that I want to study more in the future, but this blog post is about F#, so, let us ask the obvious question: why use F# instead of Purescript? YMMV but I see F# to have an interesting advantage on the server side since IMO on the backend the .NET platform is a more solid runtime than Node. Since F# compiles to IL and can interface with any .NET library, it has access to a huge amount of libraries that interface with all sorts of systems, parse files etc. It also supports strong multi-threading primitives and F# even has support to cross compile to the GPU - this makes it much more interesting for numerically intense workloads than Node.

This means that if you either already have a big chunk of business logic written in a .NET language or if you need to do high performance computations on the server, F# is IMO a more attractive choice than Purescript. Additionally, because F# is more in the tradition of pragmatic functional languages like OCaml than the Haskell tradition of that Purescript adopted, it offers the escape hatches of mutability and side effects within the normal control flow (this is arguably also dangerous, but debating this is for another post).

The downside of F#/Fable is that the same language is bolted onto two different runtimes with slightly different semantics. One example of such a mismatch is that the fixed-point arithmetic datatype Decimal of the .NET platform does not exist in Javascript of course and is thus silently converted to a double. For many cases this is fine but it is definitely something to be aware of (a longer list is here )

Alright, so this is why I think it makes sense to use the same language on the backend and frontend, some of my criteria for choosing a language and why F# is the candidate I want to use.

The proof of concept idea

Let’s finally get to some code! Be warned that some of this is probably not exactly idiomatic F# code since I haven’t used the language much until now :)

The basic idea for my little proof of concept was:

  • Write a frontend in F# that is the most primitive shopping cart you can imagine - it just has one product and the user can use buttons to increase/decrease the quantity.
  • Have a type that defines a discount, consisting of: a name, a function that checks whether the discount applies and one that modifies the price. Reuse these data types and functions between the frontend and the backend
  • On the frontend, use Fable-Arch to bring the clarity of the Elm Architecture to F#
  • Bundle up the generated Javascript into an Electron app to see how well this works
  • Since the Electron Desktop app is based on the Chromium engine, use the power of CSS and icon fonts to pep up the UI a little by just dropping in some CSS from a third party.
  • Try Suave as a http server with a functional design. Reuse the type definitions and discount calculation code. Handle Json-Serialization and CORS headers.

The implementation

The entire setup is on github at where you can just clone it and run both the Suave server and the electron based client.

Since this is a proof of concept, the actual code is maybe less interesting than the setup around it, but for completness sake, what follows are the three main file that are the essence of the two programs. First, the shared code that defines the Cart and Discount types, a concrete instance of the Discount type that gives a 90% discount at twelve items and the function to calculate the price for a cart given a list of potentially applicable discounts

namespace DiscountSample

module Shared =

  let ItemPrice = 20.0

  type Cart =
    { Quantity: int

  type Discount =
    { Name: string
      Applies: (Cart -> bool)
      ApplyDiscount: (double -> double)

  let doesTwelveItemsDiscountApply cart =
    match cart.Quantity with
    | 12 -> true
    | _ -> false

  let twelveItemsDiscount =
    { Name = "12 Items - 90% off!"
      Applies = doesTwelveItemsDiscountApply
      ApplyDiscount = (fun price -> price * 0.1)

  let calculatePrice (discounts : Discount list) (cart : Cart) : double =
    let discountsThatApply = List.filter (fun discount -> discount.Applies cart) discounts
    let cartCalculationFunction =
      match discountsThatApply with
      | [] -> id
      | x :: xs -> x.ApplyDiscount // use the first discount that applies only, discard the others
    let undiscountedPrice = (double cart.Quantity) * ItemPrice
    cartCalculationFunction undiscountedPrice

This shared code is then used in the frontend:

#r "../node_modules/fable-core/Fable.Core.dll"
#load "../node_modules/fable-arch/Fable.Arch.Html.fs"
#load "../node_modules/fable-arch/Fable.Arch.App.fs"
#load "../node_modules/fable-arch/Fable.Arch.Virtualdom.fs"
#load "../../backend/src/ClientServerShared.fs"
#r "../node_modules/fable-powerpack/Fable.PowerPack.dll"

open Fable.Core
open Fable.Core.JsInterop
open Fable.Import.Browser

open Fable.Arch
open Fable.Arch.App
open Fable.Arch.Html
open DiscountSample.Shared
open Fable.PowerPack

type Status =
  | Shopping
  | TransactionPending
  | BuyingFailed of string
  | BuyingSucceeded of double

type Model =
  { Cart: Cart
    Status: Status

let initModel =
  { Cart = { Quantity = 0 }
    Status = Shopping

type Actions =
  | IncreaseQuantity
  | DecreaseQuantity
  | Buy
  | ServerResponseOk of double
  | ServerResponseError of string
  | SetStatus of Status

// Update
let update model action =
  let model' =
    match action with
    | IncreaseQuantity ->
      { model with Cart = { model.Cart with Quantity = model.Cart.Quantity + 1 } }
    | DecreaseQuantity ->
      { model with Cart = { model.Cart with Quantity = System.Math.Max(0, model.Cart.Quantity - 1) } }
    | SetStatus status ->
      { model with Status = status }
    | Buy -> model
    | ServerResponseOk price -> { model with Status = BuyingSucceeded price }
    | ServerResponseError error -> { model with Status = BuyingFailed error }

  let delayedCall h =
    match action with
    | Buy ->
        let promise = Fable.PowerPack.Fetch.postRecord "" model.Cart []
                      |> Fable.PowerPack.Promise.bind
                          (fun response ->
                          (fun price ->
                            h (ServerResponseOk price)
                      |> Fable.PowerPack.Promise.catch
                          (fun err ->
                            h (ServerResponseError err.Message)

        h (SetStatus TransactionPending)
     | _ -> ()

  // We return the model, and a list of Actions to execute
  model', delayedCall |> toActionList

let availableDiscounts =
  [ twelveItemsDiscount ]

let view model =
  let infoText =
    match model.Status with
    | Shopping -> "Please make your selection"
    | TransactionPending -> "Waiting for confirmation from server"
    | BuyingFailed msg -> "Sorry, your purchase failed! The reason was: " + msg
    | BuyingSucceeded price -> "The purchase worked, with a final price of " + (price.ToString())

  let counterView quantity =
    div []
      [ label [] [ text ("How many items do you want?") ]
        button [ onMouseClick (fun _ -> IncreaseQuantity) ] [ text "+" ]
        label [] [ text (quantity.ToString()) ]
        button [ onMouseClick (fun _ -> DecreaseQuantity) ] [ text "-" ]

  let counters =
    [ counterView (model.Cart.Quantity) ]

  let applicableDiscounts =
    List.filter (fun item -> item.Applies model.Cart ) availableDiscounts

  let discountView (discount : Discount) =
    li []
      [ label [] [ text discount.Name ] ]

  let discountsView (discounts : Discount list) =
    ul [ classy "discounts" ]
      ( discountView discounts)

  let totalPrice =
    div [] [ text <| "The total price is: " + ((calculatePrice availableDiscounts (model.Cart)).ToString()) ]

        [text "This is your shopping cart: "]
        [ text infoText ]
      br []
      div [] counters
      discountsView applicableDiscounts
        [ onMouseClick (fun _ -> Buy)
          classy "buy"
        [ i [ classy "fa fa-bolt" ] []
          text " Buy!"

/// Create our application
createApp initModel view update Virtualdom.createRender
|> withStartNodeSelector "#echo"
|> start

And finally the server code using Suave:

open Suave                 // always open suave
open Suave.Web             // for config
open Suave.Writers
open Suave.Filters
open Suave.Successful
open Suave.Operators
open Newtonsoft.Json
open FSharp.Core
open DiscountSample.Shared

type Error =
  { Error : string

let discounts = [ twelveItemsDiscount ]

let serializeJson obj =
  let converter = new Fable.JsonConverter()
  JsonConvert.SerializeObject(obj, converter)

let deserializeCart str =
  let converter = new Fable.JsonConverter()
  let deserialized = JsonConvert.DeserializeObject<Cart>(str, converter)
  let boxed = box deserialized
  match boxed with
    | null ->
    | other ->
      Some deserialized

let deserializeCalculateSerialize json =
  let deserialized =
    |> deserializeCart

  match deserialized with
    | Some cart ->
        |> calculatePrice discounts
        |> serializeJson

    | None ->
      { Error = "Could not deserialize" }
      |> serializeJson

let mapJson f =
  request(fun r ->
    |> f
    |> Successful.OK)

let setCORSHeaders =
    setHeader  "Access-Control-Allow-Origin" "*"
    >=> setHeader "Access-Control-Allow-Headers" "content-type"

let allow_cors : WebPart =
    choose [
        OPTIONS >=>
            fun context ->
                context |> (
                    >=> OK "CORS approved" )

let app =
  choose [
    POST >=> path "/test" >=> (mapJson deserializeCalculateSerialize) >=> Writers.setMimeType "application/json"

startWebServer defaultConfig app

Final thoughts

I think that the ability to use F# on the backend with the full power of the .NET ecosystem but now also share code that does not depend on .NET libraries (like business logic and the core problem domain code) with the frontend is a very exiting development. I’m looking forward to exploring this in more detail in the future :).

I’d also be interested in hearing about people who already use this stack or are exploring one of the other options on using the same language on the frontend and the backend.

Finally I’d like to thank the numerous great people in the F# universe who keep improving this ecosystem and create examples and blogposts about them - to name just a few that I learned from the most about F#: Tomas Petricek, Scott Wlaschin, Alfonso Garcia Caro, Steffen Forkmann and Sergey Tihon!

Ports in Elm

26 February 2016

(Disclaimer: This post was written about Elm 0.16. Signals, the mechanism described in this post, have since been deprecated. The concepts in this post may still help understand how the Elm Architecture works internally, but the actual code has changed significantly)

This is the third post in a series of posts about Elm. In my first post about Signals in Elm I briefly mentioned ports. Since they are the only way to communicate with “native” Javascript, they certainly warrant a closer look. If you haven’t checked out the last post in this series on tasks and effects I suggest you do that now as this post will build on these concepts.

So what are Ports, exactly? They are basically a way to send messages from Elm to native JS or from JS to Elm. They are defined in Elm with their own keyword, port. If a Port is defined to be of a Non-Signal type (e.g. port initialUrl : String) then it is a “one time” message (at init time of the Elm code), i.e. such ports can be used if you want to send initialization values from JS to Elm at init time (and never afterwards). More frequently it will be a Signal of some type (e.g. a Signal String). Ports can not send and receive values of any type but only a subset - the big two groups of values that can’t be used are functions and union types (Maybe is the only exception to this rule). All the details can be found on the elm guide page on interop.

As a simple example, let’s create a pair of ports to send Strings from Elm to Js, do something with it in native JS, and then send the Strings back. One case where something like this might be useful would be to encrypt values using a native library (using one of the new Browser crypto APIs).

Outgoing ports

Since we want to send stuff several times, not just once, we need to declare both ports as Signals. Let’s start with the outgoing port and on the Elm side:

port requestEncryption : Signal String
port requestEncryption =
  -- how do we get a Signal here for the implementation?

This is a simple outgoing port definition, but somehow we have to implement this port - we need a way to get a Signal that we can “trigger” in our elm app and that will be received on the JS side. Let’s see how the JS side will look like before coming back to Elm:

var div = document.getElementById('root');
var myapp = Elm.embed(Elm.MyApp, div);

function encryptString(message) {
    // do something with the string, send it to be encrypted etc

Pretty straigthforward. We use the subscribe method to register a callback that will be called with the message string value every time the Signal fires at the Elm side. Ok, but how do we finish implementing this on the Elm side?

There are two ways to do this - one is to create a new Mailbox and use Effects to send our messages, the other is to create a custom version of StartApp that returns an additional value for things to send to the port in update. I have implemented both attempts as gists, here is the one with the Mailbox and once with a modified StartApp. For the rest of the blogpost I will refer to the first version since it works with the vanilla StartApp. Ok, let’s hook up the Mailbox:

portRequestEncryptionMailbox : Mailbox String
portRequestEncryptionMailbox =
  mailbox ""

port requestEncryption : Signal String
port requestEncryption =

This initalizes the Mailbox and fills in the hole we had before - the Signal we use as a port will just be the Signal of our new Mailbox. But how do we actually send anything to this Mailbox? By creating an Effect, like so:

sendStringToBeEncrypted : String -> Effects Action
sendStringToBeEncrypted clearText =
  Signal.send portRequestEncryptionMailbox.address clearText
  |> Effects.task
  |> (\_ -> Noop)

-- and this is our update function that now returns a tuple of (Model, Effect):
update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of
    TextChanged text ->
      ( { model | clearText = text }
      , sendStringToBeEncrypted text -- create the Effect here
    -- other cases ...

The last line in sendStringToBeEncrypted may be a bit confusing - what are we mapping there? Let’s take a look at the type of Mailbox.send:

send : Address a -> a -> Task x ()

This means that the success type of the task we get back from send is () (aka Unit) which acts a bit similar to void in C like languages, i.e. it represents “no actual value”. Let me desugar sendStringToBeEncrypted so it is clearer what types we are working with:

sendStringToBeEncrypted : String -> Effects Action
sendStringToBeEncrypted clearText =
  sendTask : Task x ()
  sendTask = Signal.send portRequestEncryptionMailbox.address clearText

  effectOfUnit : Effects ()
  effectOfUnit = Effects.task sendTask

  effectOfAction : Effects Action
  effectOfAction = (\_ -> Noop)

(Note that instead of first converting to Effects () and then mapping that I could also have mapped the Task x () to Task x Action and then converted the Task to Effects). This may still seem a bit weird but it may help to realize that in this particular case of sending a message to a mailbox we are explicitly not interested in an actual Action value. We are only interested in performing the side effect of sending the message and it will not have a reasonable “payload” that should be routed through update. But because of how Effects are typed in StartApp, we do need to have an Effects Action in the end and so we introduce a Noop value that explicitly does nothing when it is processed in update.

At this point it is important to remember that StartApp.start returns a record that contains a tasks field and this has to be wired to an outgoing port - if you don’t do this, the Tasks you create via Effects will never be executed by the runtime:

app =
    { init = init
    , update = update
    , view = view
    , inputs = []

port tasks : Signal (Task.Task Never ())
port tasks =

Ok great, this is the outgoing part of the ports - how about handling stuff that comes into our Elm program?

Incoming Ports

Let’s start on the Javascript side. We will define an incoming port called encryptionCompleted on the Elm side, and here we see how to send messages to it from JS. (Note that this example simplifies the logic a little and immediately after receiving a message from the outgoing port it sends an encrypted value back to Elm via the incoming port - in practice encryptString would probably call an API that returns a promise and only when this is fullfilled call send to send a value back to Elm)

var div = document.getElementById('root');
var myapp = Elm.embed(Elm.MyApp, div, {encryptionCompleted : ""});

function encryptString(message) {
    encryptedMessage = "Encypted: " + message; // actually encypting the message is ommited

Note that I not only had to modify encryptString but also pass in an initial value at the time when we initialize Elm with the call to Elm.embed. The third parameter takes the initial value of every incoming Signal we define on the Elm side - it is required because Signals in Elm always need an initial value. Let’s add this incoming port on the Elm side to complete the example:

port encryptionCompleted : Signal String

Note that this time the port we have defined has no “implementation” in Elm. That is because, viewed from Elm, this is just an external input - a Signal we can use to trigger behaviour in our app. But how can we do that? How can we wire up this Signal into our StartApp.start call?

In the last post, when we switched from StartApp.Simple to StartApp, I mentioned inputs. inputs is a List of (Signal of Action), i.e. Signals that fire Actions that will be combined with the Signal of the main mailbox that is administered by StartApp. So this is exactly what we want to have for this little program so it can react to the Signal that represents the port - the only thing that is missing is that we have defined encryptionCompleted as a Signal of String and we need a Signal of Action for inputs. Sounds like we need a map again:

encryptedString : Signal Action
encryptedString = EncryptedValueReceived encryptionCompleted

app =
    { init = (init, Effects.none)
    , view = view
    , update = update
    , inputs = [ encryptedString ]

And voilà! We have a Signal of Actions that we can put into the inputs part of start.

So just to recap, let’s go through the example again: Whenever the user enters text we process the TextChanged value in our update function and not only update the model but also create a new Effects. This is then returned by update and, because we wired the tasks part returned by start to an outgoing port, it is handed to the runtime. This leads, on the native JS side, to a call of encryptString (because this is the function we registered with subscribe). In it we pretended to do some encryption and then sent the value back with encryptionCompleted.send (again, you can send values at any time, it only happens in our example that we send one value back for every value we receive on the JS side). This send call leads the encryptionCompleted Signal to fire, with the string value we sent from the JS side. This is than mapped into an Action value, namely EncryptedValueReceived, and because this is hooked up to the inputs part of StartApp it triggers the same chain through update as any other events. In update we then handle processing of this EncryptedValueReceived value and the whole exercise is complete.

Thanks for reading through this long post! I hope it was useful and I appreciate any feedback you might have!

Tasks and Effects in Elm

19 February 2016

(Disclaimer: This post was written about Elm 0.16. Signals have since been deprecated. The concepts in this post may still help understand how the Elm Architecture works internally, but the actual code has changed significantly)

This is the second post in a series on some of the concepts in Elm that might be a bit puzzling when you start out with Elm. In the last post about Signals in Elm I wrote about Signals and how they are behind the scenes of StartApp.Simple. In this post I get into long running operations like XHRs (aka AJAX). There are two closely related types that are involved in this, Tasks and Effects, and the exact differences between can be confusing in the beginning. So let’s dive right in:


Task is the more basic type (it is defined in Core) and so let’s start with this one. A Task represents a long-running operation that can fail (with an error type) or succeed (with a success type). It’s type is thus:

Task errorType successType

-- (or, as it is actually written in the library:)

Task x a

There are only two values of Task you can create yourself in your code, without using a separate library. These two ways are two functions:

succeed : a -> Task x a

-- and

fail : x -> Task x a

These are ways to create task values without actually doing any long-running operations. This can be useful if you want to combine a long running task and a simple value in some way and process them further (you would then turn the simple value into a Task with succeed).

Most of the time you actually get in contact with tasks, these will be created for you by library functions that initialize the task so that it will perform some long running operation when the runtime executes it and handle the result of the operation according to Task semantics (I.e. that some native code will make sure to call fail or succed on the native representation of the task when the operation is finished).

Note that the operation doesn’t start right away! I said “when the runtime executes it”. In purely functional programming languages, inside the language you can never just perform a side effect (something that changes “the world” outside the internal state of your code), and sending an http request surely is a side effect in that sense. This is one of the big mental shifts from imperative programming, where you can always do this, to working with purely functional languages where you can’t.

So how does this actually work? The task you get back represents the long running action. When a library creates it for you, nothing “happens”, it just created a value (of type Task) that indicates what you would like to happen.

If you look at e.g. the implementation of the native part of the send function in http you will see that a Task is created in native JS code by handing it a callback. This callback is what will get called when the runtime actually executes the task. This is when the actual XHR request is created and performed - only when the runtime executes this callback.

So how do you get the runtime to run this task? By passing it into an outgoing port. I will go into detail on ports in a later blogpost, but suffice to say that they are a way to send messages between “native” JS and Elm (called an incoming port) and from Elm to native JS (an outgoing port). The runtime has some special casing for Tasks that come to it via outgoing ports that make it execute the callback the Task represents.

When the long running native code is done, it will either call succeed or fail on the task. In most real life code that uses the Elm Architecture you will set up a “chain” of task processing that will lead to the the end result of the task execution being that a value of your Action type is routed back through your update function. This value of your Action type is the usually tagged with the result of the task (e.g. the decoded Json response of an XHR).

As a last piece of info before we have a look at Effects and how all of this actually looks in an example, let me just mention that Tasks can easily be chained togehter with andThen, much like promises in JS are chained together.


On to Effects! If you look at the definition for Effects it’s pretty simple:

type Effects a
    = Task (Task.Task Never a)
    | Tick (Time -> a)
    | None
    | Batch (List (Effects a))

None and Batch are helpers, so the basic things an Effect can represent are Tasks (with error type Never) and Ticks. The latter is used for animations if you want to do something at the next animation frame.

It’s very common to turn a Task into an Effect, whereas the inverse is usually only ever done by StartApp/the runtime.

Several libraries use Task to allow you to work with long running operations - Http is one, elm-history is another.

So how is this used? The Elm Architecture example 5 uses this very central piece of code:

getRandomGif : String -> Effects Action
getRandomGif topic =
  Http.get decodeImageUrl (randomUrl topic)
    |> Task.toMaybe
    |> NewGif
    |> Effects.task

Let’s look at what it does. It starts with creating a task that represents the Http get operation and then builds a chain on top of this. I will deconstruct this from using the pipe operator to normal function calls with type annotations to hopefully explain what’s happening:

getRandomGif topic =
  getTaskWithError : Task Http.Error String
  getTaskWithError = Http.get decodeImageUrl (randomUrl topic)

  getTaskWithNoErrorAndMaybe : Task Never (Maybe String)
  getTaskWithNoErrorAndMaybe = Task.toMaybe getTaskWithError

  getTaskWithNoErrorAndAction : Task Never (Action)
  getTaskWithNoErrorAndAction = NewGif getTaskWithNoErrorAndMaybe

  taskAsEffect : Effects Action
  Effects.task getTaskWithNoErrorAndAction

So in the end, Effects in this case just wraps the Task for us. Because we used toMaybe and then mapped it to the NewGif type constructor function, this will result in an Action coming back to us via update when it is done that is either (NewGif Nothing) if the http request failed, or (NewGif "some-url-here") if it succeeds. If you want to understand how this wiring happens I would suggest looking at the implementation of Effects.

One thing that is worth looking at is the return type of the function: Effects Action. Effects has a type variable, just like for example List. So this is an Effects that deals with the Action type you define in your application - and this is the really neat part of how to make sure that you can deal with the result of the Task/Effect - the result will just be a value of your Action type!

At this point you may wonder: why have Effects at all? Aren’t they just weird wrappers for Tasks? Let’s quickly take a look again at how the Task case of the Effects type is defined:

type Effects a
    = Task (Task.Task Never a)

The way StartApp is typed, going via Effects Action constraints all Tasks to come back with Actions and have the error type Never. This is really nice because it means that you don’t have to handle different task types to different ports, but you set up “pipelines” of tasks to effects like with getRandomGif above and it will all work out in a typesafe manner that the result of your tasks will be sent back to your program’s update function as Actions.

Ok, so finally, remember I wrote something about having to send Tasks off to an outgoing port. I you don’t do this, the Tasks will never be executed! If you want to use Effects, the easiest way is to switch from StartApp.Simple to StartApp. This brings three minor changes with it:

  1. start no longer directly returns a Signal of Html but a record of 3 Signals: one for the html, one for the model, and, crucially for us, one of tasks.
  2. The update function now returns not just the Model, but a tuple of (Model, Effects Action). I.e. that every case in your update function will have to return both the changed model and an Effect (which will often be Effects.none)
  3. start gets a fourth parameter, inputs, for incoming Signals.
  4. The tasks part of the record that is returned by start has to be handed to a port so that the Tasks/Effects are actually performed by the runtime like so:
app =
    { init = init "funny cats"
    , update = update
    , view = view
    , inputs = []

main =

port tasks : Signal (Task.Task Never ())
port tasks =

Phew, this got a little long again, but I hope it helps a little to understand how Tasks/Effects work!

Signals in Elm

12 February 2016

(Disclaimer: This post was written about Elm 0.16. Signals, the mechanism described in this post, have since been deprecated. The concepts in this post may still help understand how the Elm Architecture works internally, but the actual code has changed significantly)

I have rewritten a webapp from React/Redux to Elm over the last few weeks and am really enjoying the language so far. Elm is a compile to Javascript, purely functional language that was built specifically to create web UIs with it. It is inspired by several functional programming languages, especially Haskell and OCaml. I have participated in the Elm google group quite a bit lately and I noticed that even though the Elm docs are really good, there are some concepts that are a bit hard to understand and to differentiate from each other. I am therefore starting a mini-series of posts about different concepts in Elm. This first one is about Signals - and why you don’t see them much in many smaller Elm programs even though they are always there.

These blog posts assume that you already know a little bit about Elm, e.g. you have gone through the great primer “Road to Elm” by Lambdacat and then studied the Elm Architecture Tutorials a little. OTOH, if you already use Tasks and Ports extensively you will find most of this a bit boring :). If you already know about Signals, you may want to jump ahead to the next post about tasks and effects or the one after that about ports

What are Signals?

Elm uses a very nice unidirectional architecture for the flow of:

displayed website ➞ user actions ➞ new application state ➞ displayed website

All the code you write in a typical Elm program comes together in just two pure functions: update and view. Update takes a user action and the previous application state and creates a new application state, and view takes an application state and renders it into a virtual dom representation (that then gets efficiently displayed by batching diffs to the DOM a la React). For more background on unidirectional UIs in general see André Staltz’ excellent blog post Unidirectional User Interface Architectures

One of the key concepts in Elm is that of a Signal. A Signal is a value that can change over time. One of the conceptually simplest signals is the current time - every second the signal “fires” with the new time value (seconds passed since epoch or whatever). Another example could be the coordinates of the mouse cursor in the current window. When the mouse is still, no values are fired by the Signal - but whenever the user moves the mouse, new values are sent. (This is actually one of the examples at Signals are a bit similar to EventEmmitters or Observables in Javascript - the key difference is that they exist for the entire lifetime of the program and always have an initial value.

Signals don’t provide any access to their history - they only provide the current value. But even a simple counter example needs to track the number of clicks that happened so far. Since Elm is a pure language with no mutable state, how do you keep track of the current click-count? We’ll come back to that question, but first let’s look at how StartApp.Simple works that you probably know from the Elm Architecture Tutorials.

StartApp hides a bit of wiring from you, but I think it helps to understand how StartApp.start does its magic. What the start function does is hook up a Mailbox (something where messages go when you send them to the address e.g. in an onClick handler) so that they lead to a new html emmited to main. This is the heart of the unidirectional UI approach. The user clicks a button, this leads to a message being sent to the mailbox. The mailbox has a Signal that fires whenever a message is sent to it. This Signal is of your applications Action type, i.e. it fires Action values. Eventually this leads to a full cycle through your update/view functions and thus to a new version of your Virtual Dom.

Let’s look at the intermediary types more closely: we start with a Signal of Actions. This then gets turned into a Signal of Models (so everytime a new Action is fired this action value is run through update together with the last model state to get the new model state). This finally gets turned into a Signal of Html (whenever the Signal of Model fires, we run it through the view function to arrive at a new Html to display). This is then handed to main so that the Elm runtime can display it for us.

Note that when I wrote about the update function, I said “together with the last model state”. This brings us back to our question from above - how can you work with history or state in Elm? The answer is in the function called Signal.foldp (“fold from the past”). If you aren’t familiar with folds yet, they are another name for reduce functions (as in map/reduce). It logically reduces all the values from the entire history with a given function and returns the value - in our case it uses the inital Model and reduces all Actions that were sent to our program to arrive at a current Model. (the implementation actually just caches the last current value and works from there of course).

At this point, if you want to really dive into it, let’s look at how StartApp.Simple is actually implemented (I added comments and type annotation to every named value)

start : Config model action -> Signal Html
start config =
    -- create the main Mailbox. It is of type "Mailbox (Maybe action)" and is
    -- initialized with an "empty" value of Nothing
    actions : Mailbox (Maybe action)
    actions =
      Signal.mailbox Nothing

    -- here the address is set up. Since the Mailbox is of Maybe action,
    -- everything that is sent to address is "wrapped" in the Just type
    -- constructor and forwarded to the Mailbox
    address : Address action
    address =
      Signal.forwardTo actions.address Just

    -- This local version of update just wraps config.update to
    -- take care of the Maybe part of the action that will be
    -- processed (so that the update function the user provides)
    -- can simply operate as Action -> Model -> Model)
    update : Maybe action -> model -> model
    update maybeAction model =
      case maybeAction of
        Just action ->
            config.update action model

        Nothing ->
            Debug.crash "This should never happen."

    -- set up a signal of new models that foldp-s over
    -- the actions signal. This is the central piece
    -- that makes the elm architecture work the way it does.
    -- The update function will process one Action and
    -- the old Model state to the new model State, the
    -- Signal that triggers it all is the Mailbox' Signal
    -- we set up at the top
    model : Signal model
    model =
      Signal.foldp update config.model actions.signal
    -- Finally, map over it with the view function. This
    -- turns the Signal of Models into a Signal of Htmls
    -- that can be rendered (config.view address) model

StartApp.Simple is quite clever in how it uses a Signal under the hood but as a user who just wants to write some interactive web app you never need to deal with Signals directly and can just supply update and view. It all works fine until you need to message back and forth with native javascript. For that, you will need to use Ports, and understanding Signals first will be very helpful for that. The other thing StartApp.Simple does not let you do is perform long running operations, like e.g. send XHR requests.

The next post in the series deals with Tasks and Effects, while the final post is all about ports. I hope you enjoyed the article and if you have any feedback please let me know!

Slides for my talk about Elm at Berlin.js

11 February 2016

Last month I had the oppertunity to talk about Elm at the very friendly Berlin.js Javascript usergroup. If you don’t know about elm, it’s a pretty new, small language designed to create websites. The language is purely functional, nicely small, and modelled on Haskell and OCaml. Have a look at the slides if you are interested and follow the links on the third-to-last slide for more information! (If you use the arrow keys for navigating don’t miss the slides that extend downwards - or just use the spacebar to see all).