Sequential Programming in  Erlang

                (from   www.erlang.org  2000.Jan.17)

                (extended by J F H Winkler  2000.Jan)



 

 

 

 

 

 

 

Numbers

Integers                  at least 24-bit integer precision
        10
        -234
        16#AB10F             Base 16;   base in the range  2..16
        2#110111010
        $A


Floats

         17.368
         -56.654 
         12.34E-10.
Back to top

Atoms        are named constants

        abcef
        start_with_a_lower_case_letter
        'Blanks can be quoted'
        'Anything inside quotes \n\012'
    Hint:  atoms are not  strings, especially no operations

Back to top


Tuples            {  }

        {123, bcd}
        {123, def, abc}
        {person, 'Joe', 'Armstrong'}
        {abc, {def, 123}, jkl}
        {}
Back to top

Lists           [  ]

        [123, xyz]
        [123, def, abc]
        [{person, 'Joe', 'Armstrong'},
                {person, 'Robert', 'Virding'},
                {person, 'Mike', 'Williams'}
        ]
        "abcdefghi"
                becomes - [97,98,99,100,101,102,103,104,105]
        ""
                becomes - []
Back to top

Records

   ~record(RecordName, {Field1 [= DefaultValue1],      Definition of a record TYPE
                        Field2 [= DefaultValue1],
                          . . . ,
                        FieldN [= DefaultValueN] } ).
Example    ~record(person, {name, phone, address} ).
A new record is created with the following syntax
        #RecordName{Field1 = Expr1,
                    Field2 = Expr2,
                    . . . ,
                    FieldN = ExprN}.
Example    #person{phone = [0,8,2,3,4,3,1,2], name = "Robert"}.
                            component address  is undefined
    P1 = #person{name = "Joe", phone = [1,2,3], address = "A street"}
Accessing a component
        P1#person.name
Creation of a record as a modified copy of an existing one:
     P2 = P1#person{name = "Robert"}     create NEW record and modify it
         P2 is now bound to
           #person{name = "Robert", phone = [1,2,3], address = "A street"}
Since variables have only dynamic types it is sometimes necessary to first check
whether a variable is bound to a record of a certain record type:
        record(Variable, RecordType)
Example:      when  record(P2, person) ->  ... P#person.phone
Back to top

 Variables

        Abc
        A_long_variable_name
        AnObjectOrientatedVariableName
Back to top

Complex Data Structures

        [{{person,'Joe', 'Armstrong'},
                {telephoneNumber, [3,5,9,7]},
                {shoeSize, 42},
                {pets, [{cat, tubby},{cat, tiger}]},
                {children,[{thomas, 5},{claire,1}]}},
         {{person,'Mike','Williams'},
                {shoeSize,41},
                {likes,[boats, beer]},
                ...
Back to top

 

 Pattern Matching         Pattern = Expression

    1) evaluate  Expression
   2) match result against Pattern

   The match succeds or fails.
   If the match succeeds any variables occurring in pattern become bound.
   Once a variable has been bound it can never be changed.

    Pattern matching occurs:


   Examples:

         A = 10
                Succeeds - binds A to 10

        {B, C, D} = {10, foo, bar}
                Succeeds - binds B to 10, C to foo and D 
                to bar

        {A, A, B} = {abc, abc, foo}
                Succeeds - binds A to abc, B to foo
        
        {A, A, B} = {abc, def, 123}
                Fails
        
        [A,B,C] = [1,2,3] 
                Succeeds - binds A to 1, B to 2, C to 3
        
        [A,B,C,D] = [1,2,3]
                Fails
        [A,B|C] = [1,2,3,4,5,6,7]
                Succeeds - binds A = 1, B = 2,
                C = [3,4,5,6,7]
        
        [H|T] = [1,2,3,4]
                Succeeds - binds H = 1, T = [2,3,4]
        
        [H|T] = [abc]
                Succeeds - binds H = abc, T = []
        
        [H|T] = []
                Fails
        
        {A,_, [B|_],{B}} = {abc,23,[22,x],{22}}
                Succeeds - binds A = abc, B = 22
        #person{name = Name} = #person{name="Joe", phone=[0,0,7], address="A str"}
                Succeeds - binds  Name = "Joe"
Back to top

Function Calls

        module:func(Arg1, Arg2, ... Argn)            :  means qualification 
        
        func(Arg1, Arg2, .. Argn)
Back to top

Module System

        -module(demo).
        -export([double/1]).
        
        double(X) ->
                times(X, 2).
        
        times(X, N) ->
                X * N.
Back to top

Starting the system

        unix> erl
        Eshell V2.0
        1> c(demo).
        double/1 times/2 module_info/0
        compilation_succeeded
        2> demo:double(25).
        50
        3> demo:times(4,3).
        ** undefined function:demo:times[4,3] **
        ** exited: {undef,{demo,times,[4,3]}} **
        4> 10 + 25.
        35
        5>
Back to top

Built In Functions (BIFs)

        date()
        time()
        length([1,2,3,4,5])
        size({a,b,c})
        atom_to_list(an_atom)
        list_to_tuple([1,2,3,4])
        integer_to_list(2234)
        tuple_to_list({})
Back to top
Function Syntax

Is defined as a collection of clauses.

        func(Pattern1, Pattern2, ...) ->
                ... ;
        func(Pattern1, Pattern2, ...) ->
                ... ;
                ...
        func(Pattern1, Pattern2, ...) ->
                ... .
Evaluation Rules Example
        -module(mathStuff).
        -export([factorial/1, area/1]).
        
        factorial(0) -> 1;
        factorial(N) -> N * factorial(N-1).
        
        area({square, Side}) ->
                Side * Side;
        area({circle, Radius}) ->
                % almost :-)
                3 * Radius * Radius;
        area({triangle, A, B, C}) ->
                S = (A + B + C)/2,
                math:sqrt(S*(S-A)*(S-B)*(S-C));
        area(Other) ->
                {invalid_object, Other}.
Evaluation example
        factorial(0) -> 1;
        factorial(N) -> N * factorial(N-1)
        > factorial(3)
                matches N = 3 in clause 2
                == 3 * factorial(3 - 1)
                == 3 * factorial(2)
                matches N =2 in clause 2 
                == 3 * 2 * factorial(2 - 1)
                == 3 * 2 * factorial(1)
                matches N = 1 in clause 2
                == 3 * 2 * 1 * factorial(1 - 1)
                == 3 * 2 * 1  * factorial(0)
                == 3 * 2 * 1  * 1 (clause 1)
                == 6
Back to top
Guarded Function Clauses
        factorial(0) -> 1;
        factorial(N) when N > 0 ->
                N * factorial(N - 1).
        factorial(N) when N > 0 ->
                N * factorial(N - 1);
        factorial(0) -> 1.
        factorial(N) ->
                N * factorial(N - 1);
        factorial(0) -> 1.
Back to top
Examples of Guards
        number(X)       - X is a number
        integer(X)      - X is an integer
        float(X)        - X is a float
        atom(X)         - X is an atom
        tuple(X)        - X is a tuple
        list(X)         - X is a list
        
        length(X) == 3  - X is a list of length 3
        size(X) == 2    - X is a tuple of size 2.
        
        X > Y + Z       - X is > Y + Z
        X == Y          - X is equal to Y
        X =:= Y         - X is exactly equal to Y
                          (i.e. 1 == 1.0 succeeds but 
                           1 =:= 1.0 fails)
Back to top

 
 
 
 
 

Traversing Lists

        average(X) -> sum(X) / len(X).
        
        sum([H|T]) -> H + sum(T);
        sum([]) -> 0.
        
        len([_|T]) -> 1 + len(T);
        len([]) -> 0.
Two other common patterns:
        double([H|T]) -> [2*H|double(T)];
        double([]) -> [].
        
        member(H, [H|_]) -> true;
        member(H, [_|T]) -> member(H, T);
        member(_, []) -> false.
Back to top
Lists and Accumulators
        average(X) -> average(X, 0, 0).
        
        average([H|T], Length, Sum) ->
                average(T, Length + 1, Sum + H);
        average([], Length, Sum) ->
                Sum / Length.
Back to top
Shell Commands
        h() - history . Print the last 20 commands.
        
        b() - bindings. See all variable bindings.
        
        f() - forget. Forget all variable bindings.
        
        f(Var) - forget. Forget the binding of variable 
        X. This can ONLY be used as a command to 
        the shell - NOT in the body of a function!
        
        e(n) - evaluate. Evaluate the n:th command 
        in history.
        
        e(-1) - Evaluate the previous command.
Back to top

Special Functions

        apply(Mod, Func, Args)
        1> apply( lists1,min_max,[[4,1,7,3,9,10]]).
        {1, 10}
Back to top

Special Forms

        case Expr of
            Pattern1 [when Guard1]  -> Seq1;
            Pattern2 [when Guard2]  -> Seq2;
            . . .
            PatternN [when GuardN]  -> SeqN
        end
        case lists:member(a, X) of
                true ->
                        ... ;
                false -> 
                        ...
        end,
        factorial(N)  ->
            case N of
                0 -> 1;
                N when integer(N), N>0, N<13 -> 
                    N*factorial(N-1)
        end.
---------------------------------------------------------
        if
            Guard1 -> Sequence1;
            Guard2 -> Sequence2;
            . . .
            GuardN -> SequenceN
        end
        
        if
             integer(X) -> ... ;
             tuple(X) -> ... 
        end,
        factorial(N) ->
            if
                0 -> 1;
                integer(N), N>0, N<13 ->
                    N*factorial(N-1)
            end.
Back to top