Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Programming in PHP

Functional Programming in PHP

Functional programming in the PHP programming language.

See the associated blog post for more information: http://simonholywell.com/post/2014/02/functional-php-talks.html

Simon Holywell

February 12, 2014
Tweet

More Decks by Simon Holywell

Other Decks in Programming

Transcript

  1. FUNCTIONAL PHP
    SIMON HOLYWELL
    12/02/2014
    0

    View Slide

  2. WHO?
    Lead developer
    Mosaic in Brighton
    Full service agency
    @ on Twitter
    Treffynnon
    SimonHolywell.com

    View Slide

  3. WORK
    Web apps
    Obligatory CMS!

    View Slide

  4. PROJECTS
    Maintainer of
    ssdeep - and extension
    - geo library for PHP
    - Node.js bot for GTalk - now defunct :(
    Idiorm and Paris
    PECL HHVM
    Navigator
    PHP-at-Job-Queue-Wrapper
    njsbot

    View Slide

  5. FUNCTIONS IN PHP
    Rarely employed
    Discouraged by PHP's evolution
    Naming collisions
    The old name spacing object

    View Slide

  6. SIMPLE BEASTS
    PHP functions are:
    Easy
    Contained
    Unaware of global state
    Can now be namespaced

    View Slide

  7. FUNCTION
    <
    ?
    p
    h
    p
    f
    u
    n
    c
    t
    i
    o
    n h
    e
    l
    l
    o
    (
    $
    a
    r
    g = '
    W
    o
    r
    l
    d
    '
    ) {
    e
    c
    h
    o _
    _
    F
    U
    N
    C
    T
    I
    O
    N
    _
    _ . " $
    a
    r
    g
    "
    ;
    }
    h
    e
    l
    l
    o
    (
    )
    ; /
    / h
    e
    l
    l
    o W
    o
    r
    l
    d

    View Slide

  8. A LITTLE BIT OF HISTORY
    I started with PHP3
    Functions were the norm
    Classes merely wrapped them
    OOP was very poorly understood

    View Slide

  9. DRY
    Most mashed code with HTML
    Functions promoted code reuse
    HTML then had functions in it!

    View Slide

  10. EVOLVE
    Come PHP4 you get better OOP
    Functions no longer in focus
    They become seen poorer cousins
    Can't carry context vs. class properties

    View Slide

  11. PHP5
    Functions are still marginalised
    Still seen as spaghetti
    The bad way

    View Slide

  12. PHP5.3+
    Proper anonymous functions
    We get closures!

    View Slide

  13. THE BASICS ARE IN
    PLACE
    ¡Functional is possible!

    View Slide

  14. JUST WHAT IS
    FUNCTIONAL?
    Programming without assignment
    Stateless
    Pure

    View Slide

  15. WITHOUT ASSIGNMENT...
    Say goodbye to
    $
    v
    a
    r = '
    v
    a
    l
    u
    e
    '
    ;
    $
    C
    l
    a
    s
    s
    I
    n
    s
    t
    a
    n
    c
    e
    -
    >
    p
    r
    o
    p
    e
    r
    t
    y = '
    v
    a
    l
    u
    e
    '
    ;

    View Slide

  16. STATELESS AND PURE
    No:
    Globals
    Side effects
    Incrementors/accumulators
    For, while or foreach loops

    View Slide

  17. PASSING VALUES
    From function to function as
    Arguments
    Return values

    View Slide

  18. 10
    How would you sum all the integers from one to ten?

    View Slide

  19. IMPERATIVE WAY
    <
    ?
    p
    h
    p
    $
    s
    u
    m = 0
    ;
    f
    o
    r
    (
    $
    i = 1
    ; $
    i <
    = 1
    0
    ; $
    i
    +
    +
    ) {
    $
    s
    u
    m +
    = $
    i
    ;
    }
    /
    / $
    s
    u
    m = 5
    5

    View Slide

  20. FUNCTIONAL WAY
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    s
    u
    m
    (
    r
    a
    n
    g
    e
    (
    1
    , 1
    0
    )
    )
    ;
    More descriptive
    Removes state ($
    s
    u
    m
    )
    Reusable components

    View Slide

  21. LIKE WELL-DESIGNED
    OOP
    Encapsulated
    Broken down into small chunks
    Reusable

    View Slide

  22. CAN IT BE NEATER?
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    s
    u
    m
    (
    r
    a
    n
    g
    e
    (
    1
    , 1
    0
    )
    )
    ;
    Lua - s
    =
    0
    ; f
    o
    r i
    =
    1
    ,
    1
    0 d
    o s
    =
    s
    +
    i e
    n
    d
    Erlang - l
    i
    s
    t
    s
    :
    s
    u
    m
    (
    l
    i
    s
    t
    s
    :
    s
    e
    q
    (
    1
    , 1
    0
    )
    )
    .
    Clojure - (
    r
    e
    d
    u
    c
    e + (
    r
    a
    n
    g
    e (
    i
    n
    c 1
    0
    )
    )
    )
    Ruby - (
    1
    .
    .
    1
    0
    )
    .
    i
    n
    j
    e
    c
    t
    (
    0
    ) {
    |
    s
    ,
    i
    | s + i
    }
    Python - s
    u
    m
    (
    r
    a
    n
    g
    e
    (
    1
    , 1
    0 + 1
    )
    )
    F# - L
    i
    s
    t
    .
    s
    u
    m [
    1 .
    . 1
    0
    ]
    Scala - (
    1 t
    o 1
    0
    )
    .
    s
    u
    m
    Haskell - s
    u
    m
    [
    1
    .
    .
    1
    0
    ]

    View Slide

  23. THE SCALE
    Pure - Haskell
    Middle ground - Scala and Clojure
    Dabbling - PHP and Python
    Hopeless - Brainfuck
    %

    View Slide

  24. HISTORY
    Vienna Circle - 1920s
    Philosophers
    Logic
    Can be defined apart from content
    Unless experienced or observed = worthless
    M! = ethics, metaphysics, religion and aesthetics

    View Slide

  25. KURT GÖDEL
    Attended Vienna Circle
    Ultimately disproved manifesto
    Incompleteness theorem - 1931
    Some truths cannot be proven

    View Slide

  26. FUNCTIONAL HISTORY
    Kurt Gödel - recursively calculated functions - 1930s
    Haskell Curry - combinatory logic - 1927
    Alan Turing - machines calculating from inputs - 1936
    Alonzo Church - lambda calculus - 1930s

    View Slide

  27. LAMBDA CALCULUS
    Mathematical functions - abstraction
    Accept functions as parameters
    Return other functions
    Basis of functional programming

    View Slide

  28. COMBINATORY LOGIC
    Haskell Curry
    Combinatory calculus - 1927
    Primitive functions combined to build others
    Named after him
    Currying
    Haskell

    View Slide

  29. WORLD WAR II
    Vienna/Göttingen unsafe
    Great minds move to US or UK
    Turing involved in code breaking

    View Slide

  30. ACADEMIC
    Little activity 'til late 1950s

    View Slide

  31. LISP
    1958
    Jon McCarthy
    MIT
    Became the standard for AI

    View Slide

  32. MOMENTUM
    Some advances
    Still mostly academic
    Imperative programming the norm

    View Slide

  33. TELEPHONES
    Fault tolerant system
    Erlang by Ericsson
    1980s

    View Slide

  34. ERICSSON
    Ericsson
    Erlang
    Highly symbolic to improve productivity
    Lisp and Prolog discounted
    Focused on
    Reliability
    Concurrency

    View Slide

  35. HASKELL
    Formed by committee
    Pure functional language

    View Slide

  36. COMMERCIAL ADOPTION
    Domain specific languages (DSL)
    Type handling
    Pattern matching
    Fast to build complex parsers
    Less code = easier to maintain

    View Slide

  37. CASESTUDY
    Barclays bank
    Functional Payout Framework
    Written in Haskell
    DSL for mathematicians
    Builds trading applications
    Functional eased scope creap
    ^

    View Slide

  38. NONE SHALL PASS!
    <
    ?
    p
    h
    p
    $
    a
    l
    l
    o
    w
    a
    b
    l
    e
    _
    i
    p
    s = a
    r
    r
    a
    y
    (
    '
    1
    9
    2
    .
    1
    6
    8
    .
    0
    .
    '
    ,
    '
    8
    .
    8
    .
    8
    .
    8
    '
    ,
    )
    ;
    a
    r
    r
    a
    y
    _
    f
    i
    l
    t
    e
    r
    (
    $
    a
    l
    l
    o
    w
    a
    b
    l
    e
    _
    i
    p
    s
    , f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    i
    p
    ) {
    r
    e
    t
    u
    r
    n $
    i
    p =
    =
    s
    u
    b
    s
    t
    r
    (
    $
    _
    S
    E
    R
    V
    E
    R
    [
    '
    R
    E
    M
    O
    T
    E
    _
    A
    D
    D
    R
    '
    ]
    , 0
    , s
    t
    r
    l
    e
    n
    (
    $
    i
    p
    )
    )
    ;
    }
    ) ?
    : d
    i
    e
    (
    '
    D
    e
    n
    i
    e
    d
    .
    '
    )
    ;

    View Slide

  39. ARRAY_FILTER()
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    f
    i
    l
    t
    e
    r
    (
    $
    a
    l
    l
    o
    w
    a
    b
    l
    e
    _
    i
    p
    s
    , f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    i
    p
    ) {
    Takes a list and predicate
    "Removes" items when predicate fails
    λ or anonymous function
    And hey, it's not a loop!

    View Slide

  40. THA PREDICATE
    <
    ?
    p
    h
    p
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    i
    p
    ) {
    r
    e
    t
    u
    r
    n $
    i
    p =
    =
    s
    u
    b
    s
    t
    r
    (
    $
    _
    S
    E
    R
    V
    E
    R
    [
    '
    R
    E
    M
    O
    T
    E
    _
    A
    D
    D
    R
    '
    ]
    , 0
    , s
    t
    r
    l
    e
    n
    (
    $
    i
    p
    )
    )
    ;
    }
    IP v.4 addresses
    Chops user IP to same length as allowable ($
    i
    p
    )
    Compares result for equality

    View Slide

  41. KILLER CONDITION
    <
    ?
    p
    h
    p
    ?
    : d
    i
    e
    (
    '
    D
    e
    n
    i
    e
    d
    .
    '
    )
    ;
    Empty arrays == false
    Terminates application
    Ternary shortcut
    <
    ?
    p
    h
    p
    e
    x
    p
    r
    1 ? e
    x
    p
    r
    2 : e
    x
    p
    r
    3
    ;
    e
    x
    p
    r
    1 ?
    : e
    x
    p
    r
    3
    ;

    View Slide

  42. WHAT SAY THE BLACK
    KNIGHT?
    <
    ?
    p
    h
    p
    /
    / $
    _
    S
    E
    R
    V
    E
    R
    [
    '
    R
    E
    M
    O
    T
    E
    _
    A
    D
    D
    R
    '
    ] = '
    1
    9
    2
    .
    1
    6
    8
    .
    '
    $
    a
    l
    l
    o
    w
    a
    b
    l
    e
    _
    i
    p
    s = a
    r
    r
    a
    y
    (
    '
    1
    9
    2
    .
    1
    6
    8
    .
    0
    .
    '
    ,
    '
    8
    .
    8
    .
    8
    .
    8
    '
    ,
    )
    ;
    a
    r
    r
    a
    y
    _
    f
    i
    l
    t
    e
    r
    (
    $
    a
    l
    l
    o
    w
    a
    b
    l
    e
    _
    i
    p
    s
    , f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    i
    p
    ) {
    r
    e
    t
    u
    r
    n $
    i
    p =
    =
    s
    u
    b
    s
    t
    r
    (
    $
    _
    S
    E
    R
    V
    E
    R
    [
    '
    R
    E
    M
    O
    T
    E
    _
    A
    D
    D
    R
    '
    ]
    , 0
    , s
    t
    r
    l
    e
    n
    (
    $
    i
    p
    )
    )
    ;
    }
    ) ?
    : d
    i
    e
    (
    '
    D
    e
    n
    i
    e
    d
    .
    '
    )
    ;

    View Slide

  43. BONUS: ARRAY CLEANER
    a
    r
    r
    a
    y
    _
    f
    i
    l
    t
    e
    r
    (
    ) without a predicate
    Entries == false dropped
    false == "" == 0 == array() == null == '0' == 0.0
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    f
    i
    l
    t
    e
    r
    (
    a
    r
    r
    a
    y
    (
    '
    '
    , '
    s
    '
    , 0
    )
    )
    ;
    /
    / a
    r
    r
    a
    y
    (
    '
    s
    '
    )

    View Slide

  44. BENEFITS OF
    FUNCTIONAL
    Techniques useful for OOP
    Abstraction = more readable
    No distracting guff
    Just the problem solving stuff

    View Slide

  45. ...AND MORE
    Shorter code = quicker to debug
    No global state to assemble in mind
    Focus on the hard problems

    View Slide

  46. HEY! WAIT THERE'S
    STILL MORE
    Testing is easier
    No globals again
    Values are final

    View Slide

  47. REFERENTIAL
    TRANSPARENCY
    Replace any function with it's return value
    Algorithm still works!
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    s
    u
    m
    (
    a
    r
    r
    a
    y
    (
    1
    ,
    2
    ,
    3
    ,
    4
    ,
    5
    ,
    6
    ,
    7
    ,
    8
    ,
    9
    ,
    1
    0
    )
    )
    ;
    /
    / I
    s s
    t
    i
    l
    l 5
    5
    !
    Can you do that to a for loop?

    View Slide

  48. NO!
    <
    ?
    p
    h
    p
    $
    s
    u
    m = 0
    ;
    f
    o
    r
    (
    $
    i = 1
    ; $
    i <
    = 1
    0
    ; $
    i
    +
    +
    ) {
    $
    s
    u
    m +
    = $
    i
    ;
    }
    /
    / $
    s
    u
    m = 5
    5
    Closest:
    <
    ?
    p
    h
    p
    $
    s
    u
    m = 0
    ;
    $
    s
    u
    m +
    = 1
    ;
    $
    s
    u
    m +
    = 2
    ;
    .
    .
    .
    $
    s
    u
    m +
    = 1
    0
    ;
    /
    / $
    s
    u
    m = 5
    5

    View Slide

  49. SO WHAT ELSE?
    Easier parallel processing
    Who's using the other cores in your CPU?
    Not common in PHP - see pthreads

    View Slide

  50. IF PHP WERE REALLY
    FUNCTIONAL
    Machine optimisation of code
    Lazy-evaluation
    Hot code deployment (Erlang!)
    %

    View Slide

  51. STEP BACK - Λ
    λ
    lambda function
    anonymous function
    <
    ?
    p
    h
    p
    $
    f
    u
    n
    c
    _
    n
    a
    m
    e = f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    p
    a
    r
    a
    m
    ) {
    r
    e
    t
    u
    r
    n $
    p
    a
    r
    a
    m
    ;
    }
    ;

    View Slide

  52. SHOULD BE FAMILIAR
    <
    ?
    p
    h
    p
    s
    p
    l
    _
    a
    u
    t
    o
    l
    o
    a
    d
    _
    r
    e
    g
    i
    s
    t
    e
    r
    (
    f
    u
    n
    c
    t
    i
    o
    n (
    $
    c
    l
    a
    s
    s
    ) {
    i
    n
    c
    l
    u
    d
    e '
    c
    l
    a
    s
    s
    e
    s
    /
    ' . $
    c
    l
    a
    s
    s . '
    .
    c
    l
    a
    s
    s
    .
    p
    h
    p
    '
    ;
    }
    )
    ;
    If not - how about in JS:
    b
    u
    t
    t
    o
    n
    .
    o
    n
    c
    l
    i
    c
    k = f
    u
    n
    c
    t
    i
    o
    n
    (
    ) {
    a
    l
    e
    r
    t
    (
    '
    L
    a
    m
    b
    d
    a
    '
    )
    ;
    }
    ;

    View Slide

  53. EXTEND IT - CLOSURE
    Just like a lambda
    But, with context/data ($
    v
    a
    l
    u
    e
    )
    <
    ?
    p
    h
    p
    $
    v
    a
    l
    u
    e = 5
    ;
    $
    f
    u
    n
    c
    _
    n
    a
    m
    e = f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    p
    a
    r
    a
    m
    ) u
    s
    e (
    $
    v
    a
    l
    u
    e
    ) {
    r
    e
    t
    u
    r
    n $
    p
    a
    r
    a
    m + $
    v
    a
    l
    u
    e
    ;
    }
    ;
    e
    c
    h
    o $
    f
    u
    n
    c
    _
    n
    a
    m
    e
    (
    3
    )
    ; /
    / 8
    Vars can be other closures or lambdas too
    No aliasing unfortunately

    View Slide

  54. MAP
    a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    )
    Applies function to each element
    Returns new array with adjusted elements
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    v
    ) { r
    e
    t
    u
    r
    n s
    t
    r
    t
    o
    u
    p
    p
    e
    r
    (
    +
    +
    $
    v
    )
    ; }
    ,
    $
    a
    r
    r
    a
    y
    )
    ;
    a
    r
    r
    a
    y
    (
    '
    o
    '
    , '
    g
    '
    , '
    o
    '
    ) becomes a
    r
    r
    a
    y
    (
    '
    P
    '
    , '
    H
    '
    , '
    P
    '
    )

    View Slide

  55. SOCHI MAP IT
    1st

    View Slide

  56. APPLIED BY A MAP
    2nd

    View Slide

  57. MORE MAPPING!
    3rd

    View Slide

  58. REDUCE
    a
    r
    r
    a
    y
    _
    r
    e
    d
    u
    c
    e
    (
    )
    Fold array down to one value
    Applies function to each element
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    r
    e
    d
    u
    c
    e
    (
    $
    a
    r
    r
    a
    y
    ,
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    r
    e
    s
    u
    l
    t
    , $
    v
    ) { r
    e
    t
    u
    r
    n $
    r
    e
    s
    u
    l
    t .
    = $
    v
    ; }
    )
    ;
    a
    r
    r
    a
    y
    (
    '
    o
    '
    , '
    g
    '
    , '
    o
    '
    ) becomes o
    g
    o

    View Slide

  59. REDUCE FIGURES
    9 + 6.10 + 7.62 + 6.98 ...

    View Slide

  60. FOLDING SCORES
    15.10 + 7.62 + 6.98 ...

    View Slide

  61. DISAPPOINTMENT
    63.10

    View Slide

  62. MAP AND REDUCE
    Combined to great effect
    <
    ?
    p
    h
    p
    $
    a = a
    r
    r
    a
    y
    (
    '
    o
    '
    , '
    g
    '
    , '
    o
    '
    )
    ;
    a
    r
    r
    a
    y
    _
    r
    e
    d
    u
    c
    e
    (
    a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    v
    ) { r
    e
    t
    u
    r
    n s
    t
    r
    t
    o
    u
    p
    p
    e
    r
    (
    +
    +
    $
    v
    )
    ; }
    , $
    a
    )
    ,
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    r
    e
    s
    u
    l
    t
    , $
    v
    ) { r
    e
    t
    u
    r
    n $
    r
    e
    s
    u
    l
    t .
    = $
    v
    ; }
    )
    ;
    /
    / P
    H
    P

    View Slide

  63. RECURSION
    Just like the meaning of PHP
    A function that calls itself
    Directly or
    Indirectly
    Can be used for loops
    Loose or forgotten condition = blown stack

    View Slide

  64. HEADS OR TAILS
    PHP = heads
    <
    ?
    p
    h
    p
    f
    u
    n
    c
    t
    i
    o
    n h
    e
    a
    d
    _
    s
    u
    m
    (
    $
    x
    ) {
    r
    e
    t
    u
    r
    n (
    $
    x =
    = 1
    )
    ? $
    x
    : $
    x + h
    e
    a
    d
    _
    s
    u
    m
    (
    $
    x - 1
    )
    ;
    }
    h
    e
    a
    d
    _
    s
    u
    m
    (
    1
    0
    )
    ; /
    / 5
    5
    Other languages have optimised tails

    View Slide

  65. HIGHER ORDER
    FUNCTIONS
    Functions that have other functions as
    Call parameters
    Return values
    Can be used to form expressions

    View Slide

  66. HIGHER EXAMPLE
    <
    ?
    p
    h
    p
    $
    d
    a
    t
    a = a
    r
    r
    a
    y
    (
    1
    , 2
    , 3
    , 4
    , 5
    , 6
    , 7
    , 8
    , 9
    , 1
    0
    )
    ;
    f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    _
    a
    l
    g
    o
    r
    i
    t
    h
    m
    (
    $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c
    ) {
    r
    e
    t
    u
    r
    n (
    o
    d
    d
    _
    e
    v
    e
    n
    (
    $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c
    (
    )
    )
    ) ?
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    v
    a
    l
    u
    e
    ) {
    r
    e
    t
    u
    r
    n $
    v
    a
    l
    u
    e * $
    v
    a
    l
    u
    e
    ;
    } :
    f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    v
    a
    l
    u
    e
    ) u
    s
    e (
    $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c
    ) {
    r
    e
    t
    u
    r
    n (
    $
    v
    a
    l
    u
    e * $
    v
    a
    l
    u
    e / $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c
    (
    )
    ) + 1
    0
    ;
    }
    ;
    }
    f
    u
    n
    c
    t
    i
    o
    n o
    d
    d
    _
    e
    v
    e
    n
    (
    $
    v
    a
    l
    u
    e
    ) {
    r
    e
    t
    u
    r
    n (
    $
    v
    a
    l
    u
    e % 2 =
    =
    = 0
    )
    ;
    }
    $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c = f
    u
    n
    c
    t
    i
    o
    n
    (
    ) { r
    e
    t
    u
    r
    n r
    a
    n
    d
    (
    )
    ; }
    ;
    $
    r
    e
    s
    u
    l
    t
    s = a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    g
    e
    t
    _
    a
    l
    g
    o
    r
    i
    t
    h
    m
    (
    $
    r
    a
    n
    d
    _
    s
    e
    e
    d
    _
    f
    n
    c
    )
    , $
    d
    a
    t
    a
    )
    ;

    View Slide

  67. PARTIAL FUNCTION
    APPLICATION
    Essentially set defaults
    <
    ?
    p
    h
    p
    $
    f
    i
    r
    s
    t
    _
    c
    h
    a
    r = f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    s
    t
    r
    i
    n
    g
    ) {
    r
    e
    t
    u
    r
    n s
    u
    b
    s
    t
    r
    (
    $
    s
    t
    r
    i
    n
    g
    , 0
    , 1
    )
    ;
    }
    ;
    Works nicely with a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    )
    <
    ?
    p
    h
    p
    a
    r
    r
    a
    y
    _
    m
    a
    p
    (
    $
    f
    i
    r
    s
    t
    _
    c
    h
    a
    r
    , a
    r
    r
    a
    y
    (
    '
    f
    o
    o
    '
    ,
    '
    b
    a
    r
    '
    ,
    '
    b
    a
    z
    '
    )
    )
    ;
    /
    / a
    r
    r
    a
    y
    (
    '
    f
    '
    ,
    '
    b
    '
    ,
    '
    b
    '
    )

    View Slide

  68. CURRYING
    Each parameter becomes a function
    More flexible PFA
    <
    ?
    p
    h
    p
    $
    f
    i
    r
    s
    t
    _
    c
    h
    a
    r = f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    s
    t
    a
    r
    t
    ) {
    r
    e
    t
    u
    r
    n f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    l
    e
    n
    g
    t
    h
    ) u
    s
    e (
    $
    s
    t
    a
    r
    t
    ) {
    r
    e
    t
    u
    r
    n f
    u
    n
    c
    t
    i
    o
    n
    (
    $
    s
    t
    r
    i
    n
    g
    ) u
    s
    e (
    $
    s
    t
    a
    r
    t
    , $
    l
    e
    n
    g
    t
    h
    ) {
    r
    e
    t
    u
    r
    n s
    u
    b
    s
    t
    r
    (
    $
    s
    t
    r
    i
    n
    g
    , $
    s
    t
    a
    r
    t
    , $
    l
    e
    n
    g
    t
    h
    )
    ;
    }
    ;
    }
    ;
    }
    ;
    $
    a = $
    f
    i
    r
    s
    t
    _
    c
    h
    a
    r
    (
    0
    )
    ;
    $
    b = $
    a
    (
    1
    )
    ;
    $
    b
    (
    '
    f
    o
    o
    '
    )
    ; /
    / f
    $
    c = $
    a
    (
    2
    )
    ;
    $
    c
    (
    '
    f
    o
    o
    '
    )
    ; /
    / f
    o

    View Slide

  69. MEMOIZATION
    Function local cache
    <
    ?
    p
    h
    p
    f
    u
    n
    c
    t
    i
    o
    n d
    e
    m
    o
    (
    ) {
    s
    t
    a
    t
    i
    c $
    _
    c
    ;
    i
    f
    (
    i
    s
    _
    n
    u
    l
    l
    (
    $
    _
    c
    )
    ) {
    $
    _
    c = g
    e
    t
    _
    s
    o
    m
    e
    _
    e
    x
    p
    e
    n
    s
    i
    v
    e
    _
    o
    p
    e
    r
    a
    t
    i
    o
    n
    (
    )
    ;
    }
    r
    e
    t
    u
    r
    n $
    _
    c
    ;
    }
    Handy in class methods too!

    View Slide

  70. WHEN TO USE
    FUNCTIONAL?
    Practice
    Innate understanding
    Turing complete methodology

    View Slide

  71. SO MUCH MORE...
    Function composition
    Tail recursion
    Function objects
    New language features
    Functors
    Applicatives
    Monads
    Event driven programming
    Null handling
    & more.

    View Slide

  72. EXIT()
    Functional PHP
    Follow @ for tips
    Simon Holywell
    Follow @
    FunctionalPHP
    FunctionalPHP.com
    Treffynnon
    SimonHolywell.com

    View Slide