speakerdeck-june11-fp-pycon2012-gavinbong.pdf
-
Upload
jon-garcia-de-salazar -
Category
Documents
-
view
213 -
download
0
Transcript of speakerdeck-june11-fp-pycon2012-gavinbong.pdf
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
1/47
Functional Programmingfor the Uninitiated
gavin bong
pycon asia 2012, Singaporele 7 juin 2012 2229 jeudi
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
2/47
2
oadmapfunctional wayhigh order functionsrecursion
foldscurry / partial app.parser combinators
closing
30 mins
mins020208
08mins06mins03
mins
mins
mins
min01
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
3/47
Purely functional is the right
default. Imperatieconstructs .. must be e!posedthrough e!plicit effects"typing
constructs.
#im $weeney%&PI' games (2006)
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
4/47
*o matter what language you
wor+ in% programming in afunctional style proidesbenefits. ,ou should do itwheneer it is conenient% andyou should thin+ hard aboutthe decision when it isn-tconenient.
ohn 'armac+% I $oftware26thapril 2012
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
5/47
The functional way
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
6/47
$ide effectf eese immutable containe s.
ecu sion oe ite ation
i st"class functions 4 closu es.5ighe "o de functions ee ywhe e
a7y ealuation
Functional way: a cook's tour
Pu efunctions ( efe ential t anspa ency)sin(n), log2(n) 'omposable
&!ecution order insignificant
ata t ansfo mations e.g. $#
etc...
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
7/47
Is python a functional language?
anonymous functions (a.+.a lambdas)map% filter% reduceite toolsfunctoolslist comp ehensions%gene ato s
It is an impe atielanguage that hasac9ui ed some functional featu es.*o
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
8/47
Functional aspects #1
Immutable containe s in pythontuplef o7enset
lambdas in python a e limited to a singlee!p ession.#ypes (has+ell as a efe ence)
Patte n matching does not e!ist in python.
nli+e python% has+ell has static typechec+ing with type infe ence.sum :: (Num a) => [a] -> a
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
9/47
High order functions
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
10/47
In python 3.!% map etu ns an ite ato .#hus itertools.imapis emoed.
High order functions
:ccept functions as a guments and/oetu n functions.map
map(f, [a, a2]) [f(a), f(a2)]
filtefilter(predicate, [a, a2]) educeetail t eatment in upcoming slides.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
11/47
Functional aspects #2
[(!, ") for ! in !range(, #)for " in !range(#, )if "-! == $]
ist comp ehension in python
[(!, ") % ! &- [..'], " &- [#..], "-! == $]is inspi ed by has+ell;s synta!
ist comp ehension has la gelysupe ceded the utility of the filter5
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
12/47
Recursion
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
13/47
ecu sionunctional languages do *+ntegersum [] =sum (!:!s) =! sum !s
> has+ell
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
14/47
defsum(se): ifnotse: return
else: returnse[] sum(se[:])
> python
nave sum function
#his does not wo + if you pass in anite ato (e.g. gene ato e!p ession) as thea gument. ?e will fi! this in upcomingslides.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
15/47
*
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
16/47
+nteger ->+ntegersum [] acc =accsum (!:!s) acc =sum !s (! acc) > has+ell
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
17/47
Bany functional languages (li+e $cheme) cansuppo t an unboundednumbe of actie tailcalls ( ecu sie o othe wise).
5as+ell being a la7y language has adiffe ent app oach.
tail ecu sion elimination
defsum(se): deftailsum(se, acc):ifnotse: returnacc else: returntailsum(se[:], se[]acc) returntailsum(se, )
Python does not perform #ail 'all 4()
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
18/47
ecu sion in PythonEIn 'Python%
P efe ite ation oe ecu sion.
:oid the python stac+.# ampoline techni9ue
se co e python featu es. e.g.uiltins.sum
: t ampoline is a function e!ecuto .?o +s fo tail" ecu sie functions(and also co outines with tail"calls).:oids stac+ oe flow.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
19/47
Trampolines
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
20/47
t ampoline >1t*un5 = lamdafn: lamda3args: lamda: fn(3args)
deftailsum(se, acc): it = iter(se) tr": first, rest = (ne!t(it), list(it)) e!cept 6top+teration: returnacc else: returnt*un5(tailsum)(rest, first acc)
elayed computation
#rampoline code is based on e!ample by
ames #auber FDtauber
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
21/47
t ampoline >2In python 3.! (see P&P3132)% we can simplifythe code that e!t acts the head 4 tail of theite ato .deftailsum(se, acc): it = iter(se) tr": first, 3rest = it e!cept 7alue1rror: returnacc else: returnt*un5(tailsum)(rest, first acc)
>python 3
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
22/47
t ampoline >3deftrampoline(ouncer): *ilecallale(ouncer): 8 s*ould e land "et9 ouncer = ouncer() returnouncer
defsum(se): returntrampoline(t*un5(tailsum)(se, ))
#rampoline code is based on e!ample by FDtauber
bounce
land
>>>sum(i fori in range(2))
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
23/47
t ampoline >G
# ampoline e sion highly inefficient.
H8G secs>>>sum( i fori in!range() );'
'ompa isons of benchma +s using timeit>>>sum( i fori in!range() );'
1.66 secs
>>>sum( i fori in!range());'>>sum( i for i in!range());' has+ell
It encapsulates the ecu sie patte nofp ocessing data st uctu es (listsfo simplicity).
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
26/47
fold
sum [] =sum (!:!s) =()!(sum !s) > has+ell
It encapsulates the ecu sie patte nofp ocessing data st uctu es (listsfo simplicity).
K2LMraham 5utton N : tutorial on the uniersality 4
e!pressieness of fold% 1JJJ
nie salp ope tyK2Lof thef ldope ato g [] =g (!:!s) =f!(g !s) fold f #hus% sumsimplifies to
relude>foldl () [..$]#
a ity 2initelists
It educes a list to a single alue.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
27/47
left s ight foldIn has+ell% use foldlfor folding from the left (the
start) and foldrfor folding from the right (the end).
relude> let f = (?acc ! -> acc)relude>foldl f [..$];
&!ample finding the length
f
f
f
2
f
$ left fold
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
28/47
left s ight fold >2relude> let g = (?! acc -> acc)relude>foldr g [..$];
&!ample finding the length
$ g
g
2
g
g
ight fold
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
29/47
fold in pythonIn python 2.!% uiltins.reduce is thepython e sion of the fold ope ato .eft 4 ight folds a e handled by same function.defre@erse(se):
defr(acc, !): acc.insert(, !) returnacc returnreduce(r, se, [])
&!ample reerse a list
et;s implement has+ell;selemusing ight fold.relude>elem 2 [..$]Aruerelude>elem [..$]Balse
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
30/47
defelem(item, se):
se = re@erse(se) defmatc*(!, acc): if! == item: returnArue else:
returnacc returnreduce(lamda a, : matc*(, a), se, Balse)
&!ample has+ell;selemusing ight fold.
#he initial alue is set to Balse.#he accumulato emains Balseuntil amatch is found.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
31/47
H8G secs>>>sum(i fori in!range() )
'ompa isons of benchma +s using timeit
>>> reduce(operator.add,i fori in!range(), )
1.38msecs
>>> reduce(operator.add,i fori in!range(), )
13.6msecsH.HJmsecs
>>>sum(i for i in!range())
$imple benchma + of educe>>> importoperator
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
32/47
In python 3.!% uiltins.reducehasbeen moed to functools.reduce
$ee al p ope ties of educe
reduce( lamdaa, : a % , [Arue, Balse, Balse], Balse ) 8 an"
reducedoes not sho t"ci cuitO which woulde!plain why it is slowe than the builtin an"oallfo use cases below
reduce( lamdaa, : a C , [Balse, Balse, Arue], Balse ) 8 all
5omewo +Implement map4 filterusing reduce.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
33/47
Currying &
partial application
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
34/47
'u ied functions'u yingis the techni9ue of t ansfo ming afunction that ta+es multiplea guments into ..a chain of una yfunctions.&!ample cu ying functions of a ity2>>> importoperator>>> assertoperator.su(, 2)== -operator
>>> defcurr"2(f): returnlamdaa: lamda: f(a, )
>>> curriedsu = curr"2(operator.su)>>> assertcurriedsu()(2) ==-
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
35/47
&!ample uncu ying functions of a ity2uncu y
>>> defuncurr"2(f): return lamda a, : f(a)()
>>> originalsu = uncurr"2(curriedsu)
>>> assertoriginalsu(, 2) ==-
:ll functions a e cu iedin 5as+ell.K1Lsutract :: (Num a) => a -> a -> a
as oppose to the uncu iedfo msutract :: (Num a) => (a, a) -> a
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
36/47
Cenefits of cu ied functions?hat is the point of this E
#heo etical N able to t eat functions unifo mly.P actical N aids in the c eation of pa tiallyapplied functions.
Cind somealues to some (but not all) of thea guments of a cu ied function.Pa tial application
> has+ellg*ci> map (23) [, , 2][, 2, ;]
g*ci> map (sutract ) [, , 2][-, , ]
P&P 30J standa di7es a pa tialobDect(since python 2.).
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
37/47
functools.pa tial in action>>> operator.su.docDsu(a, ) E same as a - .D>>> sutract = partial(operator.su, )>>> sutract(2) 8 e@aluat ng - 2-
>>> sutract.5e"ordsFG
>>> sutract.args(,)
'aeat $ince pe at is a ' module% you cannotbind alues to specific positionala guments.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
38/47
functools.pa tial in action >2#he limitation desc ibed in the last slide doesnot apply to use defined functions. #hus%>>> defminus(a, ): Dclone of operator.suD returna - >>> sutract2 = partial(minus, =2)>>> sutract2.5e"ordsFDD: 2G>>> sutract2.docDpartial(func, 3args, 335e"ords) ...D>>> fromfunctools importupdaterapper>>> updaterapper(sutract2, minus)>>> sutract2.docDclone of operator.suD
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
39/47
miscpa tialcan be applied to classes% classmethods and instance methods.pa tialcan be used to c eate thun+s (asopposed to hand"c afted lambdas)It is o+ to imagine pe at .itemgette 4pe at .att gette as cu ied functions(although thei implementation does notmatch that mental model).
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
40/47
functools.w apsP o!ying to callables fo c eating deco ato s.
In conDunction with functools.updateQw appe4 functools.pa tial% the w apped function;sQQnameQQ% QQmoduleQQandQQdocQQa ep ese ed.
e.g. Dango iew deco ato Fcs fQe!empt
&!ample deco ato to measu e unning timedefueue(fn, duration): 8 send timings as"nc*ronousl" pass
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
41/47
importtimefromfunctools importrapsdeftimer(f): Hraps(f) defrapper(3args, 335args): start = time.time() f(3args, 335args) end = time.time() ueue(f.name, end E start) return rapperHtimerdefuserfunction(a, , c): pass
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
42/47
functools in python 3.!functools.l uQcacheBemoi7ation deco ato that caches esultsof the w appe function.Imp oes pe fo mance of t ee ecu siefunctions e.g. fibonacci.
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
43/47
Parser combinators:
a case study
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
44/47
Pa se combinato s: eal wo ld application of highe o de functions.: pa se is built up f om smalle p imitie pa se s.Pa se combinato s a e Dust highe "o defunctions.
arser :: 6tring I6AJominator :: arser arser arser#hus% g amma const uction fo things li+eepetition % se9uencing o choice is modelled usingcombinato s.&!ample t iial ma athon unning timepa seusing funcpa selib.
parse(2:':2')==(2,',2')
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
45/47
Pa se combinato s >2to5enie: 6tring [Ao5en]
parse: [Ao5en] tuple
>>> to5enie(D2:':2'D)[Ao5en(Dositi@e+ntegerD, D2D),Ao5en(DJolonD, D:D),
Ao5en(Dositi@e+ntegerD, D'D),Ao5en(DJolonD, D:D),Ao5en(Dositi@e+ntegerD, D2'D)]
>>> parse(to5enie(D2:':2'D))(2, ', 2')
-
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
46/47
Pa se combinato s >3grammar = (*our colon minute colon second s5ip(finis*ed))grammar.parse(se) 8se is [Ao5en]
'omplete code at http//pastebin.com/+1Bd5$i
ma5enum = lamdan: int(n)to5@al = lamda!: !.@alue*our = some(lamda !: posint(!) and it*in(!.@alue,K))>> to5@al>> ma5enum
http://pastebin.com/k1MdUHSihttp://pastebin.com/k1MdUHSi -
8/13/2019 speakerdeck-june11-fp-pycon2012-gavinbong.pdf
47/47
#he endea ning P will ma+e you a bette(python) p og amme .#heo y$tudy 'atego y theo y4 #ype theo y.
Play with othe P languages5as+ell%