Professional Documents
Culture Documents
Richard Carlsson
Computing Science Department
Uppsala University
Box 311, 751 05 Uppsala, Sweden
richardc@csd.uu.se
-module(list).
-export([length/1, reverse/1℄).
The se
ond reason is that the original abstra
t ma
hine It should be a stri
t, higher-order fun
tional language,
used for Erlang, the JAM [2℄ sta
k ma
hine, had an in- with a
lear and simple semanti
s.
stru
tion set whi
h was similar enough to the a
tual sour
e-
level language that no intermediate representation was ever It should be as regular as possible, to fa
ilitate the
used in the ompiler. When the new abstra t ma hine, the development of ode-walking tools.
Fun
tion variables were not stri
tly ne
essary for the lan- expr ::= var j fname j lit j fun
guage, but make it easier to see the
onne
tion to the original
j [ exprs 1 | exprs 2 ℄
program, and keep the export me
hanism simple, sin
e the
external names are the same as the internal. The exported j { exprs 1 , : : :, exprs n }
fun
tions are listed after the module name, and must be a j let vars = exprs 1 in exprs 2
subset of those dened in the top level of the module. j do exprs 1 exprs 2
Ea
h module has a possibly empty set of attributes, where
j letre
fname 1 = fun 1
the keys, whi
h must be unique, are atoms and the
or- fname n = fun n in exprs
responding values are any
onstant terms. The meaning apply exprs 0 (exprs 1 , : : :, exprs n )
Erlang
j
of module attributes is implementation-dependent;
j
all exprs n+1 :exprs n+2 (exprs 1 , : : :, exprs n )
uses them for things su
h as version information. Constant
terms are: j primop Atom (exprs 1 , : : :, exprs n )
j try exprs 1
at
h (var 1 , var 2 ) -> exprs 2
onst ::= lit j [
onst 1 |
onst 2 ℄
j
ase exprs of
lause 1
lause n end
j {
onst 1 , : : :,
onst n }
j re
eive
lause 1
lause n
lit ::= Integer j Float j Atom
after exprs 1 -> exprs 2
j Char j String j [℄
vars ::= var j < var 1 , : : :, var n >
Core Erlang, all atoms must be written within single Erlang has rather unusual s
oping rules, making
ode traver-
In
quotes, to avoid any
onfusion with keywords.
Core Erlang, s
opes are nested as in
sal di
ult, but in
ordinary lambda
al
ulus.
2 Erlang was originally made a rst-order language, be-
2.1.1 Functions, lambdas and results of expressions
ause it was thought that lambda abstra
tions would make
Lambda abstra
tions are for apparent reasons known as funs programs too
ompli
ated, and
ould generally be done
in the Erlang parlan
e. They were added to the language without.
2.2.1 Function calls
lause ::= pats when exprs 1 -> exprs 2
Core Erlang fun
tion
alls
ome in three avours: appli- pats ::= pat j < pat 1 , : : :, pat n >
ations, remote
alls, and primitive operations. The rst is
simply the appli
ation of a fun
tional value (su
h as a lo
ally
pat ::= var j lit j [ pat 1 | pat 2 ℄
dened fun
tion) to a list of arguments. j { pat 1 , : : :, pat n }
j var = pat
apply exprs 0 (exprs 1 , : : :, exprs n )
all exprs n+1 :exprs n+2 (exprs 1 , : : :, exprs n ) Patterns in
lude the form var = pat , whi
h is analogous to as
patterns in ML [9℄. Clauses are tried in order, until the rst
primop Atom (exprs 1 , : : :, exprs n )
with a mat
hing pattern is found whose guard evaluates to
true. If no
lause should mat
h, the behaviour is undened.
from Erlang, sin
e unrestri
ted use
ould violate the lan- substituted for the result. This is used for supporting the
quite unorthodox way Erlang treats ex
eptions in guard
guage semanti
s.
expressions. It is possible that in future versions of Core
Erlang, fully general try expressions will be allowed in
guards.
2.2.2 Error handling
Core Erlang does not spe
ify how ex
eptions are gen-
2.2.4 Receive expressions
erated; only how they may be
aught. An ex
eption has
two
omponents: the tag and the value. These may be any
Last, we des
ribe the rather intri
ate asyn
hronous re
eive
values, but the tag is expe
ted to signify the
lass of the ex-
expression. Its syntax is very similar to a
ase expression:
eption; in Erlang, possible tags are
urrently the atoms re
eive
lause 1
lause n
'EXIT' and 'THROW'. after exprs 1 -> exprs 2
try exprs 1
at
h (var 1 , var 2 ) -> exprs 2 but it has no expli
it sele
tor, and adds a nal
lause for
timeouts.
f(X) ->
ase X of We see that all pattern mat
hing is moved to
ase expres-
{foo, A} -> B = g(A); sions, and that some of the run-time error
he
king done
{bar, A} -> B = h(A) by Erlang is made expli
it by adding default
lauses; in
end, the reverse/1 fun
tion, this has been removed by elimi-
{A, B}. nating unrea
hable
ode. The evaluation order of Erlang
expressions is enfor
ed by introdu
ing let bindings during
translation. (In the above example this was not stri
tly ne
-
where the values of A and B in the resulting tuple depend essary.)
on the sele
ted bran
h. Maintaining input and output en-
vironments while traversing Erlang
ode is
umbersome Translating operators like + to qualied
alls to the module
and error prone. Translating the above into Core Erlang erlang is done in order to have a normalised representation
might produ
e the following
ode: of standard operators, making it possible to write program
transformations that are not implementation dependent. In-
'f'/1 = fun (X) -> stead of presenting a list of o
ial Core Erlang primops,
we use the fa
t that these fun
tions already have denitions
let <X1, X2> =
ase X of in the Erlang standard library. There should be no run-
time penalty indu
ed by this, however, be
ause the
ompiler
{foo, A} when 'true' ->
is allowed to re
ognize
alls to su
h built-in fun
tions (BIFs)
let B = apply 'g'/1(A)
and generate more e
ient
ode for these, using the assump-
in <A, B>
tion that they will not be redened. In other words, a later
{bar, A} when 'true' ->
let B = apply 'h'/1(A) transformation stage
ould rewrite su
h
alls to primop ap-
pli
ations, making the program representation dependent of
in <A, B>
the parti
ular
ompiler implementation, as a prelude to low-
end,
level
ode generation.
in {X1, X2}
erlang:
the standard library module named
Feeley and Larose [6℄ (the ETOS proje
t)
ompile Erlang
by translation to S
heme[10℄, but the generated S
heme
ode
module 'list' ['length'/1, 'reverse'/1℄ is too tightly
oupled to their implementation to be useful as
attributes [℄ a generi
intermediate format for Erlang. Furthermore, it
'length'/1 = does not seem feasible to perform e. g. program veri
ation
fun (X1) -> or pro
ess
ommuni
ation analysis using the output from
ase X1 of their translation.
[X | Xs℄ when 'true' ->
let X2 = apply 'length'/1(Xs) 5. CONCLUDING REMARKS
in
all 'erlang':'+'(1, X2) We have des
ribed the Core Erlang language, its rela-
[℄ when 'true' -> 0 tion toErlang, and the history of its development. Core
X2 when 'true' -> Erlang is today being used in the Erlang/OTP
ompiler,3
whi
h is the standard
ompiler for the Erlang language.
all 'erlang':'exit'('no_
lause')
end Although the
ompiler ba
k end had to be modied to han-
'reverse'/1 = dle some of the
onstru
ts, this was not a major problem,
fun (X1) -> apply 'reverse'/2(X1, [℄) and in several
ases
leaned up the implementation. Fur-
'reverse'/2 =
fun (X1, X2) -> 3The Erlang/OTP
ompiler, runtime system and libraries
ase <X1, X2> of are available as Open Sour
e from http://www.erlang.org.
module ::= module Atom [ fname i1 , : : :, fname ik ℄
attributes [ Atom 1 =
onst 1 , : : :, Atom m =
onst m ℄
fname 1 = fun 1 fname n = fun n end
fname ::= Atom / Integer
onst ::= lit j [
onst 1 |
onst 2 ℄ j {
onst 1 , : : :,
onst n }
lit ::= Integer j Float j Atom
j Char j String j [ ℄
fun ::= fun (var 1 , : : :, var n ) -> exprs
var ::= VariableName
exprs ::= expr j < expr 1 , : : :, expr n >
expr ::= var j fname j lit j fun
j [ exprs 1 | exprs 2 ℄ j { exprs 1 , : : :, exprs n }
j let vars = exprs 1 in exprs 2
j do exprs 1 exprs 2
j letre
fname 1 = fun 1 fname n = fun n in exprs
j apply exprs 0 (exprs 1 , : : :, exprs n )
j
all exprs n+1 :exprs n+2 (exprs 1 , : : :, exprs n )
j primop Atom (exprs 1 , : : :, exprs n )
j try exprs 1
at
h (var 1 , var 2 ) -> exprs 2
j
ase exprs of
lause 1
lause n end
j re
eive
lause 1
lause n after exprs 1 -> exprs 2
vars ::= var j < var 1 , : : :, var n >
lause ::= pats when exprs 1 -> exprs 2
pats ::= pat j < pat 1 , : : :, pat n >
pat ::= var j lit j [ pat 1 | pat 2 ℄ j { pat 1 , : : :, pat n }
j var = pat
thermore, the
ore language makes it possible to
ontinue [5℄ M. Dam and L. Fredlund. On the veri
ation of open
extending Erlang in a more systemati
way than before. distributed systems. Te
hni
al Report R97-01,
Swedish Institute of Computer S
ien
e, 1997.
Our experien
e (e. g., from the implementation of a re
ent,
[6℄ M. Feeley and M. Larose. Compiling Erlang to
advan
ed inlining algorithm, likely to be in
orporated in the
standard
ompiler) is that analysis and transformation of
S
heme. In LNCS 1490, pages 261272.
at the
ore language level, whi
h has only a few, simple and
[7℄ B. Hausman. Turbo Erlang: Approa
hing the speed of
well-dened
onstru
ts, and uses ordinary s
oping rules.
Implementations of Logi
C. In E. Ti
k, editor,
Programming Systems. Kluwer A
ademi
Publishers,
6. ACKNOWLEDGMENTS 1994.
I would like to thank Kostis Sagonas for his advi
e and
om-
ments on versions of this paper. [8℄ F. Hu
h. Veri
ation of Erlang programs using
abstra
t interpretation and model
he
king. In
[3℄ J. Barklund and R. Virding. Erlang 4.7.3 referen e Laboratory, Cambridge, Mass., De ember 1975.