Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are...

49
Func%onal Programming in Scheme and Lisp

Transcript of Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are...

Page 1: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Func%onalProgramminginSchemeandLisp

Page 2: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Overview

•  Inafunc(onalprogramminglanguage,func(onsarefirstclassobjects.

•  Youcancreatethem,putthemindatastructures,composethem,specializethem,applythemtoarguments,etc.

•  We’lllookathowfunc(onalprogrammingthingsaredoneinLisp

Page 3: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

eval• Remember:Lispcodeisjustans‐expression

•  YoucancallLisp’sevalua(onprocesswiththeevalfunc(on.

 (defines(list‘cadr’(onetwothree))) s (CADR'(ONETWOTHREE))>(evals)

TWO>(eval(list'cdr(car'((quote(a.b))c))))B

Page 4: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Apply• Applytakesafunc(onandalistofargumentsforit,andreturnstheresultofapplyingthefunc(ontothearguments:

>(apply+‘(123))6

•  Itcanbegivenanynumberofarguments,solongasthelastisalist:

>(apply+12‘(345))15

• Asimpleversionofapplycouldbewri]enas(define(applyflist)(eval(consflist)))

Page 5: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Lambda

• Thedefinespecialformcreatesafunc(onandgivesitaname.

• However,func(onsdon’thavetohavenames,andwedon’tneeddefinetodefinethem.• Wecanrefertofunc(onsliterallybyusingalambdaexpression.

Page 6: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Lambdaexpression• Alambdaexpressionisalistcontainingthesymbollambda,followedbyalistofparameters,followedbyabodyofzeroormoreexpressions:

>(definef(lambda(x)(+x2)))

>f

#<proceedure:f>

>(f100)

102

Page 7: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Lambdaexpression•  Alambdaexpressionisaspecialform•  Whenevaluated,itcreatesafunc(onandreturnsareferencetoit

•  Thefunc(ondoesnothaveaname•  alambdaexpressioncanbethefirstelementofafunc(oncall:>((lambda(x)(+x100))1)101

•  Otherlanguageslikepythonandjavascripthaveadoptedtheidea

Page 8: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

definevs.define

(define(add2x)(+x2))

(defineadd2(lambda(x)(+x2)))

(defineadd2#f)

(set!add2(lambda(x)(+x2)))

•  The define special form comes in two varieties

•  The three expressions to the right are entirely equivalent

•  The first define form is just more familiar and convenient when defining a function

Page 9: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Mappingfunc%ons•  CommonLispandSchemeprovidesseveralmappingfunc(ons•  map(mapcarinLisp)isthemostfrequentlyused.•  Ittakesafunc(onandoneormorelists,andreturnstheresultofapplyingthefunc(ontoelementstakenfromeachlist,un(loneofthelistsrunsout:

>(mapabs'(3‐42‐5‐6))(34256)>(mapcons'(abc)'(123))((a.1)(b.2)(c.3))>(map(lambda(x)(+x10))‘(123))(111213)>(maplist‘(abc)‘(1234))map:alllistsmusthavesamesize;argumentswere:#<procedure:list>(12)(abc)

Page 10: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Definingmap

•  Definingasimple“oneargument”versionofmapiseasy

(define(map1funclist)(if(null?list)

null

(cons(func(firstlist))(map1func(restlist)))))

Page 11: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

DefineLisp’sEveryandSome

• everyandsometakeapredicateandoneormoresequences• Whengivenjustonesequence,theytestwhethertheelementssa(sfythepredicate: (everyodd?‘(135)) #t (someeven?‘(123)) #t

•  Ifgiven>1sequences,thepredicatetakesasmanyargsastherearesequencesandargsaredrawnoneata(mefromthem: (every>‘(135)‘(024)) #t

Page 12: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

every

(define(everyflist)

;;notetheuseoftheandfunc(on

(if(null?list)

#t

(and(f(firstlist))

(everyf(restlist)))))

Page 13: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

some

(define(someflist)

(if(null?list)

#f(or(f(firstlist))

(somef(restlist)))))

Page 14: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Willthiswork?

(define(someflist)

(not(every(lambda(x)(not(fx)))list)))

Page 15: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

filter

(filter<f><list>)returnsalistoftheelementsof<list>whichsa(sfythepredicate<f>

>(filterodd?‘(012345))

(135)

>(filter(lambda(x)(>x98.6))

‘(101.198.698.199.4102.2))

(101.199.4102.2)

Page 16: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Example:filter(define(myfilterlistfunc);;returnsalistofelementsoflistwherefunc(onistrue

(cond((null?list)nil)((func(firstlist))(cons(firstlist)(myfilter(restlist)func)))(#t(myfilter(restlist)func))))

>(myfilter‘(1234567)even?)(246)

Page 17: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Example:filter•  Defineintegersasafunc(onthatreturnsalistofintegersbetweenaminandmax

(define(integersminmax)(if(>minmax)empty(consmin(integers(add1min)max))))

•  Andprime?asapredicatethatistrueofprimenumbersandfalseotherwise

>(filterprime?(integers220))(235711131719)

Page 18: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Here’sanotherpaJern•  Weojenwanttodosomethinglikesumtheelementsofasequence

(define(sum‐listl)(if(null?l)

0(+(firstl)(sum‐list(restl)))))

•  Andother(meswewanttheirproduct(define(mul(ply‐listl)

(if(null?l)1

(*(firstl)(mul(ply‐list(restl)))))

Page 19: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Here’sanotherpaJern•  Weojenwanttodosomethinglikesumtheelementsofasequence

(define(sum‐listl)(if(null?l)

0(+(firstl)(sum‐list(restl)))))

•  Andother(meswewanttheirproduct(define(mul(ply‐listl)

(if(null?l)1

(*(firstl)(mul(ply‐list(restl)))))

Page 20: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Example:reduce

 Reducetakes(i)afunc(on,(ii)afinalvalue,and(iii)alist

 Reduce(+0(v1v2v3…vn))isjustV1+V2+V3+…Vn+0

 InScheme/Lispnota(on:>(reduce+0‘(12345))15

(reduce*1‘(12345))120

Page 21: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Example:reduce

(define(reducefunc(onfinallist)(if(null?list)

final

(func(on

(firstlist)

(reducefunc(onfinal(restlist)))))

Page 22: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Usingreduce(define(sum‐listlist);;returnsthesumofthelistelements

(reduce+0list))

(define(mul‐listlist)

;;returnsthesumofthelistelements

(reduce*1list))

(define(copy‐listlist)

;;copiesthetoplevelofalist(reducecons‘()list))

(define(append‐listlist)

;;appendsallofthesublistsinalist

(reduceappend‘()list))

Page 23: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose
Page 24: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Composingfunc%ons

>compose

#<procedure:compose>>(define(squarex)(*xx))>(define(doublex)(*x2))

>(square(double10))400>(double(square10))

200>(definesd(composesquaredouble))>(sd10)400

>((composedoublesquare)10)200

Page 25: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Here’showtodefineit

(define(my‐composef1f2)

(lambda(x)(f1(f2x))))

Page 26: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Variables,freeandbound

•  Inthisfunc(on,towhatdoesthevariableGOOGOLrefer?

(define(big‐number?x);;returnstrueifxisareallybignumber

(>xGOOGOL))•  ThescopeofthevariableXisjustthebodyofthefunc(onforwhichit’saparameter.

Page 27: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Here,GOOGOLisaglobalvariable

>(defineGOOGOL(expt10100))>GOOGOL

10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

>(define(big‐number?x)(>xGOOGOL))

>(big‐number?(add1(expt10100)))

#t

Page 28: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

WhichXisaccessedattheend?

>(defineGOOGOL(expt10100))

>GOOGOL10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

>(definex‐1)

>(define(big‐number?x)(>xGOOGOL))>(big‐number?(add1(expt10100)))#t

Page 29: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Variables,freeandbound

•  Inthebodyofthisfunc(on,wesaythatthevariable(orsymbol)XisboundandGOOGOLisfree.

(define(big‐number?x)

;returnstrueifXisareallybignumber

(>XGOOGOL))

•  Ifithasavalue,ithastobeboundsomewhereelse

Page 30: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Theletformcreateslocalvariables

>(let[(pi3.1415)(e2.7168)]

(big‐number?(exptpie)))

#f•  Thegeneralformis(let<varlist>.<body>)•  Itcreatesalocalenvironment,bindingthevariablestotheirini(alvalues,andevaluatestheexpressionsin<body>

Note: square brackets are line parens, but only match other square brackets. They are there to help you cope with paren fatigue.

Page 31: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Letcreatesablockofexpressions

(if(>ab)

(let()

(prins"aisbiggerthanb.~n")(prins"bissmallerthana.~n")

#t)#f)

Page 32: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Letisjustsyntac%csugarforlambda

(let[(pi3.1415)(e2.7168)](big‐number?(exptpie)))

((lambda(pie)(big‐number?(exptpie)))

3.1415

2.7168)

andthisishowwediditbackbefore~1973

Page 33: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Letisjustsyntac%csugarforlambda

Whathappenshere:

(definex2)

(let[(x10)(xx(*x2))]

(prins"xis~sandxxis~s.~n"xxx))

Page 34: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Letisjustsyntac%csugarforlambda

Whathappenshere:

(definex2)

((lambda(xxx)(prins"xis~sandxxis~s.~n"xxx))10

(*2x))

Page 35: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Letisjustsyntac%csugarforlambda

Whathappenshere:

(definex2)

(define(f000034xxx)(prins"xis~sandxxis~s.~n"xxx))

(f00003410(*2x))

Page 36: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

letandlet*

•  Theletspecialformevaluatesalloftheini(alvalueexpressions,andthencreatesanewenvironmentinwhichthelocalvariablesareboundtothem,“inparallel”

•  Thelet*formdoesissequen(ally

•  let*expandstoaseriesofnestedlets– (let*[(x100)(xx(*2x))](fooxxx))– (let[(x100)](let[(xx(*2x))](fooxxx)))

Page 37: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Whathappenshere?

>(defineX10)>(let[(X(*XX))](prins"Xis~s.~n"X)(set!X1000)(prins"Xis~s.~n"X)‐1)

???

>X

???

Page 38: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Whathappenshere?

>(defineX10) (let[(X(*XX))](prins“Xis~s\n”X)(set!X1000)(prins“Xis~s\n”X)‐1)

Xis100

Xis1000

‐1

>X10

Page 39: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Whathappenshere?

>(defineGOOGOL(expt10100))>(define(big‐number?x)(>xGOOGOL))

>(let[(GOOGOL(expt10101))]

(big‐number?(add1(expt10100))))

???

Page 40: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Whathappenshere?

>(defineGOOGOL(expt10100))>(define(big‐number?x)(>xGOOGOL))>(let[(GOOGOL(expt10101))](big‐number?(add1(expt10100))))#t•  ThefreevariableGOOGOLislookedupintheenvironmentinwhichthebig‐number?Func(onwasdefined!

Page 41: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

func%ons•  Notethatasimpleno(onofafunc(oncangiveusthemachineryfor– Crea(ngablockofcodewithasequenceofexpressionstobeevaluatedinorder

– Crea(ngablockofcodewithoneormorelocalvariables

•  Func(onalprogramminglanguageistousefunc(onstoprovideotherfamiliarconstructs(e.g.,objects)

•  Andalsoconstructsthatareunfamiliar

Page 42: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Dynamicvs.Sta%cScoping

•  Programminglanguageseitherusedynamicorsta(c(akalexical)scoping

•  Inasta(callyscopedlanguage,freevariablesinfunc(onsarelookedupintheenvironmentinwhichthefunc(onisdefined

•  Inadynamicallyscopedlanguage,freevariablesarelookedupintheenvironmentinwhichthefunc(oniscalled

Page 43: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Closures

•  Lispisalexicallyscopedlanguage.•  Freevariablesreferencedinafunc(onthosearelookedupintheenvironmentinwhichthefunc(onisdefined.Freevariablesarethoseafunc(on(orblock)doesn’tcreatescopefor.

•  Aclosureisafunc(onthatrememberstheenvironmentinwhichitwascreated

•  Anenvironmentisjustacollec(onofvariablebindingsandtheirvalues.

Page 44: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Closureexample>(define(make‐counter)(let((count0))(lambda()(set!count(add1count)))))>(definec1(make‐counter))>(definec2(make‐counter))>(c1)1>(c1)2>(c1)3>(c2)???

Page 45: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Afanciermake‐counter

Writeafanciermake‐counterfunc(onthattakesanop(onalargumentthatspecifiestheincrement>(defineby1(make‐counter))

>(defineby2(make‐counter2))>(definedecrement(make‐counter‐1))

>(by2)2

(by2)

4

Page 46: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Op%onalargumentsinScheme

(define(make‐counter.args);;argsisboundtoalistoftheactualargumentspassedtothe

func(on

(let[(count0)

(inc(if(null?args)1(firstargs)))]

(lambda()(set!count(+countinc)))))

Page 47: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

KeywordargumentsinScheme

•  Scheme,likeLisp,alsohasawaytodefinefunc(onsthattakekeywordarguments– (make‐counter)

– (make‐counter:ini(al100)– (make‐counter:increment‐1)– (make‐counter:ini(al10:increment‐2)•  DifferentSchemedialectshaveintroduceddifferentwaystomixposi(onalarguments,op(onalarguments,defaultvalues,keywordargument,etc.

Page 48: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose

Closuretricks

Wecanwriteseveralfunc(onsthatareclosedinthesameenvironment,whichcanthenprovideaprivatecommunica(onchannel

(definefoo#f)

(definebar#f)

(let((secret‐msg"none"))(set!foo(lambda(msg)(set!secret‐msgmsg)))

(set!bar(lambda()secret‐msg)))

(display(bar));prints"none"(newline)

(foo”a]ackatdawn")(display(bar));prints”a]ackatdawn"

Page 49: Funconal Programming in Scheme and Lisp · • In a funconal programming language, funcons are first class objects. • You can create them, put them in data structures, compose