(Func&onal (Programming (in (Scheme))))jlu.myweb.cs.uwindsor.ca/440/440scheme2017.pdf · 5 History...
Transcript of (Func&onal (Programming (in (Scheme))))jlu.myweb.cs.uwindsor.ca/440/440scheme2017.pdf · 5 History...
2
Programmingparadigms
• Func&onal– Noassignmentstatement
– Nosideeffect– Userecursion
• Logic• OOP• AOP• …
3
Whatisfunc&onalprogramming
• ItisNOTwhatyoudoininIMPERATIVElanguagessuchC,C++,Java,C#....
• Func&onsarefirstclassobjects.– everythingyoucandowith"data"canbedonewithfunc&onsthemselves– suchaspassingafunc&ontoanotherfunc&on.
– "higherorder"func&ons,func&onsthatoperateonfunc&ons.E.g.,MAP/REDUCE.
• Recursionisusedasaprimarycontrolstructure.– InsomeFPlanguages,noother"loop"constructexists.
• FPisdeclara&ve--worriesaboutwhatistobecomputedratherthanhowitistobecomputed.
FP• ThereisafocusonLIStProcessing.
– Listsareo\enusedwithrecursiononsub-listsasasubs&tuteforloops.
• "Pure"func&onallanguageseschewside-effects.– Nostatements
– Noassignment– Nostate– Noassigningfirstone,thenanothervaluetothesamevariabletotracktheprogramstate.
– oneprogramisoneexpression(plussuppor&ngdefini&ons).
4
5
History
• Func&onalprogrammingbeganinthelate1950s.Thereweremanydialects,star&ngwithLISP1.5(1960),throughScheme(1975)toCommonLISP(1985).
– Lisp(1958)àscheme(1975)àcommonLisp(1985)àschemeRRS(1998)– LISP=LIStProcessor– SchemeissimplerthanLisp
– Schemespecifica&onisabout50pages,comparedtoCommonLisp's1300pagedra\standard.
• Anothercategoryoffunc&onalprogramminglanguagesareML(1973)àMiranda(1982)àHaskell(1987).
• FPISalive– XSLTalsohascharacteris&csoffunc&onalprogramming– MAPREDUCE– Python
• Themathema&calbasisofmanyfunc&onalprogramminglanguagesisλ-calculus.Itallowsexpressionsthathavefunc&onsasvalues.
6
RunSchemeinterpreterkawa• kawaisanSchemeinterpreterwrijeninJava• Alterna&vely,youcanuseotherimplementa&ons.
– DrSchemeisagoodone.Ithasdetaileddebugginginforma&on.hjp://www.plt-scheme.org/so\ware/drscheme/
• Downloadkawajarfile– \p://\p.gnu.org/pub/gnu/kawa/kawa-1.9.90.jar
• StartKawaby:
C:\440>java-jarkawa-1.9.90.jarkawa.repl
• TrythefollowingprogramsinKawa
> "hello world"
hello world
> (+ 2 3) 5 >(exit)
• Alsoinstalledinourschoolunixsystemluna:~>kawa#|kawa:1|#(+23)5
7
Runschemeprogramsinafile
• Insteadofwri&ngeverythingattheSchemeprompt,youcan:– writeyourfunc&ondefini&onsandyourglobalvariabledefini&ons(define...)inafile("file_name")
– attheSchemeprompt,loadthefilewith: (load"file_name")
– attheSchemepromptcallthedesiredfunc&ons
– thereisno"formal"mainfunc&on
8
TheStructureofaSchemeProgram
• Allprogramsanddataareexpressions
• Expressionscanbeatomsorlists
• Atom:number,string,iden&fier,character,boolean– E.g. "hello world" hello world
• List:sequenceofexpressionsseparatedbyspaces,betweenparentheses– E.g. (+ 2 3)
• Syntax:expression →atom|listatom →number|string|iden&fier|character|booleanlist →(expr_seq)expr_seq →expressionexpr_seq|expression
9
Interac&ngwithScheme
• Interpreter:"read-eval-print"loop>11
– Reads1,evaluatesit(1evaluatestoitself),thenprintsitsvalue
>(+23)5
+=>func&on+
2=>2
3=>3
Appliesfunc&on+onoperands2and3=>5
10
Evalua&on
• Constantatoms-evaluatetothemselves42 -anumber
3.14-anothernumber
"hello" -astring
‘a‘ -character'a'
#t -booleanvalue"true"
>"helloworld"
helloworld
11
Evalua&onofiden&fiers• Iden&fiers(symbols)-evaluatetothevalueboundtothem
(definea7)>a7
>(+a5)=>12
>++>x1=>error
12
Evaluatelists
• Lists-evaluateas"func&oncalls":(func&onarg1arg2arg3...)
• Firstelementmustevaluatetoafunc&on
• Recursivelyevaluateeachargument
• Applythefunc&onontheevaluatedarguments>(-71)
6
>(*(+23)(/62))
15
>
13
Operators
• Prefixnota&on• Anynumberofarguments
>(+)
0
>(+2)
2
>(+23)
5
>(+234)
9
>(-1072)
1
>(/2052)
2
14
Preven&ngEvalua&on(quote)
• Evaluatethefollowing:>(123);Error:ajempttoapplynon-procedure1.
• Usethequotetopreventevalua&on:>(quote(123))
(123)
• Short-handnota&onforquote:>'(123)
(123)
16
Forcingevalua&on
(+123) =>6
'(+123) =>(+123)
(eval'(+123)) =>6
• evalevaluatesitssingleargument
• evalisimplicitlycalledbytheinterpretertoevaluateeachexpressionentered:
“read-eval-print”loop
17
Listopera&ons
• SchemecomesfromLISP,LIStProcessing
• Listopera&ons:cons,car,cdr,…• cons–constructalistfromheadandtail
(cons'a'(bcd)) =>(abcd)
(cons'a'()) =>(a)
(cons'(ab)'(cd)) =>
((ab)cd)
(cons'a(cons'b'())) =>
(ab)
18
Listopera&ons
• car–returnsfirstmemberofalist(head)(car'(abcd)) =>a(car'(a)) =>a(car'((ab)cd)) => (ab)
(car'(this(isno)moredifficult)) => this
• cdr–returnsthelistwithoutitsfirstmember(tail)(cdr'(abcd)) =>(bcd)(cdr'(ab)) =>(b)(cdr'(a)) => ()
(cdr'(a(bc))) => (bc)? ((bc))
(car(cdr(cdr'(abcd)))) => c
(car(car'((ab)(cd))))è a
19
listopera&ons• null?–returns#tifthelistisnull() #fotherwise
(null?()) =>#t
• list–returnsalistbuiltfromitsarguments(list'a'b'c) =>(abc)(list'a) =>(a)(list'(abc))=> ((abc))
(list'(ab)'c)=> ((ab)c)
(list'(ab)'(cd)) => ((ab)(cd))
(list'(+21)(+21)) => ((+21)3)
20
Listopera&ons
• length–returnsthelengthofalist(length'(1357)) =>4(length'((ab)c)) => 2
• reverse–returnsthelistreversed(reverse'(1357)) =>(7531)(reverse'((ab)c)) => (c(ab))
• append–returnstheconcatena&onofthelistsreceivedasarguments(append'(135)'(79))=>(13579)(append'(a)'()) =>(a)
(append'(ab)'((cd)e)) => (ab(cd)e)
21
TypePredicates
• Checkthetypeoftheargumentandreturn#tor#f(boolean?x) ;isxaboolean?
(char?x) ;isxachar?– (char?#\a) =>#t– Charactersarewrijenusingthenota&on#\<character>
(string?x) ;isxastring?(string?“xyx”) =>#t
(number?x) ;isxanumber?(number?2) =>#t
(list?x) ;isxalist?
(procedure?x);isxaprocedure?
(procedure?car)=>#t
22
BooleanExpression
(<12) =>#t
(>=34) =>#f
(=44) =>#t
(eq?22) =>#t
(eq?'(ab)'(ab)) =>#f
(equal?22)=>#t
(equal?'(ab)'(ab)) =>#t;recursivelyequivalent
– "eq?"returns#tifitsparametersrepresentthesamedataobjectinmemory;
– equal?comparesdatastructuressuchaslists,vectorsandstringstodetermineiftheyhavecongruentstructureandequivalentcontents
(not(>56)) =>#t
(and(<34)(=23)) =>#f
(or(<34)(=23)) =>#t
23
Condi&onalExpressions
• if–hastheform:(if<test_exp><then_exp><else_exp>)(if(<56)12) =>1
(if(<43)12) =>2
Recallthejavaexpression(x<y)?1:2
• Anythingotherthan#fistreatedastrue:(if345) =>4
(if'()45) =>4
Itisnotatyped-language
• ifisaspecialform-evaluatesitsargumentsonlywhenneeded(lazyevalua&on):(if(=34)1(2)) =>Error
(if(=33)1(2)) =>1
24
Condi&onexpression
• cond–hastheform:(cond(<test_exp1><exp1>...)(<test_exp2><exp2>...)...(else<exp>...))
(definen-5)(cond((<n0)"nega&ve")((>n0)"posi&ve")(else"zero")) =>"nega&ve"
25
Recursivedefini&on
• HowdoyouTHINKrecursively?• Example:definefactorial
factorial(n)=1*2*3*...(n-1)*n
factorial(n-1)
1 ifn=1 (thebasecase)
factorial(n)=
n*factorial(n-1) otherwise(induc&vestep)
27
Fibonacciexample
• Fibonacci:
0 ifn=0
fib(n)= 1 ifn=1 fib(n-1)+fib(n-2) otherwise
• ImplementinScheme:(define(fibn)(cond((=n0)0)((=n1)1)(else(+(fib(-n1))(fib(-n2))))))
28
Lengthexample
• Lengthofalist: 0 iflistisempty
len(lst)=
1+len(lst-without-first-element)otherwise
• ImplementinScheme:(define(lenlst)(if(null?lst)0
(+1(len(cdrlst)))))
|(length (a b c d)) | (length (b c d)) | |(length (c d)) | | (length (d)) | | |(length ()) | | |0 | | 1 | |2 | 3
|4
29
Sumexample
• Sumofelementsinalistofnumbers:(sum‘(123))=>6
0 iflistisempty
sum(lst)=
first-element+sum(lst-without-first-element)otherwise
• ImplementinScheme:(define(sumlst)
(if(null?lst)0(+(carlst)(sum(cdrlst)))))
30
Memberexample
• Checkmembershipinalist:(define(member?xlst)(cond
((null?lst)#f) ((equal?x(carlst))#t) (else(member?x(cdrlst)))))
31
Recursion
• Whenrecurringonalistlst,– asktwoques&onsaboutit:(null?lst)andelse– makeyourrecursivecallon(cdrlst)
• Whenrecurringonanumbern,– asktwoques&onsaboutit:(=n0)andelse– makeyourrecursivecallon(-n1)
32
Localdefini&on
• let-hasalistofbindingsandabody– eachbindingassociatesanametoavalue– bindingsarelocal(visibleonlyinthebodyoflet)– letreturnsthelastexpressioninthebody
>(let((a2)(b3)) ;listofbindings(+ab)) ;body-expressiontoevaluate5
>(+ab) =>error>a =>Error:variableaisnotbound.>b =>Error:variablebisnotbound.
No&cethescopeofaandbiswithinthebodyoflet.
33
Let• Factoroutcommonsub-expressions:
f(x,y)=x(1+xy)2+y(1-y)+(1+xy)(1-y)a=1+xyb=1-yf(x,y)=xa2+yb+ab
• Locallydefinethecommonsub-expressions:(define(fxy) (let((a(+1(*xy)))(b(-1y)))(+(*xaa)(*yb)(*ab))))
(f12) =>4
34
‘let’candefinefunc&ons
– (let((f+))(f23))=>
5
– (let((f+)(x2))(fx3))=>5
– (let((f+)(x2)(y3))(fxy))=>
5
• Thevariablesboundbyletarevisibleonlywithinthebodyofthelet– (let((+*))(+23))
6(+23)=>
5
35
Inputandoutput
• read-returnstheinputfromthekeyboard>(read)234 ;usertypesthis234 ;thereadfunc&onreturnsthis>(+2(read))3 ;userinput5 ;result
• display-printsitssingleparametertothescreen>(display"helloworld")helloworld>(definex2)>(displayx)2
• newline-displaysanewline
36
Inputandoutput
• Defineafunc&onthatasksforinput:
(define(ask-themstr)(displaystr)
(read))>(ask-them"Howoldareyou?")Howoldareyou?2222
37
InputandOutput
• Defineafunc&onthatasksforanumber(ifit’snotanumberitkeepsasking):
(define(ask-number)(display"Enteranumber:")(let((n(read)))
(if(number?n) n (ask-number))))
>(ask-number)Enteranumber:aEnteranumber:(56)Enteranumber:"Whydon'tyoulikethese?“Enteranumber:77
38
Interac&vefactorialprogram• Anouter-levelfunc&ontogowithfactorial,thatreadstheinput,computesthefactorialanddisplaystheresult:
(define(factorial-interac&ve)(display"Enteraninteger:")(let((n(read)))(display"Thefactorialof")(displayn)(display"is")(display(factorialn))(newline)))
>(factorial-interac&ve)Enteraninteger:4Thefactorialof4is24
39
Higherorderfunc&ons
• Afunc&oniscalledahigher-orderfunc&onifittakesafunc&onasaparameter,orreturnsafunc&onasaresult
• InScheme,afunc&onisafirst-classobject–itcanbepassedasanargumenttoanotherfunc&on,itcanbereturnedasaresultfromanotherfunc&on,anditcanbecreateddynamically(let((f+))(f23))
40
Examplesofhigher-orderfunc&ons• map
– Takesasargumentsafunc&onandasequenceoflists– Theremustbeasmanylistsasargumentsofthefunc&on,andlistsmusthavethesamelength
– Appliesthefunc&ononcorrespondingsetsofelementsfromthelists– Returnsalltheresultsinalist
f(E1E2......En)→((fE1)(fE2)......(fEn))
(define(squarex)(*xx))(mapsquare'(12345)) =>(1491625)
– (mapabs'(1-23-45-6))=>(123456)
– (map+'(123)'(456)) =>(579)
41
lambdaexpression
• Youcanalsodefinethefunc&onin-place:(map(lambda(x)(*2x))'(123)) =>(246)
– (map(lambda(xy)(*xy))'(1234)'(8765))=>
(8141820)
• Asimpleversionofmapdefini&on(define(mapFLst)(if(null?Lst)Lst(cons(F(carLst))(mapF(cdrLst)))))
42
Lambdaexpression
• Alambdaexpression(lambdaabstrac&on)definesafunc&oninScheme.
• Informally,thesyntaxis:(lambda (<parameters>) <body>)
• Forexample:(define addOne (lambda (p) (+ p 1)))
it has the same effect as: (define (addOne p) (+ p 1))
LogoforRacket,afunc&onallanguagebasedonScheme
43
Higherorderfunc&on:reduce(alsocalledfold)
• F:abinaryopera&on,thatis,atwo-argumentfunc&on.
• E0:aconstant.• Wewanttoexpressthefollowingtransforma&on:
(E1E2......En)=>E0FE1FE2F......FEn
• inschemenota&on:(E1E2......En)=>(FE0(FE1(F......(FEn-1Fn)......)))
(define (reduce F E0 L) (if (null? L) E0 (F (car L) (reduce F E0 (cdr L)))
) )
• Example: – (reduce * 1 '(1 2 3 4)) – è 1*1*2*3*4
44
exercise:whatistheresultofthisexpression?
(reduce+0(map(lambda(x)1)‘(123)))
Differentwaystodefinelengthfunc&on(define(lenlst)(if(null?lst)0(+1(len(cdrlst)))))
(definelen(lambda(lst)(if(null?lst)0(+1(len(cdrlst))))))(definelen(lambda(lst)(reduce+0(map(lambda(x)1)lst))))
45
Higherorderfunc&on:apply
• apply– takesafunc&onandalist– theremustbeasmanyelementsinthelistasargumentsofthefunc&on
– appliesthefunc&onwiththeelementsinthelistasarguments(apply*'(56)) =>30(applyappend'((ab)(cd)))=>(abcd)
• Comparisontoeval:(eval<expression>)or(eval(<func><arg1><arg2>...))
(apply<func>(<arg1><arg2>...))
46
Higherorderfunc&on:compose
• Composetakestwofunc&onsasparameters.
• Italsoreturnsafunc&on(define(composefg)(lambda(x) (f(gx))))
((composecarcdr)'(123))=>
2
((compose(lambda(x)(+1x))(lambda(x)(*2x)))5)=>11
47
Definereversefunc&on
(definereverse(lambda(L)
(if(null?L)
'()
(append(reverse(cdrL))(list(carL))))))
48
> ( define ( append L1 L2 ) ; built-in! (if ( null? L1 ) L2 ( cons ( car L1 ) ( append ( cdr L1 ) L2 ) ) ) )
> ( append '( ab bc cd ) '( de ef fg gh ) ) => (ab bc cd de ef fg gh)
Appendexample
49
> ( define ( numberList? x ) ( cond ( ( not ( list? x ) ) #f ) ( ( null? x ) #t ) ( ( not ( number? ( car x ) ) ) #f ) ( else ( numberList? ( cdr x ) ) ) ) ) > ( numberList? ' ( 1 2 3 4 ) ) #t > ( numberList? ' ( 1 2 3 bad 4 ) ) #f
Numberlistexample
50
Inser&onsortexample
(define(insertxl)
(if(null?l)
(listx)
(if(<=x(carl))
(consxl)
(cons(carl)(insertx(cdrl))))))
(define(isortl)
(if(null?l)
()
(insert(carl)(isort(cdrl)))))
Inser&onsortinanimpera&velanguagevoidisort(int[]A){
intj;
for(inti=1;i<A.length;i++){
inta=A[i];
for(j=i-1;j>=0&&A[j]>a;j--)
A[j+1]=A[j];
A[j+1]=a;
}
}
DFAsimula&on
• Startstate:q0• Transi&ons
((q00)q2)((q01)q1)((q10)q3)((q11)q0)
((q20)q0)((q21)q3)((q30)q1)((q31)q2)
• Finalstate:q0• DFA
'(q0
(((q00)q2)((q01)q1)((q10)q3)((q11)q0)
((q20)q0)((q21)q3)((q30)q1)((q31)q2))
(q0))
51
Definemovefunc&on
52
(definemove
(lambda(dfasymbol)
(let((curstate(cardfa))(trans(cadrdfa))
(finals(caddrdfa)))
(list
(if(eq?curstate'error) ;getthenextstateor‘error
'error
(let((pair(assoc(listcurstatesymbol)trans)))
;pairisthenextstate,say((q0,0),q2),orfalsewhennotfound
(ifpair(cadrpair)'error)));booleancondistrueifnotfalse
trans
finals))))
• cadr:carandcdr.Secondelement
• caddr:thirdelement
• assoc:searchanelementinanassocia&onlist
'(q0
(((q00)q2)((q01)q1)((q10)q3)((q11)q0)
((q20)q0)((q21)q3)((q30)q1)((q31)q2))
(q0))
assocfunc&on
• assoc:searchanassocia&onlist(table)– Anassocia&onlistisalistoflists.– Eachsublistrepresentsanassocia&onbetweenakeyandalistofvalues.
• Examples– Scheme>(assoc'julie'((paulaugust22)(juliefeb9)(veroniquemarch28)))
– (juliefeb9)
– Scheme>(assoc'key2'((key1val1)(key2val2)(key0val0)))– (key2val2)
– Scheme>(assoc'(feb9)'(((aug1)maggiephil)((feb9)jimheloise)((jan6)declan)))
– ((feb9)jimheloise)
– (assoc(listcurstatesymbol)trans)
– (assoc‘(q00)trans)à((q0,0),q2)
53
Simulatefunc&on
(definesimulate
(lambda(dfainput)
(cons(cardfa)
(if(null?input)
(if(infinal?dfa)'(accept)'(reject))
(simulate(movedfa(carinput))(cdrinput))))))
• Runtheprogram(simulate
'(q0
(((q00)q2)((q01)q1)((q10)q3)((q11)q0)
((q20)q0)((q21)q3)((q30)q1)((q31)q2))
(q0))
'(010010))
• Output:thetraceofthestatesand‘accept’or‘reject’(q0q2q3q1q3q2q0accept)
54
infinalstatefunc&on(defineinfinal?
(lambda(dfa)
(memq(cardfa)(caddrdfa))))
• dfa'(q0
(((q00)q2)((q01)q1)((q10)q3)((q11)q0)
((q20)q0)((q21)q3)((q30)q1)((q31)q2))
(q0))
• memq:returnthefirstsublistoflistwhosecarisobj.Ifobjdoesnotoccurinlist,then#f(nottheemptylist)isreturned
– memq'a'(abc))==>(abc)
– (memq'b'(abc))==>(bc)
– (memq'a'(bcd))==>#f
55
56
Assignment
• acalculatorforsimplearithme&cexpressions– whentyping(calculator'(1+2)),schemeinterpreterwillprint3.
• Thecalculatorwillacceptexpressionofanylength,andtheexpressionassociatestotheright.
– In(calculator'(1+1-2+3)),theexpressionisinterpretedas(1+(1-(2+3))),hencethevalueis-3.
• Onebonusmarkforle\associa&on1+1-2+3isevaluatedas3
57
Interpreterandcompiler
• Interpreter– Programisexecuteddirectly.Notranslatedcodeisgenerated.
– Slow– Forsmallprograms
• Compiler– Programistranslatedintocodethatisclosertomachine(intermediatecode,orassemblycode,ormachinecode)
– Faster– Forbiggerprograms
– hybridimplementa&onforJavaandC#