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,      Functional
procedural)
                             Treats computation as the
Computation in terms of      evaluation of mathematical
statements that directly     functions avoiding state
change a program state       and mutable data.
Object-oriented
Treats datafields as
"objects" manipulated only
through pre-defined
methods
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
Integers
●   B#Val is used to store         > 16#FF.
    numbers in base < B >
                                   255
●   $Char - ascii value            > $B.
●   Large integers are converted   66
    to bignums
●   Max size depends on physical
    constraints
Floats
●   Calculations are not very        -123.456
    efficient
                                     12.24E-10
●   Stored as double
●   Follow IEEE 754 standard
Atoms
●   Atoms are constant literals       magic_tag
●   Start with a lower case letter    'A quoted tag'
    or are encapsulated by ’ ’        '_can include blanks'
●   Any character code is allowed
    within an atom if using ’ ’
●   Letters integers and _ are
    allowed if the atom starts with
    a lower case letter
Tuples
●   Tuples are used to store a   {123, bcd}
    fixed number of items
                                 {123, def, abc}
●   Tuples of any size are allowed {person, 'Bass', 'Savin'}
●   Must contain valid Erlang      {abc, {def, 12.3}, “jkl”}
    expressions
                                 {}
●   Tuple Arity – number of
    elements in tuple
Lists
●   Used to store a variable           [1,2,'quoted
    number of items                    Atom',atom,"str",123.12,
                                       {tuple,1}]
●   Lists are dynamically sized
                                       > [97,98,99,4,5,6].
●   Strings in Erlang are lists of
    ASCII values                       [97,98,99,4,5,6]

●   Lists are written beginning        > [233].
    with a [ and ending with a ]       "é"
●   Elements are separated by          > [65,66,68].
    commas
                                       "ABD"
Lists II
●   A recursive list definition        “ABC” “DEF” == “ABCDEF”
    consists of a head and a tail
                                       Not recommended
●   Lists whose last Tail term is []   (inefficient)
    are called: proper lists           > [1,2,3,4] – [2,3].
●   Appended automatically             [1,4]

●   Improper lists are of limited      > [1,2,3] ++ [4,5,6].
    use                                [1,2,3,4,5,6]
Variables
●   Variables start with an Upper   A_Variable_name
    Case Letter or _.
                                    AnotherWayForVariable
●   They may not contain any        _do_not_care_variable
    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.
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    A = 10.
    pattern matching succeeds   Str = “nice string”.
●   The Expression may not      List = [1,2,3].
    contain unbound variables
                                Tuple = {abc, List, Str}
                                BadTuple = {List, Data}
                                                          fails
Pattern Matching: Testing
●   A match must either succeed   {A, A, B} = {10, 20,
    or fail                       “str”}
●   Used to pick the execution                           fails
    flow in:                      [A, B] = [1, 2, 3, 4]
         –   case statements                             fails
         –   receive statements   [A, B | C] = [1,2,3,4,5]
         –   function heads                       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/

Erlang intro

  • 1.
    Introduction to FunctionalProgramming Vasilij Savin AACIMP 2011
  • 3.
    Background: Telecom issues ● No down time allowed ● Solution has to be VERY scalable (millions operations per second) ● Maintainable software ● Distributed systems
  • 4.
    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
  • 5.
    Erlang distinguished properties ● Concurrency ● Hot code loading ● Distributed ● Soft real-time ● Robust
  • 6.
    What Erlang isNOT? ● Object-oriented ● C syntax follower ● Shared memory ideology follower ● SILVER BULLET
  • 7.
    What Erlang isNOT good for? ● Front-end web development ● GUI programming ● Desktop applications
  • 8.
    Erlang in theReal World: Companies ● Klarna (e-commerce) ● Mobile Arts (telecom) ● Ericsson (telecom) ● Goldman Sachs (banking) ● Facebook (social network)
  • 9.
    Erlang in theReal World: Products ● Ejabberd (instant messanging server) ● YAWS (webserver) ● Facebook chat ● Firmware in Ericsson products ● Varios telecom services
  • 10.
    Paradigm comparison Imperative (structured, Functional procedural) Treats computation as the Computation in terms of evaluation of mathematical statements that directly functions avoiding state change a program state and mutable data. Object-oriented Treats datafields as "objects" manipulated only through pre-defined methods
  • 11.
    The biggest challengeahead: Unlearning what you already know
  • 12.
    Basic Concepts ● Functions are First Class citizens ● Functions are purely functional ● Iteration is achieved through recursion ● Execution Flow control is done with pattern matching
  • 13.
    Data Types ● Integers ● Floats ● Atoms ● Lists ● Tuples
  • 14.
    Integers ● B#Val is used to store > 16#FF. numbers in base < B > 255 ● $Char - ascii value > $B. ● Large integers are converted 66 to bignums ● Max size depends on physical constraints
  • 15.
    Floats ● Calculations are not very -123.456 efficient 12.24E-10 ● Stored as double ● Follow IEEE 754 standard
  • 16.
    Atoms ● Atoms are constant literals magic_tag ● Start with a lower case letter 'A quoted tag' or are encapsulated by ’ ’ '_can include blanks' ● Any character code is allowed within an atom if using ’ ’ ● Letters integers and _ are allowed if the atom starts with a lower case letter
  • 17.
    Tuples ● Tuples are used to store a {123, bcd} fixed number of items {123, def, abc} ● Tuples of any size are allowed {person, 'Bass', 'Savin'} ● Must contain valid Erlang {abc, {def, 12.3}, “jkl”} expressions {} ● Tuple Arity – number of elements in tuple
  • 18.
    Lists ● Used to store a variable [1,2,'quoted number of items Atom',atom,"str",123.12, {tuple,1}] ● Lists are dynamically sized > [97,98,99,4,5,6]. ● Strings in Erlang are lists of ASCII values [97,98,99,4,5,6] ● Lists are written beginning > [233]. with a [ and ending with a ] "é" ● Elements are separated by > [65,66,68]. commas "ABD"
  • 19.
    Lists II ● A recursive list definition “ABC” “DEF” == “ABCDEF” consists of a head and a tail Not recommended ● Lists whose last Tail term is [] (inefficient) are called: proper lists > [1,2,3,4] – [2,3]. ● Appended automatically [1,4] ● Improper lists are of limited > [1,2,3] ++ [4,5,6]. use [1,2,3,4,5,6]
  • 20.
    Variables ● Variables start with an Upper A_Variable_name Case Letter or _. AnotherWayForVariable ● They may not contain any _do_not_care_variable 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.
  • 21.
    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
  • 22.
  • 23.
    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
  • 24.
  • 25.
    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
  • 26.
    Pattern Matching: Assignment ● The Pattern can containunbound variables which are bound when the A = 10. pattern matching succeeds Str = “nice string”. ● The Expression may not List = [1,2,3]. contain unbound variables Tuple = {abc, List, Str} BadTuple = {List, Data} fails
  • 27.
    Pattern Matching: Testing ● A match must either succeed {A, A, B} = {10, 20, or fail “str”} ● Used to pick the execution fails flow in: [A, B] = [1, 2, 3, 4] – case statements fails – receive statements [A, B | C] = [1,2,3,4,5] – function heads succeeds A = 1, B = 2, C = [3,4,5]
  • 28.
    Pattern Matching: ValueExtraction ● 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}}
  • 30.
  • 31.
    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
  • 32.
    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) → ...
  • 33.
    Recursion examples odd([Head|Tail]) whenHead rem 1 == 0 -> [Head|even(Tail)]; odd([_Head|Tail]) -> even(Tail); odd([]) -> [].
  • 34.
    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.
  • 35.
    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
  • 36.
    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/