Core Erlang: Why have <e_1,...,e_n>?

Yes, that is correct.

Here follows an example where it used. First consider this Erlang function:

foo(0, 0) -> invalid;
foo(A, B) -> A + B.

In Core Erlang, a function cannot have multiple clauses. Therefore, multiple clauses in Erlang is translated to a case in Core Erlang:

'foo'/2 =
    fun (_0,_1) ->
          case <_0,_1> of
              <0,0> when 'true' ->
                  'invalid'
              <A,B> when 'true' ->
                  call 'erlang':'+'(A, B)
          end

The Core Erlang optimization passes also take advantage of the values construct to eliminate unnecessary tuple construction. For example:

bar(N) ->
    {A,B} = case N of
                0 -> {0,1};
                _ -> {-N,N}
            end,
    A * B.

After optimization, the Core Erlang code looks like this:

'bar'/1 =
    fun (_0) ->
        let <_7,_8> =
            case _0 of
              <0> when 'true' ->
                  <0,1>
              <_6> when 'true' ->
                  let <_1> =
                      call 'erlang':'-'(_0)
                  in  <_1,_0>
            end
        in
            call 'erlang':'*'(_7, _8)

Not sure whether you know about, but there is a series of blog posts at the Erlang/OTP Blog about the compiler. One of blog posts describes Core Erlang: Core Erlang by Example.

A final note, if you have serious plans creating your own BEAM-based language, we recommend using the Erlang Abstract Format because of the stronger compatibility guarantees. We consider Core Erlang to be an internal format that we will not change without good reason, but we will change it if there is a good reason. Note that we have made changes to how the compiler uses Core Erlang in the past.

8 Likes