erlang intro
TRANSCRIPT
Introduction to Functional Programming
Vasilij Savin
AACIMP 2011
Background: Telecom issues
● No down time allowed● Solution has to be VERY scalable (millions
operations per second)● Maintainable software● Distributed systems
History of Erlang
● Need for robust fault-tolerant language● Ericsson did not find one to suit the needs● Based originally on Prolog
– Inherits many syntax concepts
● Later rewritten with C for performance● Opensource from 2001
Erlang distinguished properties
● Concurrency● Hot code loading● Distributed● Soft real-time● Robust
What Erlang is NOT?
● Object-oriented● C syntax follower● Shared memory ideology follower● SILVER BULLET
What Erlang is NOT good for?
● Front-end web development● GUI programming● Desktop applications
Erlang in the Real World: Companies
● Klarna (e-commerce)
● Mobile Arts (telecom)
● Ericsson (telecom)
● Goldman Sachs (banking)
● Facebook (social network)
Erlang in the Real World: Products
● Ejabberd (instant messanging server)● YAWS (webserver)● Facebook chat● Firmware in Ericsson products● Varios telecom services
Paradigm comparison
Imperative (structured, procedural)
Computation in terms of statements that directly change a program state
Object-oriented
Treats datafields as "objects" manipulated only through pre-defined methods
Functional
Treats computation as the evaluation of mathematical functions avoiding state and mutable data.
The biggest challenge ahead:Unlearning what you already know
Basic Concepts
● Functions are First Class citizens● Functions are purely functional● Iteration is achieved through recursion● Execution Flow control is done with pattern
matching
Data Types
● Integers● Floats● Atoms● Lists● Tuples
● B#Val is used to store numbers in base < B >
● $Char - ascii value
● Large integers are converted to bignums
● Max size depends on physical constraints
Integers
> 16#FF.
255
> $B.
66
Floats
● Calculations are not very efficient
● Stored as double
● Follow IEEE 754 standard
-123.456
12.24E-10
Atoms
● Atoms are constant literals
● Start with a lower case letter or are encapsulated by ’ ’
● Any character code is allowed within an atom if using ’ ’
● Letters integers and _ are allowed if the atom starts with a lower case letter
magic_tag
'A quoted tag'
'_can include blanks'
Tuples
● Tuples are used to store a fixed number of items
● Tuples of any size are allowed
● Must contain valid Erlang expressions
● Tuple Arity – number of elements in tuple
{123, bcd}
{123, def, abc}
{person, 'Bass', 'Savin'}
{abc, {def, 12.3}, “jkl”}
{}
Lists
● Used to store a variable number of items
● Lists are dynamically sized
● Strings in Erlang are lists of ASCII values
● Lists are written beginning with a [ and ending with a ]
● Elements are separated by commas
[1,2,'quoted Atom',atom,"str",123.12,{tuple,1}]
> [97,98,99,4,5,6].
[97,98,99,4,5,6]
> [233].
"é"
> [65,66,68].
"ABD"
Lists II
● A recursive list definition consists of a head and a tail
● Lists whose last Tail term is [] are called: proper lists
● Appended automatically
● Improper lists are of limited use
“ABC” “DEF” == “ABCDEF”
Not recommended (inefficient)
> [1,2,3,4] – [2,3]. [1,4]
> [1,2,3] ++ [4,5,6]. [1,2,3,4,5,6]
Variables
● Variables start with an Upper Case Letter or _.
● They may not contain any special characters.
● '_' alone is a don’t care Variable. Its values are ignored and never bound.
● The value of a variable can not be changed once it hasbeen bound.
● Erlang does not have a type system.
● Types are determined at run time.
A_Variable_name
AnotherWayForVariable
_do_not_care_variable
_
Modules
● Modules are stored in files with the .erl extension
● The module and file names must be the same
● Exported functions can be called from outside the module
● Use the module prefix when making the call
– <module>:<function_name>([arg list]).
● Local functions can only be called within the module
Module anatomy
Functions
● Erlang programs consist of functions
● Functions are defined within Modules
● Function and module names must be atoms
● A function is defined as a collection of clauses
● Variables are pattern matched in the function head. If pattern matching fails on a clause, the next one is tested. One clause must always succeed
● Functions return value of the last expression executed
Function anatomy
Pattern Matching:
<Pattern> = <Expression>
Pattern Matching is used for:● Assigning values to Variables● Controlling the execution flow of the programs● Extracting values from compound data types
Pattern Matching: Assignment
● The Pattern can containunbound variables which are bound when the pattern matching succeeds
● The Expression may not contain unbound variables
A = 10.
Str = “nice string”.
List = [1,2,3].
Tuple = {abc, List, Str}
BadTuple = {List, Data}
fails
Pattern Matching: Testing
● A match must either succeed or fail
● Used to pick the execution flow in:
– case statements
– receive statements
– function heads
{A, A, B} = {10, 20, “str”}
fails
[A, B] = [1, 2, 3, 4]
fails
[A, B | C] = [1,2,3,4,5]
succeeds
A = 1, B = 2, C = [3,4,5]
Pattern Matching: Value Extraction
● Used to extract values from complex data types● Note the use of _, the don't care variable
{_, Name, {Street, City, _}} =
{person, “Vasilij”, {“Kantatvagen”, 'Stockholm', sweden}}
Case Anatomy
Case statement
● One branch must always succeed● By putting the ‘_’ or an unbound variable in the
last clause ensures that the clause will always be picked should the previous ones not match
● The _ clause is not mandatory
Guards
● Guards are additional clauses that can go in a function's head to make pattern matching more expressive.
● All variables in guards have to be bound
● If all guards have to succeed, use , to separate them
● If one guard has to succeed, use ; to separate them
● Guards have to be free of side effects
● There are restrictions on BIFS and expressions in guards
● User functions are not allowed in guards
foo(String) when is_list(String), length(String) < 10 → ...
foo(Tuple) when is_tuple(Tuple);is_atom(Tuple) → ...
Recursion examples
odd([Head|Tail]) when Head rem 1 == 0 ->
[Head|even(Tail)];
odd([_Head|Tail]) ->
even(Tail);
odd([]) ->
[].
Recursion with accumulators
average(X) -> average(X, 0, 0).
average([H|T], Length, Sum) ->
average(T, Length + 1, Sum + H);
average([], Length, Sum) ->
Sum / Length.
Runtime Errors
● badarg – BIF with wrong arguments is called● badmatch – patternmatching failed and clause list
is exhausted● function clause – no function clause matched the
pattern
Useful libraries
● io.erl – general I/O functionality
● file.erl – general filesystem functionality
● lists.erl – helpful list function
More documentation can be found here:
http://www.erlang.org/doc/