Practical Functional Programming Practical Functional Programming Bogdan Hodorog 8th November 2014 / Functional Angle
Practical Functional Programming Introduction Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Introduction About the speaker linkedin.com says Technical Manager my heart says Software engineer is daily reviewing and writing python code sometimes reads and changes elisp code seldom reads c code presently is trying to add golang to his cv in the far past he used java for several years rudimentary knowledge of ruby, javascript, ML
Practical Functional Programming Introduction About the speaker linkedin.com says Technical Manager my heart says Software engineer is daily reviewing and writing python code sometimes reads and changes elisp code seldom reads c code presently is trying to add golang to his cv in the far past he used java for several years rudimentary knowledge of ruby, javascript, ML
Practical Functional Programming Introduction What is the goal of this talk? intended for programmers using non-strict functional programming languages use something you learned from this presentation in the next week while writing your usual code
Practical Functional Programming First class functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions First order functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions First order functions Context A function’s components a unique identifier, commonly refered as name an parameters list instruction(s), commonly refered a body return value Question? What kind of arguments can be passed? Answer Any kind of objects except functions
Practical Functional Programming First class functions First order functions Code python def name(par1, par2): val = "something" return val elisp (defun name(par1 par2) (let ((return_val "something")) return_val))
Practical Functional Programming First class functions Higher order functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions Higher order functions Context Question? What kind of arguments can be passed? Answer any type including functions functions must be first-class citizens
Practical Functional Programming First class functions Higher order functions Context python def capitalize(names): result = [] for name in names: result.append(name.capitalize()) return result team = ["laura", "bogdan", "titus", "zoli", "alex"] >>> capitalize(team) [’Laura’, ’Bogdan’, ’Titus’, ’Zoli’, ’Alex’]
Practical Functional Programming First class functions Higher order functions Reason python def c a p i t a l i z e (names ) : r e s u l t = [ ] for name in names : r e s u l t . append (name . c a p i t a l i z e ( ) ) return r e s u l t def uppercase (names ) : r e s u l t = [ ] for name in names : r e s u l t . append (name . uppercase ( ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> c a p i t a l i z e ( team) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> uppercase ( team) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
Practical Functional Programming First class functions Higher order functions Enter higher order function python def process (names , func ) : r e s u l t = [ ] for name in names : r e s u l t . append ( func (name ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> process ( team , s t r i n g . c a p i t a l i z e ) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( team , s t r i n g . upper ) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
Practical Functional Programming First class functions Higher order functions Generic examples python def high_ord ( par1 , func ) : val = " { } and { } " . format ( par1 , func ( par1 ) ) return val high_ord ( " bogdan " , s t r i n g . c a p i t a l i z e ) elisp ( defun high_ord ( par1 func ) ( l e t ( ( r e t u r n _ v a l ( format "%s and %s " par1 ( funcal l func par1 ) ) ) ) r e t u r n _ v a l ) ) ( high_ord " something " ( f u n c t i o n c a p i t a l i z e ) )
Practical Functional Programming First class functions Higher order functions Decorators Question What about returning a function from a function? python def forbidden ( ) : val = " I can ’ t change t h i s code " return val def decorate ( func ) : def wrapper ( ) : pr int " Something new I want to add " return func ( ) return wrapper forbidden = decorate ( forbidden ) >>> pr int forbidden ( ) Something new I want to add " I can ’ t change t h i s code "
Practical Functional Programming First class functions map()/filter()/reduce() Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions map()/filter()/reduce() map() python def process (names , func ) : r e s u l t = [ ] for name in names : r e s u l t . append ( func (name ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> process ( team , s t r i n g . c a p i t a l i z e ) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( team , s t r i n g . upper ) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
Practical Functional Programming First class functions map()/filter()/reduce() map() python def map( func , c o l l e c t i o n ) : r e s u l t = [ ] for elem in c o l l e c t i o n : r e s u l t . append ( func ( elem ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> map( s t r i n g . c a p i t a l i z e , team) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( s t r i n g . upper , team) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
Practical Functional Programming First class functions map()/filter()/reduce() filter() python def g e t _ s t a r t s _wi t h ( chars , names ) : r e s u l t = [ ] for name in names : i f name [ 0 ] in chars : r e s u l t . append (name) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> g e t _ s t a r t s _wi t h ( " aeiou " , team) [ ’ alex ’ ]
Practical Functional Programming First class functions map()/filter()/reduce() filter() python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) [ ’ alex ’ ]
Practical Functional Programming First class functions map()/filter()/reduce() Alternative: enter List Comprehensions python team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> [ s t r i n g . upper (name) for name in team] [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ] >>> [ name for name in team i f name [ 0 ] in " aeiou " ] [ ’ alex ’ ]
Practical Functional Programming First class functions map()/filter()/reduce() reduce() Aliases fold, accumulate, aggregate python def count_chars (names ) : r e s u l t = 0 for name in names : r e s u l t += len (name) return r e s u l t team = [ ’ laura ’ , ’ bogdan ’ , ’ t i t u s ’ , ’ z o l i ’ , ’ alex ’ ] >>> count_chars ( team) 24
Practical Functional Programming First class functions map()/filter()/reduce() reduce() Aliases fold, accumulate, aggregate python def accumulator ( acc , e l ) : return acc + len ( e l ) team = [ ’ laura ’ , ’ bogdan ’ , ’ t i t u s ’ , ’ z o l i ’ , ’ alex ’ ] >>> reduce ( accumulator , team , 0) 24
Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level
Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t python def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " f i l t e r ( s t a r t s _wi t h , team)
Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners
Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners on the other hand, try to debug them :(
Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners on the other hand, try to debug them :( map/filter apart of having aliases might be disguised in other forms (e.g. comprehensions)
Practical Functional Programming First class functions Annonymous functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions Annonymous functions lambda the term comes from Lambda calculus often refers to a programming language support for annonymous functions often has slightly different semantic in each language python: anonymous function with a single expression as body elisp: anonymous function without a name
Practical Functional Programming First class functions Closures Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions Closures Closures Explained function + environment environment contains local variables, params short of lexical closure as opossed to dynamic scoping function’s variables bound where defined not where called favour laziness, they’re active only when called
Practical Functional Programming First class functions Closures Lexical scope, not dynamic! python def outer ( ) : global a pr int " global environment : a ={ } " . format ( a ) def inner ( b ) : pr int " inner environment : a ={ } , b ={ } " . format ( a , b ) return a + b a = 2 pr int ( " outer environment : a ={ } " . format ( a ) ) pr int inner ( a+2) a = 10 pr int " r e s u l t i s { } " . format ( outer ( ) ) valid python, lexical scope >>> global environment : a=10 outer environment : a=2 inner environment : a=2 ,b=4 r e s u l t is 6
Practical Functional Programming First class functions Closures Lexical scope, not dynamic! python def outer ( ) : global a pr int " global environment : a ={ } " . format ( a ) def inner ( b ) : pr int " inner environment : a ={ } , b ={ } " . format ( a , b ) return a + b a = 2 pr int ( " outer environment : a ={ } " . format ( a ) ) pr int inner ( a+2) a = 10 pr int " r e s u l t i s { } " . format ( outer ( ) ) imaginary dynamic scope >>> global environment : a=10 outer environment : a=2 inner environment : a=10 ,b=4 r e s u l t is 14
Practical Functional Programming First class functions Closures Practicality use them for laziness use them for memoization use them to have more expressive code think of them as alternative to classes know your language most languages use just lexical scoping some languages allows switching between lexical and dynamic scoping closures for functions/lambdas/others may behave different
Practical Functional Programming First class functions Partial application Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions Partial application Remember filter() example python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t Refactor starts_with def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) [ ’ alex ’ ]
Practical Functional Programming First class functions Partial application The problem python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t How do we pass the 2nd arg? def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) TypeError : s t a r t s _wi t h ( ) takes exac t l y 2 arguments (1 given )
Practical Functional Programming First class functions Partial application Solution python def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x import f u n c t o o l s f rozen_func = f u n c t o o l s . p a r t i a l ( s t a r t s _wi t h , p r e f i x =" aeiou " ) team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( f rozen_func , team) [ ’ alex ’ ] >>> f rozen_func . func < f u n c t i o n s t a r t s _wi t h at 0x103b4c500> >>> f rozen_func . keywords { ’ p r e f i x ’ : ’ aeiou ’ }
Practical Functional Programming First class functions Partial application Solution python def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x import f u n c t o o l s f rozen_func = f u n c t o o l s . p a r t i a l ( s t a r t s _wi t h , p r e f i x =" aeiou " ) team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( f rozen_func , team) [ ’ alex ’ ] >>> f rozen_func . func < f u n c t i o n s t a r t s _wi t h at 0x103b4c500> >>> f rozen_func . keywords { ’ p r e f i x ’ : ’ aeiou ’ } Explained curried("aeiou") is a function object waiting to be called its closure contains variable prefix="aeiou"
Practical Functional Programming First class functions Partial application Practicality work with map/filter functions enforce some client code based on higher order functions to use fixed value for some arguments often can be replace with lambda python team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( lambda e l : s t a r t s _wi t h ( el , " aeiou " ) , team) [ ’ alex ’ ]
Practical Functional Programming First class functions Currying Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
Practical Functional Programming First class functions Currying Problem same as for Partial application How do we pass the 2nd arg? def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) TypeError : s t a r t s _wi t h ( ) takes exac t l y 2 arguments (1 given )
Practical Functional Programming First class functions Currying Solution python def c u r r i e d ( p r e f i x ) : def el_c losure ( e l ) : return e l [ 0 ] in p r e f i x return el_c losure team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( c u r r i e d ( " aeiou " ) , team) [ ’ alex ’ ]
Practical Functional Programming First class functions Currying Solution python def mu l t i p l e ( a , b , c ) : return a + b + c def a_f ( a ) : def b_f ( b ) : def c_f ( c ) : return a + b + c return c_f return b_f mu l t i p l e (1 , 2 , 3) a_f ( 1 ) ( 2 ) ( 3 ) " " " a_f ( 1 ) ( 2 ) ( 3 ) b_f ( 2 ) ( 3 ) c_f ( 3 ) " " " SML fun foo ( a : i n t , b : i n t , c : i n t ) = a + b +c val c u r r i e d = fn x => fn y => fn z => x + y + z ( ( ( c u r r i e d 1) 2) 3 ) ; 6 c u r r i e d 1 2 3; 6
Practical Functional Programming First class functions Currying Practicality not used in daily situations came accross it in some technical docs
Practical Functional Programming First class functions Currying vs Partial application both rely on closure both solve the same problems subtle difference currying returns a function object with single param partial application may return a function object with multiple params
Practical Functional Programming Immutability Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python def reorder(coll) -- a sorted collection team = [laura, bogdan, titus, zoli, alex] print reorder(team) [’alex’, ’bogdan’, ’laura’, ’titus’, ’zoli’]
Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python def reorder(coll) -- a sorted collection team = [laura, bogdan, titus, zoli, alex] print reorder(team) [’alex’, ’bogdan’, ’laura’, ’titus’, ’zoli’] print team ???
Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python team = [laura, bogdan, titus, zoli, alex] def reorder(coll): coll.sort() return coll reorder(team) print team [’laura’, ’bogdan’, ’titus’, ’zoli’, ’alex’]
Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python team = [laura, bogdan, titus, zoli, alex] def reorder(coll): return sorted(coll) reorder(team) print team [laura, bogdan, titus, zoli, alex]
Practical Functional Programming Immutability Practicality mutablity may lead to race conditions immutable objects are considered thread-safe unwanted modifications can be performed on sensitive collections pure functions doesn’t leak side effects some languages support explicit syntax for mutable operations ruby’s bang .methods! scala’s var and val
Practical Functional Programming Immutability Practicality
Practical Functional Programming Evaluation strategies Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Evaluation strategies Functional languages Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Evaluation strategies Functional languages Eager vs Lazy many of non-strict functional languages use eager(strict) evaluation pass-by-value pass-by-reference pass-by-sharing most strict functional languages use lazy evaluation
Practical Functional Programming Evaluation strategies Non-functional languages Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Evaluation strategies Non-functional languages Thunk Reason python def crazy_complex ( i ) : pr int This i s O( nnn ) return i 1 def add_some ( x , some ) : i f some 0: return x + 3 return some pr int add_some ( crazy_complex ( 8 ) , 1) This is O( nnn ) 11
Practical Functional Programming Evaluation strategies Non-functional languages Thunk Call by name Evaluate the argument only if needed python def crazy_complex ( i ) : pr int This i s O( nnn ) return i 1 def add_some ( thunk , some ) : i f some 0: return thunk ( ) + 3 return some from f u n c t o o l s import p a r t i a l # or use cur r y i ng instead lazy_thunk = p a r t i a l ( crazy_complex , 8) pr int add_some ( lazy_thunk , 1) This is O( nnn ) 11 pr int add_some ( lazy_thunk , 1) 1
Practical Functional Programming Evaluation strategies Non-functional languages Generators Description is a function object behaving like an iterator generates one element at a time python import random team = [ laura , bogdan , t i t u s , z o l i , alex ] def i n i f i n i t e ( c o l l ) : while True : y i e l d random. choice ( team) gener = i n i f i n i t e ( team)
Practical Functional Programming Evaluation strategies Non-functional languages Generators Description is a function object behaving like an iterator generates one element at a time python gener . next ( ) ’ bogdan ’ gener . next ( ) ’ laura ’ gener . next ( ) ’ z o l i ’ python gener . next ( ) ’ t i t u s ’ gener . next ( ) ’ z o l i ’ gener . next ( ) ’ laura ’
Practical Functional Programming Evaluation strategies Non-functional languages Practicality use thunks to decorate functions thunks can help with lazy evaluation generators offers one element at a time, useful for dealing with streams use generators for inifinte source of data
Practical Functional Programming Uncommon topics Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Uncommon topics to look into Tail call optimization: famous topic, but rarely encountered in practice (Scheme, ML, Erlang) Pattern matching
Practical Functional Programming Remember checklist Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
Practical Functional Programming Remember checklist Asses functional capabilities of a programming language 1 check for first class functions: pass, bound and return 2 look for map/filter/reduce/comprehension and beware of when to use them 3 support for closure 4 annonymous functions and their limit 5 identify immutable types and other related features 6 understand the evaluation strategies employed by the language
Practical Functional Programming Remember checklist

Practical Functional Programming Presentation by Bogdan Hodorog

  • 1.
    Practical Functional Programming Practical Functional Programming Bogdan Hodorog 8th November 2014 / Functional Angle
  • 2.
    Practical Functional Programming Introduction Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 3.
    Practical Functional Programming Introduction About the speaker linkedin.com says Technical Manager my heart says Software engineer is daily reviewing and writing python code sometimes reads and changes elisp code seldom reads c code presently is trying to add golang to his cv in the far past he used java for several years rudimentary knowledge of ruby, javascript, ML
  • 4.
    Practical Functional Programming Introduction About the speaker linkedin.com says Technical Manager my heart says Software engineer is daily reviewing and writing python code sometimes reads and changes elisp code seldom reads c code presently is trying to add golang to his cv in the far past he used java for several years rudimentary knowledge of ruby, javascript, ML
  • 5.
    Practical Functional Programming Introduction What is the goal of this talk? intended for programmers using non-strict functional programming languages use something you learned from this presentation in the next week while writing your usual code
  • 6.
    Practical Functional Programming First class functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 7.
    Practical Functional Programming First class functions First order functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 8.
    Practical Functional Programming First class functions First order functions Context A function’s components a unique identifier, commonly refered as name an parameters list instruction(s), commonly refered a body return value Question? What kind of arguments can be passed? Answer Any kind of objects except functions
  • 9.
    Practical Functional Programming First class functions First order functions Code python def name(par1, par2): val = "something" return val elisp (defun name(par1 par2) (let ((return_val "something")) return_val))
  • 10.
    Practical Functional Programming First class functions Higher order functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 11.
    Practical Functional Programming First class functions Higher order functions Context Question? What kind of arguments can be passed? Answer any type including functions functions must be first-class citizens
  • 12.
    Practical Functional Programming First class functions Higher order functions Context python def capitalize(names): result = [] for name in names: result.append(name.capitalize()) return result team = ["laura", "bogdan", "titus", "zoli", "alex"] >>> capitalize(team) [’Laura’, ’Bogdan’, ’Titus’, ’Zoli’, ’Alex’]
  • 13.
    Practical Functional Programming First class functions Higher order functions Reason python def c a p i t a l i z e (names ) : r e s u l t = [ ] for name in names : r e s u l t . append (name . c a p i t a l i z e ( ) ) return r e s u l t def uppercase (names ) : r e s u l t = [ ] for name in names : r e s u l t . append (name . uppercase ( ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> c a p i t a l i z e ( team) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> uppercase ( team) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
  • 14.
    Practical Functional Programming First class functions Higher order functions Enter higher order function python def process (names , func ) : r e s u l t = [ ] for name in names : r e s u l t . append ( func (name ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> process ( team , s t r i n g . c a p i t a l i z e ) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( team , s t r i n g . upper ) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
  • 15.
    Practical Functional Programming First class functions Higher order functions Generic examples python def high_ord ( par1 , func ) : val = " { } and { } " . format ( par1 , func ( par1 ) ) return val high_ord ( " bogdan " , s t r i n g . c a p i t a l i z e ) elisp ( defun high_ord ( par1 func ) ( l e t ( ( r e t u r n _ v a l ( format "%s and %s " par1 ( funcal l func par1 ) ) ) ) r e t u r n _ v a l ) ) ( high_ord " something " ( f u n c t i o n c a p i t a l i z e ) )
  • 16.
    Practical Functional Programming First class functions Higher order functions Decorators Question What about returning a function from a function? python def forbidden ( ) : val = " I can ’ t change t h i s code " return val def decorate ( func ) : def wrapper ( ) : pr int " Something new I want to add " return func ( ) return wrapper forbidden = decorate ( forbidden ) >>> pr int forbidden ( ) Something new I want to add " I can ’ t change t h i s code "
  • 17.
    Practical Functional Programming First class functions map()/filter()/reduce() Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 18.
    Practical Functional Programming First class functions map()/filter()/reduce() map() python def process (names , func ) : r e s u l t = [ ] for name in names : r e s u l t . append ( func (name ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> process ( team , s t r i n g . c a p i t a l i z e ) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( team , s t r i n g . upper ) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
  • 19.
    Practical Functional Programming First class functions map()/filter()/reduce() map() python def map( func , c o l l e c t i o n ) : r e s u l t = [ ] for elem in c o l l e c t i o n : r e s u l t . append ( func ( elem ) ) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> map( s t r i n g . c a p i t a l i z e , team) [ ’ Laura ’ , ’Bogdan ’ , ’ Ti tu s ’ , ’ Z o l i ’ , ’ Alex ’ ] >>> process ( s t r i n g . upper , team) [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ]
  • 20.
    Practical Functional Programming First class functions map()/filter()/reduce() filter() python def g e t _ s t a r t s _wi t h ( chars , names ) : r e s u l t = [ ] for name in names : i f name [ 0 ] in chars : r e s u l t . append (name) return r e s u l t team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> g e t _ s t a r t s _wi t h ( " aeiou " , team) [ ’ alex ’ ]
  • 21.
    Practical Functional Programming First class functions map()/filter()/reduce() filter() python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) [ ’ alex ’ ]
  • 22.
    Practical Functional Programming First class functions map()/filter()/reduce() Alternative: enter List Comprehensions python team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> [ s t r i n g . upper (name) for name in team] [ ’LAURA ’ , ’BOGDAN’ , ’TITUS ’ , ’ ZOLI ’ , ’ALEX ’ ] >>> [ name for name in team i f name [ 0 ] in " aeiou " ] [ ’ alex ’ ]
  • 23.
    Practical Functional Programming First class functions map()/filter()/reduce() reduce() Aliases fold, accumulate, aggregate python def count_chars (names ) : r e s u l t = 0 for name in names : r e s u l t += len (name) return r e s u l t team = [ ’ laura ’ , ’ bogdan ’ , ’ t i t u s ’ , ’ z o l i ’ , ’ alex ’ ] >>> count_chars ( team) 24
  • 24.
    Practical Functional Programming First class functions map()/filter()/reduce() reduce() Aliases fold, accumulate, aggregate python def accumulator ( acc , e l ) : return acc + len ( e l ) team = [ ’ laura ’ , ’ bogdan ’ , ’ t i t u s ’ , ’ z o l i ’ , ’ alex ’ ] >>> reduce ( accumulator , team , 0) 24
  • 25.
    Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level
  • 26.
    Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t python def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " f i l t e r ( s t a r t s _wi t h , team)
  • 27.
    Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners
  • 28.
    Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners on the other hand, try to debug them :(
  • 29.
    Practical Functional Programming First class functions map()/filter()/reduce() Practicality solution for reducing code nesting level useful for oneliners on the other hand, try to debug them :( map/filter apart of having aliases might be disguised in other forms (e.g. comprehensions)
  • 30.
    Practical Functional Programming First class functions Annonymous functions Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 31.
    Practical Functional Programming First class functions Annonymous functions lambda the term comes from Lambda calculus often refers to a programming language support for annonymous functions often has slightly different semantic in each language python: anonymous function with a single expression as body elisp: anonymous function without a name
  • 32.
    Practical Functional Programming First class functions Closures Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 33.
    Practical Functional Programming First class functions Closures Closures Explained function + environment environment contains local variables, params short of lexical closure as opossed to dynamic scoping function’s variables bound where defined not where called favour laziness, they’re active only when called
  • 34.
    Practical Functional Programming First class functions Closures Lexical scope, not dynamic! python def outer ( ) : global a pr int " global environment : a ={ } " . format ( a ) def inner ( b ) : pr int " inner environment : a ={ } , b ={ } " . format ( a , b ) return a + b a = 2 pr int ( " outer environment : a ={ } " . format ( a ) ) pr int inner ( a+2) a = 10 pr int " r e s u l t i s { } " . format ( outer ( ) ) valid python, lexical scope >>> global environment : a=10 outer environment : a=2 inner environment : a=2 ,b=4 r e s u l t is 6
  • 35.
    Practical Functional Programming First class functions Closures Lexical scope, not dynamic! python def outer ( ) : global a pr int " global environment : a ={ } " . format ( a ) def inner ( b ) : pr int " inner environment : a ={ } , b ={ } " . format ( a , b ) return a + b a = 2 pr int ( " outer environment : a ={ } " . format ( a ) ) pr int inner ( a+2) a = 10 pr int " r e s u l t i s { } " . format ( outer ( ) ) imaginary dynamic scope >>> global environment : a=10 outer environment : a=2 inner environment : a=10 ,b=4 r e s u l t is 14
  • 36.
    Practical Functional Programming First class functions Closures Practicality use them for laziness use them for memoization use them to have more expressive code think of them as alternative to classes know your language most languages use just lexical scoping some languages allows switching between lexical and dynamic scoping closures for functions/lambdas/others may behave different
  • 37.
    Practical Functional Programming First class functions Partial application Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 38.
    Practical Functional Programming First class functions Partial application Remember filter() example python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t Refactor starts_with def s t a r t s _wi t h ( e l ) : return e l [ 0 ] in " aeiou " team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) [ ’ alex ’ ]
  • 39.
    Practical Functional Programming First class functions Partial application The problem python def f i l t e r ( func , c o l l e c t i o n ) : r e s u l t = [ ] for name in names : i f func (name ) : r e s u l t . append (name) return r e s u l t How do we pass the 2nd arg? def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) TypeError : s t a r t s _wi t h ( ) takes exac t l y 2 arguments (1 given )
  • 40.
    Practical Functional Programming First class functions Partial application Solution python def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x import f u n c t o o l s f rozen_func = f u n c t o o l s . p a r t i a l ( s t a r t s _wi t h , p r e f i x =" aeiou " ) team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( f rozen_func , team) [ ’ alex ’ ] >>> f rozen_func . func < f u n c t i o n s t a r t s _wi t h at 0x103b4c500> >>> f rozen_func . keywords { ’ p r e f i x ’ : ’ aeiou ’ }
  • 41.
    Practical Functional Programming First class functions Partial application Solution python def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x import f u n c t o o l s f rozen_func = f u n c t o o l s . p a r t i a l ( s t a r t s _wi t h , p r e f i x =" aeiou " ) team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( f rozen_func , team) [ ’ alex ’ ] >>> f rozen_func . func < f u n c t i o n s t a r t s _wi t h at 0x103b4c500> >>> f rozen_func . keywords { ’ p r e f i x ’ : ’ aeiou ’ } Explained curried("aeiou") is a function object waiting to be called its closure contains variable prefix="aeiou"
  • 42.
    Practical Functional Programming First class functions Partial application Practicality work with map/filter functions enforce some client code based on higher order functions to use fixed value for some arguments often can be replace with lambda python team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( lambda e l : s t a r t s _wi t h ( el , " aeiou " ) , team) [ ’ alex ’ ]
  • 43.
    Practical Functional Programming First class functions Currying Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 44.
    Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
  • 45.
    Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
  • 46.
    Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
  • 47.
    Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
  • 48.
    Practical Functional Programming First class functions Currying Origin named after Haskell Curry (mathematician), not the dish! Lambda calculus theory: says each function has a single param How are multi-params function emulated using this paradigm? Using function composition
  • 49.
    Practical Functional Programming First class functions Currying Problem same as for Partial application How do we pass the 2nd arg? def s t a r t s _wi t h ( el , p r e f i x ) : return e l [ 0 ] in p r e f i x team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( s t a r t s _wi t h , team) TypeError : s t a r t s _wi t h ( ) takes exac t l y 2 arguments (1 given )
  • 50.
    Practical Functional Programming First class functions Currying Solution python def c u r r i e d ( p r e f i x ) : def el_c losure ( e l ) : return e l [ 0 ] in p r e f i x return el_c losure team = [ " laura " , " bogdan " , " t i t u s " , " z o l i " , " alex " ] >>> f i l t e r ( c u r r i e d ( " aeiou " ) , team) [ ’ alex ’ ]
  • 51.
    Practical Functional Programming First class functions Currying Solution python def mu l t i p l e ( a , b , c ) : return a + b + c def a_f ( a ) : def b_f ( b ) : def c_f ( c ) : return a + b + c return c_f return b_f mu l t i p l e (1 , 2 , 3) a_f ( 1 ) ( 2 ) ( 3 ) " " " a_f ( 1 ) ( 2 ) ( 3 ) b_f ( 2 ) ( 3 ) c_f ( 3 ) " " " SML fun foo ( a : i n t , b : i n t , c : i n t ) = a + b +c val c u r r i e d = fn x => fn y => fn z => x + y + z ( ( ( c u r r i e d 1) 2) 3 ) ; 6 c u r r i e d 1 2 3; 6
  • 52.
    Practical Functional Programming First class functions Currying Practicality not used in daily situations came accross it in some technical docs
  • 53.
    Practical Functional Programming First class functions Currying vs Partial application both rely on closure both solve the same problems subtle difference currying returns a function object with single param partial application may return a function object with multiple params
  • 54.
    Practical Functional Programming Immutability Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 55.
    Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python def reorder(coll) -- a sorted collection team = [laura, bogdan, titus, zoli, alex] print reorder(team) [’alex’, ’bogdan’, ’laura’, ’titus’, ’zoli’]
  • 56.
    Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python def reorder(coll) -- a sorted collection team = [laura, bogdan, titus, zoli, alex] print reorder(team) [’alex’, ’bogdan’, ’laura’, ’titus’, ’zoli’] print team ???
  • 57.
    Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python team = [laura, bogdan, titus, zoli, alex] def reorder(coll): coll.sort() return coll reorder(team) print team [’laura’, ’bogdan’, ’titus’, ’zoli’, ’alex’]
  • 58.
    Practical Functional Programming Immutability Context Question Why should we care about types being mutable or immutable? python team = [laura, bogdan, titus, zoli, alex] def reorder(coll): return sorted(coll) reorder(team) print team [laura, bogdan, titus, zoli, alex]
  • 59.
    Practical Functional Programming Immutability Practicality mutablity may lead to race conditions immutable objects are considered thread-safe unwanted modifications can be performed on sensitive collections pure functions doesn’t leak side effects some languages support explicit syntax for mutable operations ruby’s bang .methods! scala’s var and val
  • 60.
    Practical Functional Programming Immutability Practicality
  • 61.
    Practical Functional Programming Evaluation strategies Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 62.
    Practical Functional Programming Evaluation strategies Functional languages Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 63.
    Practical Functional Programming Evaluation strategies Functional languages Eager vs Lazy many of non-strict functional languages use eager(strict) evaluation pass-by-value pass-by-reference pass-by-sharing most strict functional languages use lazy evaluation
  • 64.
    Practical Functional Programming Evaluation strategies Non-functional languages Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 65.
    Practical Functional Programming Evaluation strategies Non-functional languages Thunk Reason python def crazy_complex ( i ) : pr int This i s O( nnn ) return i 1 def add_some ( x , some ) : i f some 0: return x + 3 return some pr int add_some ( crazy_complex ( 8 ) , 1) This is O( nnn ) 11
  • 66.
    Practical Functional Programming Evaluation strategies Non-functional languages Thunk Call by name Evaluate the argument only if needed python def crazy_complex ( i ) : pr int This i s O( nnn ) return i 1 def add_some ( thunk , some ) : i f some 0: return thunk ( ) + 3 return some from f u n c t o o l s import p a r t i a l # or use cur r y i ng instead lazy_thunk = p a r t i a l ( crazy_complex , 8) pr int add_some ( lazy_thunk , 1) This is O( nnn ) 11 pr int add_some ( lazy_thunk , 1) 1
  • 67.
    Practical Functional Programming Evaluation strategies Non-functional languages Generators Description is a function object behaving like an iterator generates one element at a time python import random team = [ laura , bogdan , t i t u s , z o l i , alex ] def i n i f i n i t e ( c o l l ) : while True : y i e l d random. choice ( team) gener = i n i f i n i t e ( team)
  • 68.
    Practical Functional Programming Evaluation strategies Non-functional languages Generators Description is a function object behaving like an iterator generates one element at a time python gener . next ( ) ’ bogdan ’ gener . next ( ) ’ laura ’ gener . next ( ) ’ z o l i ’ python gener . next ( ) ’ t i t u s ’ gener . next ( ) ’ z o l i ’ gener . next ( ) ’ laura ’
  • 69.
    Practical Functional Programming Evaluation strategies Non-functional languages Practicality use thunks to decorate functions thunks can help with lazy evaluation generators offers one element at a time, useful for dealing with streams use generators for inifinte source of data
  • 70.
    Practical Functional Programming Uncommon topics Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 71.
    Practical Functional Programming Uncommon topics to look into Tail call optimization: famous topic, but rarely encountered in practice (Scheme, ML, Erlang) Pattern matching
  • 72.
    Practical Functional Programming Remember checklist Outline 1 Introduction 2 First class functions First order functions Higher order functions map()/filter()/reduce() Annonymous functions Closures Partial application Currying 3 Immutability 4 Evaluation strategies Functional languages Non-functional languages 5 Uncommon topics 6 Remember checklist
  • 73.
    Practical Functional Programming Remember checklist Asses functional capabilities of a programming language 1 check for first class functions: pass, bound and return 2 look for map/filter/reduce/comprehension and beware of when to use them 3 support for closure 4 annonymous functions and their limit 5 identify immutable types and other related features 6 understand the evaluation strategies employed by the language
  • 74.