# Prof. Fateman CS 164 Lecture 261 Functional Tiger, Calling variations Lecture 26.

## Presentation on theme: "Prof. Fateman CS 164 Lecture 261 Functional Tiger, Calling variations Lecture 26."— Presentation transcript:

Prof. Fateman CS 164 Lecture 261 Functional Tiger, Calling variations Lecture 26

Prof. Fateman CS 164 Lecture 262 Typechecking DID YOU START ON ASSIGNMENT 5 YET?

Prof. Fateman CS 164 Lecture 263 Lex Changes to Tiger to make it “functional” New token, -> New grammar rules for type declaration ty ! ty -> ty ty ! (ty {,ty}) -> ty Ty ! () -> ty E.g. let type foo= (int,int) -> int type bar=(int->string,int) -> int->int

Prof. Fateman CS 164 Lecture 264 Parse Changes to Tiger to make it “functional” New grammar rules for CallExp exp ! exp (exp {,exp}) ;actually unlikely to be LALR(1) E.g. Add(3)(4) Where function Add(n:int):int->int = let function z(x:int):int=n+x in z end /* compare to scheme, (define add(n)(lambda(x)(+ x n))… */

Prof. Fateman CS 164 Lecture 265 AST Changes to Tiger to make it “functional” New Type, say FunTy added to ArrayTy, RecordTy… Perhaps new FunExp added to IntExp, etc.

Prof. Fateman CS 164 Lecture 266 Type Check Changes to Tiger to make it “functional” New typechecking function Add(n:int):int->int = let function z(x:int):int=n+x /* implicit decl: type z=int->int */ in z End And lots more, checking signatures more carefully, deciding about structure vs name equivalence again. (personally, I think this would be a delicate business: to match type bar=(int->string,int) -> int->int)

Prof. Fateman CS 164 Lecture 267 Interpreter Changes to Tiger to make it “functional” Our interpreter: Nothing changes. Our environments persist until the Lisp GC removes them. Lists of bindings can look like this. env1 env2

Prof. Fateman CS 164 Lecture 268 Interpreter Changes to Tiger to make it “functional” A stack interpreter cannot build such a tree. Its lexical environments persist only while within lexical scope. We need to preserve until function, returned upward, is called. Here env2 clobbers env1. Another possibility (next slide) is that we exit from some scope but must still access it. env1 env2

Prof. Fateman CS 164 Lecture 269 Example… of upward functional arg (return) Let type nilint = ()->int/*type is no args -> int */ function f1():nilint = let function f2()nilint= let function f3():nilint= let var x:=10 function f4():int =x /*this function is returned */ in f4 end in f3 end in f2 end in f1() end /* f1() must return 10 so the lexical scope in which x lives must be saved somehow. */

Prof. Fateman CS 164 Lecture 2610 Interpreter Changes to Tiger to make it “functional” Let var y:=43 /*not used, though in theory visible in f4 */ function f1():nilint = let function f2():nilint= let function f3():nilint= let var x:=10 /*visible in f4, escapes…*/ function f4():int =x in f4 end in f3 end in f2 end in f1() end /* f4 could be some kind of bundle including x but not (for example) y, f1, f2, f3. */

Prof. Fateman CS 164 Lecture 2611 Interpreter Changes to Tiger to make it “functional” Let var y:=43 /* now used and visible in f4 */ function f1():nilint = /*type no args -> int */ let function f2():nilint= let function f3():nilint= let var x:=10 /*visible in f4, escapes…*/ function f4():int =x+y in f4 end in f3 end in f2 end in f1() end /* f4 could be in some kind of bundle or closure including x and y */

Prof. Fateman CS 164 Lecture 2612 Other suggested changes of chapter 15 Pure-functional Call by name Lazy evaluation

Prof. Fateman CS 164 Lecture 2613 Pure Functional no assignments; the only time a variable can take a value is on initialization or parameter passage. no input/output; continuation based I/O –getchar() replaced by getchar(consumer) –Consumer is of type string ->answer –E.g getchar(eatchar) CALLS eatcar with a single- character string. –Continuation based processing is useful in compiling..We will revisit this idea later; here it is a hack.

Prof. Fateman CS 164 Lecture 2614 Pure Functional; mostly a theoretical construct Helpful if you wish to reason about programs –prove equivalence of programs –Lazy evaluation helps avoid equivalence “if programs halt” p 342, sometimes. Values are computed only when the results actually matter –Opposite of lazy is “strict”.. All expressions are evaluated as control flow reaches them, whether or not their results are needed. –Lazy eval vs call-by-need… more later

Prof. Fateman CS 164 Lecture 2615 Call by name (Important on CS GRE) Invented for Algol 60. Often the same as call by reference.. BUT if Tiger had call-by-name semantics, Let function Q(a,x)= (x:=3; a:=4) var z:intarray :=array[10] of 0 Call Q(z[i],i) /*by name*/  results in setting z[3] to 4. versus… Call Q(m,n)  Simply sets n to 3, m to 4. Same as call by ref. Call by name: each value is a thunk that computes its value or location when used;

Prof. Fateman CS 164 Lecture 2616 One implementation:copy over the body.. Invented for Algol 60. Often the same as call by reference.. BUT if Tiger had call-by-name semantics, Let function Q(a,x)= (x:=3; a:=4) var z:intarray :=array[10] of 0 Call Q(z[i],i) /*by name*/ i:=3; z[i]:=4 An implementation could copy over the function body, renaming as appropriate to avoid “other” conflicts. (if there were other instances of i and z in Q, they would have to be renamed, e.g. Qi and Qz might do.)

Prof. Fateman CS 164 Lecture 2617 Lazy evaluation = call by need. Each “thunk” of call-by-name is now 2 cells: the thunk function + the memoized value if it has been visited before. You’ve seen this in CS61a. …Set up fibonacci function to remember fib(0), fib(1), then compute fib(2)=fib(0)+fib(1) but REMEMBER fib(2). Compute fib(3)= fib(1)+fib(2) remembered etc. This is potentially an enormous savings in heavily recursive purely-functional programs. For call-by- name or lazy evaluation, careful compilation can make this efficient.

Prof. Fateman CS 164 Lecture 2618 A thought: should cons evaluate its arguments? If you make the following arrangements: instead of (cons a b), do (list ‘CONS ‘a ‘b) Instead of (car x) do (if (eq (car x) ‘CONS) (eval (cadr x))) Instead of (cdr x) do (if (eq (car x) ‘CONS) (eval (caddr x))) ;; really we can’t do (list ‘CONS ‘a ‘b) but need (list ‘CONS (closure of a, environment) (closure of b, environment)) … so we can do (eval a) or (eval b). Look at it this way. No one knows what’s inside a cons cell without looking at its car or cdr. So don’t compute it until someone looks. Pprint looks..

Prof. Fateman CS 164 Lecture 2619 Tiger function calls As a practical semantic view, Tiger calls look rather like lisp. Call by value, but all values are refs to objects The call Foo(x,y,z) cannot change x, y, or z. However, if x is an array, Foo can change x[0], x[1]… because a pointer to the array x is given to Foo. If y is a string “hello” then y POINTs to “hello”. Within function Foo(a:intarray,b:string,c:int)… a change to b:= bye merely makes local b POINT to a different string. y still points to “hello”.

Prof. Fateman CS 164 Lecture 2620 Call by value, copy-in/out, etc Value : imagine all arguments which are simple, are copied over into a space owned by the called program. For example, stack space. Function foo(a,b,c)= (a:=b+c) changes nothing outside foo. Copy-in/out or call by value/return is sometimes used (Fortran)– if there are no other “aliased” access routes to variables they are equivalent.

Prof. Fateman CS 164 Lecture 2621 Call by reference in Fortran Function foo(a,b,c)= (a:=b+c) //this is not fortran syntax call foo(3,4,5) Print(3)  may result in printing 9. This is not “correct usage” but has historically happened in common implementations…

Download ppt "Prof. Fateman CS 164 Lecture 261 Functional Tiger, Calling variations Lecture 26."

Similar presentations