Skip to content

Elm on Erlang

Victor Hugo Borja edited this page Aug 19, 2016 · 7 revisions

This page describe how elmer handles things like partial function application on Erlang.

Module names

Modules in Elm start with uppercase letter and can contain the dot character. Module names like List get converted into the atom 'Elm.List' (akin to Elixir)

Variable names

In Erlang all variables start with an uppercase letter, so Elm variables like x get converted into V_x.

Exposed values from modules

In Elm you can expose almost any value, for example

module Foo exposing (bar)

bar = 22

The bar value is bound to the constant 22. However in erlang, all you can export from inside modules are functions, so in elmer the previous example becomes something like:

-module('Elm.Foo')

-exports([ bar/0 ]).

bar() ->
  22.

Unions and Tuples

Elm Unions are implemented in erlang as tagged tuples, that is

type Foo a = Bar | Baz a

Generates two constructors (functions):

Bar which when invoked produces the erlang value {'Bar', {}}

Baz which produces erlang values like: {'Baz', {ValueA}}

Note that the first element of the tuple is an atom of the constructor name, and the second element is a tuple with the constructor data if any.

In Elm all data constructed from a Union carries the name of the constructor used for it. The constructor name is used for some things like pattern matching.

Both Erlang and Elm have the notion of tuples, however, in Elm a tuple can be think of as just another Union with up to 9 constructors. So a tuple of two elements (1, 2) gets compiled to erlang {'_Tuple2', {1, 2}} because both tuples and unions share the same access semantics.

Functions

In Elm all functions can be partially applied, that is, you don't need to give it all arguments it expects, and will return a partially applied function expecting just the missing arguments.

In Erlang, all functions have a fixed arity, there is no varargs functions in erlang. However you can pretty much emulate having the function take a single array argument.

So any function you write in elm is then wrapped by elmer into a partially applied function. Partial functions take a single argument: a list of values.

See elmer_runtime:partial/2

module Foo exposing (bar)

bar x y =
  (+) 2

becomes something like

-module('Elm.Foo').

%% Note: the exported value is the partially applied function.
-export([ bar/0 ]).

bar() ->
    ('Elm.Basics':'+'())([2]).

As you can see, anonymous functions are wrapped in partial, and all calls are made using a list of arguments so the partial application can do its magic.

Also from this example, you can see that 'Elm.Basics':'+'() (the exposed + function from module Basics) yields a partially applied function.

Clone this wiki locally