Abstractions and small languages in synthesis CS294 : Program Synthesis for Everyone
1 Programming Languages Lecture 5 Scheme, Subroutines and Control Abstractions.
-
date post
22-Dec-2015 -
Category
Documents
-
view
221 -
download
1
Transcript of 1 Programming Languages Lecture 5 Scheme, Subroutines and Control Abstractions.
11
Programming LanguagesProgramming Languages
Lecture 5Lecture 5
Scheme, Subroutines and Scheme, Subroutines and Control AbstractionsControl Abstractions
22
Parameter PassingParameter Passing Definition: foo(int Definition: foo(int xx, int , int yy) ;) ;
xx and and yy are are formal parametersformal parameters Application: foo(Application: foo(aa, , bb););
a a and and bb are are actualactual parameters or parameters or argumentsarguments
Parameter Passing ModesParameter Passing Modes By ValueBy Value By ReferenceBy Reference By NameBy Name By Copy-In / Copy-OutBy Copy-In / Copy-Out
33
Pass by ValuePass by Value Formal parameter is bound to a ValueFormal parameter is bound to a Value
Value on stack may be:Value on stack may be: a copy of another valuea copy of another value
foo (x);foo (x); the result of an expressionthe result of an expression
foo (x + 1);foo (x + 1); Easy to implementEasy to implement May require copying large amounts of dataMay require copying large amounts of data
Which can sometimes be avoided with lazy copyWhich can sometimes be avoided with lazy copy
44
Pass by ReferencePass by Reference
Formal parameter is bound to a Formal parameter is bound to a locationlocation Value on stack is a pointer to the actual Value on stack is a pointer to the actual
valuevalue Avoids making a copy of the argumentAvoids making a copy of the argument Allows the procedure to modify the Allows the procedure to modify the
value of its parameters (But only if the value of its parameters (But only if the actual parameter is an l-value) actual parameter is an l-value)
55
Pass by NamePass by Name
Pass by name – Algol 60Pass by name – Algol 60 Actual parameters are (re)evaluated each Actual parameters are (re)evaluated each
time they are usedtime they are used Similar to treating parameters as macrosSimilar to treating parameters as macros Value on stack is a “thunk”, a hidden function Value on stack is a “thunk”, a hidden function
that evaluates the actual parameter.that evaluates the actual parameter. Expensive to implement and error prone.Expensive to implement and error prone. No longer used – Mainly of historical interestNo longer used – Mainly of historical interest
66
Copy-In/Copy-OutCopy-In/Copy-Out Subroutine can modify its parametersSubroutine can modify its parameters Both the value and address are placed on the stackBoth the value and address are placed on the stack The local value is used for computation then written The local value is used for computation then written
back to the original variable when the function back to the original variable when the function returnsreturns
Addresses Aliasing IssuesAddresses Aliasing Issues void foo(int x, int y){void foo(int x, int y){ x = 7;x = 7; y = y + 2; } y = y + 2; }
int main(){int main(){ int j = 3;int j = 3; foo(j, j); foo(j, j); Alias, x and y refer to same object Alias, x and y refer to same object print(j); } print(j); }
77
Parameters in ADAParameters in ADA In out parameters in AdaIn out parameters in Ada
function foo (function foo (inin a : Integer) returns Integer; a : Integer) returns Integer;procedure foo (procedure foo (inin a: Integer, a: Integer, outout b:Integer); b:Integer);Procedure foo (Procedure foo (in outin out a:Integer); a:Integer); Functions can only haveFunctions can only have in in parameters parameters
Scalars passed by copy-in/copy-outScalars passed by copy-in/copy-out Tagged arrays, tasks, etc. passed by referenceTagged arrays, tasks, etc. passed by reference Arrays and records implementation dependent Arrays and records implementation dependent
Named ParametersNamed Parametersfoo (a=>1);foo (a=>1);
Parameters with default valuesParameters with default valuesfunction Incr (base: integer; delt: integer := 1) return function Incr (base: integer; delt: integer := 1) return
integer;integer;
88
Parameter passing in CParameter passing in C C: parameter passing by value, no semantic C: parameter passing by value, no semantic
checks. Assignment to formal is assignment checks. Assignment to formal is assignment to local copyto local copy
If argument is pointer, effect is similar to If argument is pointer, effect is similar to passing designated object by referencepassing designated object by reference
voidvoid incr ( incr (intint* x) { (*x) ++; }* x) { (*x) ++; } incr (&counter); incr (&counter); /* pointer to counter*//* pointer to counter*/
no need to distinguish between functions no need to distinguish between functions and procedures: and procedures: voidvoid indicates side-effects indicates side-effects only.only.
99
Parameter-passing in C++Parameter-passing in C++
Default is by-value (same semantics as C)Default is by-value (same semantics as C) Explicit reference parameters:Explicit reference parameters:
voidvoid incr ( incr (intint& y) { y++};& y) { y++};
incr (counter); incr (counter);
// compiler knows profile of incr, builds // compiler knows profile of incr, builds referencereference
semantic intent indicated by qualifier:semantic intent indicated by qualifier:
voidvoid f ( f (constconst doubledouble& val);& val);
// in-parameter by reference: call cannot // in-parameter by reference: call cannot modify itmodify it
1010
Parameter-passing in JavaParameter-passing in Java
Parameters passed by value Parameters passed by value Semantics differs for Semantics differs for primitive typesprimitive types and for and for
classesclasses:: primitive types have value semanticsprimitive types have value semantics objects have reference semanticsobjects have reference semantics
ConsequenceConsequence: methods can modify objects.: methods can modify objects. No way to express semantic intent on primitive No way to express semantic intent on primitive
types: assignment allowed, affects local copy.types: assignment allowed, affects local copy.
1111
Parameter-passing in Parameter-passing in Functional LanguagesFunctional Languages
Strictly Functional languages have no Strictly Functional languages have no variables and no assignment, so…variables and no assignment, so…
Always use pass by value semanticsAlways use pass by value semantics Implementation may use references for Implementation may use references for
efficiencyefficiency Procedure can never modify argumentsProcedure can never modify arguments Remember, copying the actual Remember, copying the actual
parameter value to the formal is parameter value to the formal is initialization, not assignmentinitialization, not assignment
1212
AliasingAliasing varvar global : integer := 10;global : integer := 10; another : integer := 2;another : integer := 2; procedureprocedure confuse ( confuse ( varvar first, second : integer); first, second : integer); beginbegin first := first + global;first := first + global; second := first * second;second := first * second; endend;;beginbegin confuse (global, another); confuse (global, another); firstfirst and and globalglobal will be aliased will be aliased
Semantics should not depend on implementation of Semantics should not depend on implementation of parameter passingparameter passing
passing by value with copy-return is less error-pronepassing by value with copy-return is less error-prone
1313
Run-time organizationRun-time organization
Each subprogram invocation creates an Each subprogram invocation creates an activation record.activation record. RecursionRecursion imposes stack allocation (all languages today) imposes stack allocation (all languages today) Activation record hold actuals, linkage information, saved Activation record hold actuals, linkage information, saved
registers, local entities.registers, local entities. callercaller: place actuals on stack, return address, linkage : place actuals on stack, return address, linkage
information, then transfer control to information, then transfer control to calleecallee.. ProloguePrologue: save registers, allocate space for locals: save registers, allocate space for locals EpilogueEpilogue: place return value in register or stack position, : place return value in register or stack position,
update actuals, restore registers, then transfer control to caller.update actuals, restore registers, then transfer control to caller. Binding of locationsBinding of locations: actuals and locals are at fixed offsets from : actuals and locals are at fixed offsets from
frame pointersframe pointers complicationscomplications: variable no. of actuals, dynamic objects.: variable no. of actuals, dynamic objects.
1414
Activation record layoutActivation record layout
actual
actual
Return addr
Save area
Frame pointer
Stack pointer
local
localHandled by callee
Handled by caller
1515
Functions with variable Functions with variable number of parametersnumber of parameters
printf (“this is %d a format %d string”, x, y);printf (“this is %d a format %d string”, x, y); within body of printf, need to locate as many actuals as within body of printf, need to locate as many actuals as
place-holders in the format string.place-holders in the format string. SolutionSolution: place parameters on stack in reverse order. : place parameters on stack in reverse order.
ActualsActuals at at positive offsetpositive offset from FP, from FP, localslocals at at negative offsetnegative offset from FP.from FP.
actual nactual n
actual n-1actual n-1
… …
actual 1 (format string)actual 1 (format string)
return addressreturn address
1616
Objects of dynamic sizeObjects of dynamic size
declaredeclare
x : string (1..N); x : string (1..N); -- N global, non-constant-- N global, non-constant
y : string (1..N);y : string (1..N);
beginbegin...... where is the start of y in the activation record?where is the start of y in the activation record? Solution 1Solution 1: use indirection: activation record hold pointers. : use indirection: activation record hold pointers.
Simpler implementation, costly dynamic allocation., Simpler implementation, costly dynamic allocation., deallocationdeallocation..
solution 2:solution 2: local indirection: activation record holds offset local indirection: activation record holds offset into stack.into stack.
Faster allocation/deallocation, complex implementationFaster allocation/deallocation, complex implementation..
1717
Global linkageGlobal linkage
Static chainStatic chain: pointer to activation record of : pointer to activation record of statically enclosing scopestatically enclosing scope
Display:Display: array of pointers to activation records array of pointers to activation records does not work for function valuesdoes not work for function values
functional languages allocate activation functional languages allocate activation records on heaprecords on heap
may not work for pointers to functionsmay not work for pointers to functions simpler if there is no nesting (C, C++, Java)simpler if there is no nesting (C, C++, Java) can check static legality in many cases (Ada)can check static legality in many cases (Ada)
1818
Static LinksStatic Links
Activation record hold pointer to activation record Activation record hold pointer to activation record of enclosing scope. Setup as part of call prologue.of enclosing scope. Setup as part of call prologue.
outer outer
outer
inner
inner
inner
inner
To enclosing scopeTo retrieveentity 3 frames out: 3 dereference operations
1919
DisplayDisplay
Global array of pointers to current activation Global array of pointers to current activation recordsrecords
outer outer
outer
inner
inner
inner
inner
displayoutermost
...To retrieve entity 3 frames out: one indexing operation
2020
Subprogram parametersSubprogram parameters Caller can see parameter, therefore environment Caller can see parameter, therefore environment
of parameter is subset of current environment of parameter is subset of current environment Parameter is pair Parameter is pair (ptr to code, Env)(ptr to code, Env)
typetype proc proc is access procedureis access procedure (X : Integer); (X : Integer);
procedureprocedure Use_It (Helper : proc); Use_It (Helper : proc);
procedureprocedure Do_It (X : Integer) Do_It (X : Integer) isis … …
Use_It (Do_It’Use_It (Do_It’AccessAccess););
-- -- ‘Access creates pair (ptr to Do_It, environment of Do_It)‘Access creates pair (ptr to Do_It, environment of Do_It) simplest implementation if Env is pointer (simplest implementation if Env is pointer (static static
linklink)) Display more efficient to retrieve non-local entities, Display more efficient to retrieve non-local entities,
less efficient for subprogram parameters.less efficient for subprogram parameters.
2121
Subprogram parameters in Subprogram parameters in C/C++C/C++
voidvoid (*pf) (string); (*pf) (string);
// pf is a pointer to a function that takes a string // pf is a pointer to a function that takes a string argument and returns nothing (void).argument and returns nothing (void).
typedeftypedef voidvoid (*PROC)( (*PROC)(intint););
// type abbreviation clarifies syntax// type abbreviation clarifies syntax
voidvoid use_it (PROC); use_it (PROC);
PROC ptr = &do_it;PROC ptr = &do_it;
use_it (ptr);use_it (ptr);
use_it (&do_it);use_it (&do_it);
2222
Subprogram parameters in Subprogram parameters in JavaJava
No notion of pointer, so no immediate translationNo notion of pointer, so no immediate translation Dynamic dispatchingDynamic dispatching on a virtual method is on a virtual method is
indirect call, so can be obtained using indirect call, so can be obtained using interfacesinterfaces, , classesclasses, and , and extensionsextensions
Subprograms must be wrapped in classes, e.g. Subprograms must be wrapped in classes, e.g. Comparator, etc. Comparator, etc.
2323
The limits of stack allocationThe limits of stack allocation
typetype ptr ptr is access functionis access function (x : integer) (x : integer) returnreturn integer; integer;
functionfunction make_incr (x : integer) make_incr (x : integer) returnreturn ptr ptr isis
functionfunction new_incr (base : integer) new_incr (base : integer) returnreturn integer integer isis
begin begin
returnreturn base + x; base + x; -- reference to formal of -- reference to formal of make_incrmake_incr
endend;;
beginbegin
returnreturn new_incr’access; -- will it work? new_incr’access; -- will it work?
endend;;
add_five: ptr := make_incr (5);add_five: ptr := make_incr (5);
total : integer := add_five (10); total : integer := add_five (10); -- where does add_five find x ?-- where does add_five find x ?
2424
Heap allocation of activation Heap allocation of activation record record
General implementation of First-Order functions General implementation of First-Order functions requires that the environment of definition of the requires that the environment of definition of the function must be preserved until the point of call: function must be preserved until the point of call: activation record cannot be reclaimed if it creates activation record cannot be reclaimed if it creates functions.functions.
Functional languages require more complex run-Functional languages require more complex run-time management.time management.
Higher-order functionsHigher-order functions: functions that return : functions that return (build) functions, are powerful but complex (build) functions, are powerful but complex mechanisms. Imperative languages restrict their mechanisms. Imperative languages restrict their use.use.
A function that returns a pointer to a function A function that returns a pointer to a function is a is a higher-order function.higher-order function.
2525
Higher-order functionsHigher-order functions
Both arguments and result can be (pointers to) Both arguments and result can be (pointers to) subprograms:subprograms:
typetype Func Func is access functionis access function (x : integer) return integer; (x : integer) return integer;
functionfunction compose (first, second : Func) compose (first, second : Func) returnreturn Func Func isis
beginbegin
functionfunction result (x : integer) result (x : integer) returnreturn integer integer isis
beginbegin
returnreturn (second (first (x)); (second (first (x)); -- implicit dereference on call-- implicit dereference on call
endend; ; -- in C++ as well-- in C++ as well..
beginbegin
returnreturn result ’access; result ’access; -- but first and second won’t exist at the -- but first and second won’t exist at the pointpoint
endend; ; -- of call, so -- of call, so illegal in Adaillegal in Ada..
2626
Restricting higher-order Restricting higher-order functionsfunctions
CC: no nested definitions, so environment is always : no nested definitions, so environment is always global.global.
C++:C++: ditto, except for nested classes. ditto, except for nested classes. AdaAda: static checks to reject possible dangling : static checks to reject possible dangling
referencesreferences ModulaModula: pointers to function illegal if function not : pointers to function illegal if function not
declared at top-level.declared at top-level. LISPLISP: special syntax to indicate capture of : special syntax to indicate capture of
environmentenvironment ML, HaskellML, Haskell: no restriction: : no restriction: composecompose is a primitive is a primitive
2727
Returning composite valuesReturning composite values
Intermediate problem: functions that return values of Intermediate problem: functions that return values of non-static sizes:non-static sizes:
functionfunction conc3 (x, y, z : string) conc3 (x, y, z : string) returnreturn string string isis
beginbegin
returnreturn x & “:” & y & “:” & z; x & “:” & y & “:” & z;
endend;; example : string := conc3 (this, that, theother);example : string := conc3 (this, that, theother);
best not to use heap explicitly, but still need best not to use heap explicitly, but still need indirection.indirection.
SimplestSimplest : forbid it (Pascal, C) or use heap : forbid it (Pascal, C) or use heap automatically (Java)automatically (Java)
2828
Evaluation OrderEvaluation Order ““Normal Order” (Lazy) Evaluation – HaskellNormal Order” (Lazy) Evaluation – Haskell
Arguments are not evaluated unless and until Arguments are not evaluated unless and until they are actually neededthey are actually needed
Allows functions that define infinite lists!Allows functions that define infinite lists!(define naturals(define naturals (letrec ((next n) (cons n (delay (next (+ n 1))))))) (next (letrec ((next n) (cons n (delay (next (+ n 1))))))) (next
1)))1)))(define head car)(define head car)(define (tail stream) (force (cdr stream))))(define (tail stream) (force (cdr stream)))) Scheme uses Scheme uses delaydelay and and forceforce to do lazy evaluation to do lazy evaluation
Applicative Order Evaluation Applicative Order Evaluation Arguments are evaluated prior to execution of Arguments are evaluated prior to execution of
the function, whether they will be needed or not.the function, whether they will be needed or not.
2929
Lambda CalculusLambda Calculus Developed by Alonzo Church in 1930’s to Developed by Alonzo Church in 1930’s to
examine formal properties of examine formal properties of computabilitycomputability
Function Definition: Function Definition: x.Mx.M x is the formal parameterx is the formal parameter M is an expression on xM is an expression on x
Function ApplicationFunction Application x.M Nx.M N
ExamplesExamples x.x – identityx.x – identity x.times x x – squarex.times x x – square x.x.y.sqrt (+ (square x) (square y)) y.sqrt (+ (square x) (square y))
3030
Lambda CalculusLambda CalculusSubstitutionsSubstitutions Alpha (Alpha () reduction – renaming) reduction – renaming
x.E x.E y.E y.E substituting y for xsubstituting y for x
Beta (Beta () reduction – application) reduction – application ((x.E) M x.E) M E E substituting M for xsubstituting M for x Similar to call by nameSimilar to call by name
Eta (Eta () reduction – simplifying ) reduction – simplifying x.F x x.F x F – F – unnecessary unnecessary expression expression
3131
Theoretical FoundationTheoretical Foundation Church-Turing ThesisChurch-Turing Thesis
Effective computationEffective computation Turing machines and Turing machines and -calculus-calculus
Church-Rosser Theorems for Church-Rosser Theorems for -calculus-calculus If reductions produce terminal form (no If reductions produce terminal form (no
further reduction possible) that form is further reduction possible) that form is unique.unique.
If any evaluation order will terminate, If any evaluation order will terminate, normal order will terminate.normal order will terminate.
3232
Introduction to SchemeIntroduction to Scheme
Dialect of Lisp Developed by Guy Dialect of Lisp Developed by Guy Steele (who is also one of the original Steele (who is also one of the original developers of Java) and Gerald developers of Java) and Gerald SussmanSussman Based on Lambda CalculusBased on Lambda Calculus Static scope rulesStatic scope rules Dynamically typedDynamically typed ContinuationsContinuations First class functionsFirst class functions
3333
Scheme ResourcesScheme Resources List of scheme resources:List of scheme resources: http://http://
www.swiss.ai.mit.eduwww.swiss.ai.mit.edu/projects/scheme//projects/scheme/
Download MIT SchemeDownload MIT Scheme http://www.gnu.org/software/mit-scheme/http://www.gnu.org/software/mit-scheme/
Books:Books: The Little SchemerThe Little Schemer, by Daniel P. Friedman, Matthias Felleisen, by Daniel P. Friedman, Matthias Felleisen Structure and Implementation of Computer Programs,Structure and Implementation of Computer Programs, by by
Harold Abelson and Gerald Sussman (Harold Abelson and Gerald Sussman (full-text available on-linefull-text available on-line))
3434
Basic Scheme SyntaxBasic Scheme Syntax A Scheme program is a listA Scheme program is a list
(<function> <operand(<function> <operand11> …)> …) First element of list is a function over the other First element of list is a function over the other
elementselements (+ 2 2) is 4(+ 2 2) is 4 An element may be a listAn element may be a list (+ 2 (* 2 3)) is 8(+ 2 (* 2 3)) is 8
Function definitions introduced by “lambda”Function definitions introduced by “lambda” (“lambda” <parameters> <body>)(“lambda” <parameters> <body>) (lambda (x) (+ x x)) – a procedure(lambda (x) (+ x x)) – a procedure ((lambda (x) (+ x x)) 4) – a value, 8 ((lambda (x) (+ x x)) 4) – a value, 8
3535
Scheme ExampleScheme Example
; semicolon starts a comment; semicolon starts a comment
(define fact (define fact ; binds “fact” to the definition; binds “fact” to the definition
(lambda (n)(lambda (n)
(if (= n 0) (if (= n 0)
1 1 ; base case; base case
(* n (fact (- n 1))))))(* n (fact (- n 1))))))
(define (fact n) (if …)) (define (fact n) (if …)) ; shorthand for the above; shorthand for the above
3636
QuoteQuote
If every list is a computation, how do we If every list is a computation, how do we describe data?describe data?
Another primitive: Another primitive: quotequote (quote (1 2 3 4)) (quote (1 2 3 4)) => (1 2 3 4)=> (1 2 3 4) (quote (this is a simple declarative (quote (this is a simple declarative
sentence)sentence) => (this is a simple declarative sentence)=> (this is a simple declarative sentence) ‘ ‘ (this also works)(this also works) => (this also works)=> (this also works)
3737
Car and CdrCar and Cdr
Names are historicalNames are historical car – contents of address registercar – contents of address register cdr – contents of data registercdr – contents of data register
car = head car = head ; first element; first element cdr = tailcdr = tail ; rest of list; rest of list cadar = (head (tail (head x)))cadar = (head (tail (head x))) cddar = (head (tail (tail x))) cddar = (head (tail (tail x))) ; 3; 3rdrd
elementelement
3838
Decomposing a listDecomposing a list
(car ‘(this is a list of symbols))(car ‘(this is a list of symbols))
=> this=> this
(cdr ‘(this is a list of symbols))(cdr ‘(this is a list of symbols))
=> (is a list of symbols)=> (is a list of symbols)
(cdr ‘(this that))(cdr ‘(this that))
=> (that) => (that) ; a list; a list (cdr ‘(singleton))(cdr ‘(singleton))
=> () => () ; the empty list; the empty list
(car ‘()) ; run time error(car ‘()) ; run time error
3939
Building listsBuilding lists
(cons ‘this ‘(that and the other))(cons ‘this ‘(that and the other))
=> (this that and the other)=> (this that and the other)
(cons ‘a ‘())(cons ‘a ‘())
=> (a)=> (a)
useful shortcut: listuseful shortcut: list
(list ‘a ‘b ‘c ‘d ‘e)(list ‘a ‘b ‘c ‘d ‘e)
=> (a b c d e) => (a b c d e)
equivalent toequivalent to
(cons ‘a (cons ‘b (cons ‘c (cons ‘d (cons ‘e ‘())))))(cons ‘a (cons ‘b (cons ‘c (cons ‘d (cons ‘e ‘())))))
4040
Control structuresControl structures
Conditional Conditional
(if condition expr1 expr2)(if condition expr1 expr2) Generalized formGeneralized form
(cond(cond
(pred1 expr1)(pred1 expr1)
(pred2 expr2)(pred2 expr2)
… …
((elseelse exprn) exprn)
Needs special ruleNeeds special rule: evaluate only the successful entry: evaluate only the successful entry
if and cond are if and cond are notnot regular functions regular functions
4141
Function declarationsFunction declarations
(define (sqr n) (* n n))(define (sqr n) (* n n)) definedefine is also special: body is not evaluated is also special: body is not evaluated defines produces a binding: sqr is bound to the defines produces a binding: sqr is bound to the
body of the computation:body of the computation:
(lambda (n) (* n n))(lambda (n) (* n n)) define can produce value bindings as well:define can produce value bindings as well:
(define x 15)(define x 15)
(sqr x)(sqr x)
=> 225=> 225
4242
Recursion Recursion
(define (add1 x) (+ x 1)) (define (add1 x) (+ x 1)) ; the beginnings of Peano ; the beginnings of Peano arithmeticarithmetic
(define (sub1 x) (- x 1))(define (sub1 x) (- x 1))
(define (add x y)(define (add x y)
(if (= y 0) x(if (= y 0) x
(add ( (add1 x) (sub1 y))))(add ( (add1 x) (sub1 y))))
(define (times x y)(define (times x y)
(cond(cond
((= y 0) 0)((= y 0) 0)
((= y 1) x)((= y 1) x)
(else (add x (times (x (sub1 y)))))))(else (add x (times (x (sub1 y)))))))
4343
Recursion (ii)Recursion (ii)
(define (exp x y)(define (exp x y)
(cond(cond
((eq y 0) 1)((eq y 0) 1)
(else (times x (exp x (sub1 y))))))(else (times x (exp x (sub1 y))))))
betterbetter::
(define (fast-exp x y)(define (fast-exp x y)
(cond (= y 0) 1)(cond (= y 0) 1)
( (even? y) (square (fast-exp x (/ y 2))))( (even? y) (square (fast-exp x (/ y 2))))
(else (* x (fast-exp x (- y 1))))))(else (* x (fast-exp x (- y 1))))))
(define (even? n) (= (remainder n 2) 0)) (define (even? n) (= (remainder n 2) 0)) ; defining a ; defining a predicatepredicate
4444
Recursion on listsRecursion on lists
(define (member elmt lis)(define (member elmt lis)
(cond (cond
((null? lis) ‘())((null? lis) ‘())
((eq elmt (car lis)) lis)((eq elmt (car lis)) lis)
(else (member elmt (cdr lis)))))(else (member elmt (cdr lis)))))
conventionconvention: return rest of list, starting from elmt, : return rest of list, starting from elmt, rather than rather than #t#t or or #f#f
conventionconvention: every non-false value is : every non-false value is truetrue in a in a boolean contextboolean context
4545
PredicatesPredicates
If variables are untyped, need run-time tests to If variables are untyped, need run-time tests to determine kind:determine kind:
symbol?symbol?
number?number?
list?list?
null?null?
zero?zero?
Syntax conventions differ in different dialectsSyntax conventions differ in different dialects: : symbolp, numberp, listp, zerop...symbolp, numberp, listp, zerop...
4646
Functional argumentsFunctional arguments
(define (map fun lis)(define (map fun lis)
(cond(cond
((null? lis) ‘())((null? lis) ‘())
(cons (fun (car lis)) (map fun (cdr lis)))))(cons (fun (car lis)) (map fun (cdr lis)))))
(map sqr (map sqr ‘( 1 2 3 4))(map sqr (map sqr ‘( 1 2 3 4))
=> (1 16 81 256)=> (1 16 81 256)
4747
Self-definitionSelf-definition
(define (eval exp env) (define (eval exp env) ; the lisp interpreter; the lisp interpreter
(cond (cond
((((numbernumber? exp) exp) ? exp) exp) ; numbers are self-evaluating; numbers are self-evaluating
((((symbolsymbol? exp) (lookup exp env)) ? exp) (lookup exp env)) ; a symbol has a binding; a symbol has a binding
((((nullnull? exp) ‘()) ? exp) ‘())
((eq (car exp) ‘((eq (car exp) ‘quotequote) (car (cdr exp))) ) (car (cdr exp))) ; could write cadr; could write cadr
((eq (car exp) ‘((eq (car exp) ‘carcar) (car (car (cdr exp)))) ; ) (car (car (cdr exp)))) ; caadrcaadr
((eq (car exp) ‘((eq (car exp) ‘cdrcdr) (cdr (car (cdr exp)))) : ) (cdr (car (cdr exp)))) : cdadrcdadr
(else ((else (applyapply (eval (car exp) env) (eval (car exp) env) ; apply function; apply function
(eval-list (cdr exp) env))) (eval-list (cdr exp) env))) ; to arguments; to arguments
4848
Function applicationFunction application
(define (apply procedure arguments)(define (apply procedure arguments)
(eval (procedure-body procedure)(eval (procedure-body procedure)
(extend-environment (extend-environment
(parameters procedure) (parameters procedure)
argumentsarguments
(environment procedure))))(environment procedure))))
In words: add actuals to environment, evaluate body In words: add actuals to environment, evaluate body of procedure in new environmentof procedure in new environment
Note: environment is in of procedure definition Note: environment is in of procedure definition (closure)(closure)
4949
EnvironmentsEnvironments
An environment describes the current bindings of An environment describes the current bindings of symbolssymbols
A binding is a pair: A binding is a pair: (symbol value)(symbol value) A frame is a list of bindings (activation record), A frame is a list of bindings (activation record),
i.e. an i.e. an association list: association list: ((s1 v1) (s2 v2)…)((s1 v1) (s2 v2)…) An environment is a list of framesAn environment is a list of frames In some cases we can treat the environment as a In some cases we can treat the environment as a
single association list (e.g. with dynamic binding)single association list (e.g. with dynamic binding)
5050
Association listsAssociation lists
(define ((define (add-assocadd-assoc symb val env) symb val env)
(cons (list symb val) env)) (cons (list symb val) env)) ; add a binding; add a binding
(define ((define (namename binding) (car binding)) binding) (car binding)) ; for readability; for readability
(define ((define (valuevalue binding) (car (cdr binding))); binding) (car (cdr binding)));
(define ((define (lookuplookup symb env) symb env) ; sequential search; sequential search
(cond (cond
((null? env) ‘()) ((null? env) ‘()) ; error detected ; error detected laterlater
((eq symb (name (car env))) (value (car env))((eq symb (name (car env))) (value (car env))
(else (lookup symb (cdr env)))))(else (lookup symb (cdr env)))))
5151
Procedures and their Procedures and their environmentenvironment
A function has three components: a list of A function has three components: a list of formalsformals, , a a bodybody, and , and environmentenvironment of definition. Formals and of definition. Formals and body are represented by a lambda expression:body are represented by a lambda expression:
(lambda (f1 f2 ..) expr)(lambda (f1 f2 ..) expr) A function is evaluated in its A function is evaluated in its environment of environment of
definitiondefinition (lexical scoping) after adding the current (lexical scoping) after adding the current bindings of the actuals (activation record)bindings of the actuals (activation record)
The definition must capture all three componentsThe definition must capture all three components
(define ((define (make-proceduremake-procedure spec body env) spec body env)
(list ‘procedure (make-lambda spec body) env))(list ‘procedure (make-lambda spec body) env))
make-procedure is called by make-procedure is called by evaleval to evaluate a to evaluate a definedefine
5252
Procedure componentsProcedure components
given the representationgiven the representation
(procedure (lambda parameters body) env)(procedure (lambda parameters body) env)
the components of a procedure can be obtained as follows:the components of a procedure can be obtained as follows:
(define ((define (parametersparameters proc) (cadr (cadr proc))) proc) (cadr (cadr proc)))
(define ((define (procedure-bodyprocedure-body proc) (caddr (cadr proc))) proc) (caddr (cadr proc)))
(define ((define (environmentenvironment proc) (caddr proc)) proc) (caddr proc))
5353
Evaluating a function Evaluating a function definitiondefinition
(define ((define (namename binding) (car binding)) binding) (car binding)) results in the binding:results in the binding:
(name(name
(procedure (lambda (binding) (car binding)) env))(procedure (lambda (binding) (car binding)) env))
procedureprocedure and and lambdalambda are labels to indicate kind are labels to indicate kind Env is the current environment. At the top level it Env is the current environment. At the top level it
includes the binding for includes the binding for carcar (used in the body) as (used in the body) as well as all other predefined symbols.well as all other predefined symbols.
5454
The need for closureThe need for closure
(define ((define (composecompose f1 f2) f1 f2)
(lambda (x) (f1 (f2 x))))(lambda (x) (f1 (f2 x))))
(define ((define (sqrsqr x) (* x x)) x) (* x x))
(define (define fourthfourth (compose (sqr sqr))) (compose (sqr sqr)))
(fourth 4) ; yields 256(fourth 4) ; yields 256
When fourth is called, the bindings of f1 and f2 haveWhen fourth is called, the bindings of f1 and f2 have
disappeared. The evaluation of the lambda captures disappeared. The evaluation of the lambda captures the environment in which f1 and f2 are bound to the environment in which f1 and f2 are bound to sqr.sqr.
5555
Tail recursionTail recursion
Tail recursive function needs single stack frame. Tail recursive function needs single stack frame. mandated by semantics of Scheme:mandated by semantics of Scheme:
(define ((define (factorialfactorial n) (if (zero? N) 1) n) (if (zero? N) 1)
(* n (factorial (- n 1))) (* n (factorial (- n 1))) ; stack grows to size n; stack grows to size n
define factorial n) (fact-iter 1 1 n) define factorial n) (fact-iter 1 1 n) ; alternate definition; alternate definition
(define ((define (fact-iterfact-iter prod count var) prod count var)
(if (> count var) prod(if (> count var) prod
(fact-iter (* count prod) (fact-iter (* count prod) ; tail recursion; tail recursion
(+ count 1) (+ count 1) ; implemented as loop; implemented as loop
var))))var))))
5656
Implementation of tail Implementation of tail recursionrecursion
If last operation in function is recursive call, If last operation in function is recursive call, overwrite actuals and go to beginning of code:overwrite actuals and go to beginning of code:
(define (last lis)(define (last lis)
(if (null? (cdr lis) (car lis))(if (null? (cdr lis) (car lis))
(last (crd lis)))) (last (crd lis)))) ; can be done with ; can be done with looploop
(define (length lis)(define (length lis)
(if (null? lis) 0)(if (null? lis) 0)
(+ 1 (length (cdr lis)))) (+ 1 (length (cdr lis)))) ; not tail recursive!; not tail recursive!