-
Notifications
You must be signed in to change notification settings - Fork 0
Elm on Erlang
This page describe how elmer
handles things like partial function application on Erlang.
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)
In Erlang all variables start with an uppercase letter, so Elm variables like x
get converted into V_x
.
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.
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.
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.
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.