1 / 21

Functions and Recursion

Functions and Recursion. 10. High Level Languages. Java (Object Oriented) ASP RDF (Horn Clause Deduction, Semantic Web). This Course. Jython in Java. Relation. “ let ” transformation, differed substitution and closures, and interpretation in FAE “ let ” transformation:

kasia
Download Presentation

Functions and Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Functions and Recursion

  2. 10 High Level Languages Java (Object Oriented) ASP RDF (Horn Clause Deduction, Semantic Web) This Course Jython in Java Relation

  3. “let” transformation, differed substitution and closures, and interpretation in FAE • “let” transformation: • (let ((A B)) C) == ((lambda (A) C) B) • A B ---------------- C ------------------- • A ---------- B -------- C • (let (( x 3)) (let ((f (lambda (y) (+ x y)))) (f 4)) • ((lambda (x) ((lambda (f) (f 4)) (lambda (y) (+ x y)))) 3) • (app (fun 'x [app (fun 'f [app (id 'f) (num 4)]) (fun 'y (add (id 'x) (id 'y)))]) (num 3)) • (app ------- arg1 ------------------ ------------arg2--------------- • (app --------------------------------------- arg1------------------------------------- --arg2— • Differed substitution and closures: • (aSub 'f (closureV 'y (add (id 'x) (id 'y)) (aSub 'x (numV 3) (mtSub))) (aSub 'x (numV 3) (mtSub))) • Interpretation: • (interp (app (id 'f) (num 4)) (aSub 'f (closureV 'y (add (id 'x) (id 'y)) (aSub 'x (numV 3) (mtSub))) (aSub 'x (numV 3) (mtSub)))) • (numV 7)

  4. Eduardo Saenz (anon. to classmates)  (1 day ago) - If our AST does not have let class nodes, then when our interpreter visits every node of the AST, making the environment of differed substitutions along the way, our environment will only have closures? You only do: (aSub x 3 (mtSub)) when you encounter a let, and since our parser converts lets to lambdas we'll never see this type of differed substitution in our environment; only closures in our environment. Is this logic correct? Philip Cannata (Instructor) (Just now) - This is a good observation but try to understand the following three cases that can occur and see if you can distinguish when deferred substitution should be done in each of them and when function application should be done: > (parse '(with (f (fun (x) x)) 5)) (app (fun 'f (num 5)) (fun 'x (id 'x))) > (interp (parse '(with (f (fun (x) x)) 5)) (mtSub)) (numV 5) > (parse '(with (f (fun (x) x)) (f 5))) (app (fun 'f (app (id 'f) (num 5))) (fun 'x (id 'x))) > (interp (parse '(with (f (fun (x) x)) (f 5))) (mtSub)) (numV 5) > (parse '(with (f (fun (x) x)) ((fun (y) (+ y 2)) 5))) (app (fun 'f (app (fun 'y (add (id 'y) (num 2))) (num 5))) (fun 'x (id 'x))) > (interp (parse '(with (f (fun (x) x)) ((fun (y) (+ y 2)) 5))) (mtSub)) (numV 7)

  5. Static and Dynamic Scoping   Static scoping: (interp (parse '{with {x 5} {f 4}}) (aSub 'f (closureV 'y (add (id 'x) (id 'y)) (aSub 'x (numV 3) (mtSub))) (aSub 'x (numV 3) (mtSub)))) (numV 7) Dynamic Scoping: (interp (parse '{with {x 5} {f 4}}) (aSub 'f (closureV 'y (add (id 'x) (id 'y)) (aSub 'x (numV 3) (mtSub))) (aSub 'x (numV 3) (mtSub)))) (numV 9) Think about this expression for both Static and Dynamic Scoping: (let ((z 3)) (let ((d 3) (f (lambda (x) x))) (let ((z 27)) (let ((z 3) (a 5) (x (lambda (x y) (+ x (+ y z))))) (let ((z 9) (a 7)) (x z a))))))

  6. PLAI Chapters 4, 5 and 6 Chapter 6, Pages 41 & 42 – “first-order Functions are not values in the language. They can only be defined in a designated portion of the program, where they must be given names for use in the remainder of the program. The functions in F1WAE are of this nature, which explains the 1 in the name of the language. higher-order Functions can return other functions as values. first-class Functions are values with all the rights of other values. In particular, they can be supplied as the value of arguments to functions, returned by functions as answers, and stored in data structures. Page 27 - "

  7. $ java crono.Crono (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a)))) Evaluating: (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a))))   Environment: empty   Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a)))     Environment:       z: 17     Evaluating: (\ (x y) (- x (+ y z)))       Environment:         z: 17     Result: (\ (x y) (- x (+ y z))) [z: 17]     Evaluating: (let ((z 10) (a 5)) (x z a))       Environment:         a: 5         z: 3         x: (\ (x y) (- x (+ y z))) [z: 17]       Evaluating: (x z a)         Environment:           a: 5           z: 10           x: (\ (x y) (- x (+ y z))) [z: 17]         Evaluating: (- x (+ y z))           Environment:             y: 5             z: 17             x: 10           Evaluating: (+ y z)             Environment:               y: 5               z: 17               x: 10           Result: 22         Result: -12       Result: -12     Result: -12   Result: -12 Result: -12 In Crono, “\” mean lambda

  8. In CronoOptions.java set public static boolean ENVIRONMENT_DYNAMIC = true; Run ant to rebuild crono. $ java crono.Crono (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a)))) Evaluating: (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a))))   Environment: empty   Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a)))     Environment:       z: 17     Evaluating: (\ (x y) (- x (+ y z)))       Environment:         z: 17     Result: (\ (x y) (- x (+ y z))) [z: 17]     Evaluating: (let ((z 10) (a 5)) (x z a))       Environment:         a: 5         z: 3         x: (\ (x y) (- x (+ y z))) [z: 17]       Evaluating: (x z a)         Environment:           a: 5           z: 10           x: (\ (x y) (- x (+ y z))) [z: 17]         Evaluating: (- x (+ y z))           Environment:             a: 5             y: 5             z: 10             x: 10           Evaluating: (+ y z)             Environment:               a: 5               y: 5               z: 10               x: 10           Result: 15         Result: -5       Result: -5     Result: -5   Result: -5 Result: -5

  9. (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 0))))) Evaluating: (let ((z 17)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 0)))))   Environment: empty   Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 0))))     Environment:       z: 17     Evaluating: (\ (x y) (- x (+ y z)))       Environment:         z: 17     Result: (\ (x y) (- x (+ y z))) [z: 17]     Evaluating: (let ((z 10) (a 5)) (x z (x 0 0)))       Environment:         a: 5         z: 3         x: (\ (x y) (- x (+ y z))) [z: 17]       Evaluating: (x z (x 0 0))         Environment:           a: 5           z: 10           x: (\ (x y) (- x (+ y z))) [z: 17]         Evaluating: (x 0 0)           Environment:             a: 5             z: 10             x: (\ (x y) (- x (+ y z))) [z: 17]           Evaluating: (- x (+ y z))             Environment:               y: 0               z: 17               x: 0             Evaluating: (+ y z)               Environment:                 y: 0                 z: 17                 x: 0             Result: 17           Result: -17         Result: -17         Evaluating: (- x (+ y z))           Environment:             y: -17             z: 17             x: 10           Evaluating: (+ y z)             Environment:               y: -17               z: 17               x: 10           Result: 0         Result: 10       Result: 10     Result: 10   Result: 10 Result: 10 Notice function application here.

  10. (let ((z 17)(i 22)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 ((\ (x) x) i)))))) Evaluating: (let ((z 17) (i 22)) (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 ((\ (x) x) i))))))   Environment: empty   Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 ((\ (x) x) i)))))     Environment:       i: 22       z: 17     Evaluating: (\ (x y) (- x (+ y z)))       Environment:         i: 22         z: 17     Result: (\ (x y) (- x (+ y z))) [i: 22, z: 17]     Evaluating: (let ((z 10) (a 5)) (x z (x 0 ((\ (x) x) i))))       Environment:         i: 22         a: 5         z: 3         x: (\ (x y) (- x (+ y z))) [i: 22, z: 17]       Evaluating: (x z (x 0 ((\ (x) x) i)))         Environment:           i: 22           a: 5           z: 10           x: (\ (x y) (- x (+ y z))) [i: 22, z: 17]         Evaluating: (x 0 ((\ (x) x) i))           Environment:             i: 22             a: 5             z: 10             x: (\ (x y) (- x (+ y z))) [i: 22, z: 17]           Evaluating: ((\ (x) x) i)             Environment:               i: 22               a: 5               z: 10               x: (\ (x y) (- x (+ y z))) [i: 22, z: 17]             Evaluating: (\ (x) x)               Environment:                 i: 22                 a: 5                 z: 10                 x: (\ (x y) (- x (+ y z))) [i: 22, z: 17]             Result: (\ (x) x) [i: 22, a: 5, z: 10, x: (\ (x y) (- x (+ y z)))] Result: 22           Evaluating: (- x (+ y z))             Environment:               i: 22               y: 22               z: 17               x: 0             Evaluating: (+ y z)               Environment:                 i: 22                 y: 22                 z: 17                 x: 0             Result: 39           Result: -39         Result: -39         Evaluating: (- x (+ y z))           Environment:             i: 22             y: -39             z: 17             x: 10           Evaluating: (+ y z)             Environment:               i: 22               y: -39               z: 17               x: 10           Result: -22         Result: 32       Result: 32     Result: 32   Result: 32 Result: 32

  11. 10 High Level Languages Java (Object Oriented) ASP RDF (Horn Clause Deduction, Semantic Web) This Course Jython in Java Relation

  12. Parameter and Arguments • Definitions • An argument is an expression that appears in a function application/call. • A parameter is an identifier that appears in a function definition/declaration. • In the code on the right the call A(a, b) has arguments a and b. • The function declaration A has parameters x and y. int h, i; void B(int w) { int j = 1, k = 2; i = 2*w; w = w+1; printf("In B - w, j, k, h, i: %d, %d, %d, %d, %d\n", w, j, k, h, i); } void A(int x, int y) { float i = 1.1, j = 2.2; B(h); printf("In A - x, y, i, j, h: %d, %d, %f, %f, %d\n", x, y, i, j, h); } int main() { int a, b; h = 5; a = 3; b = 2; A(a, b); printf("In Main a, b, h, i: %d, %d, %d, %d\n", a, b, h, i); }

  13. Parameter Passing Mechanisms • By value - Compute the value of the argument at the time of the call and assign that value to the parameter. So passing by value doesn’t normally allow the called function to modify an argument’s value. • By reference - Compute the address of the argument at the time of the call and assign it to the parameter. Passing by value allows the called function to modify an argument’s value. • By value-result • By name

  14. int h, i; void B(int w) { int j = 1, k = 2; i = 2*w; w = w+1; printf("In B - w, j, k, h, i: %d, %d, %d, %d, %d\n", w, j, k, h, i); } void A(int x, int y) { float i = 1.1, j = 2.2; B(h); printf("In A - x, y, i, j, h: %d, %d, %f, %f, %d\n", x, y, i, j, h); } int main() { int a, b; h = 5; a = 3; b = 2; A(a, b); printf("In Main a, b, h, i: %d, %d, %d, %d\n", a, b, h, i); } $ ./a In B - w, j, k, h, i: 6, 1, 2, 5, 10 In A - x, y, i, j, h: 3, 2, 1.100000, 2.200000, 5 In Main a, b, h, i: 3, 2, 5, 10 int h, i; void B(int *w) { int j = 1, k = 2; i = 2*(*w); *w = *w + 1; printf("In B - w, j, k, h, i: %d, %d, %d, %d, %d\n", w, j, k, h, i); } void A(int *x, int *y) { float i = 1.1, j = 2.2; B(&h); printf("In A - x, y, i, j, h: %d, %d, %f, %f, %d\n", x, y, i, j, h); } int main() { int a, b; h = 5; a = 3; b = 2; A(&a, &b ); printf("In Main a, b, h, i: %d, %d, %d, %d\n", a, b, h, i); } $ ./a In B - w, j, k, h, i: 4206640, 1, 2, 6, 10 In A - x, y, i, j, h: 2280676, 2280672, 1.100000, 2.200000, 6 In Main a, b, h, i: 3, 2, 6, 10 Pass by Value Pass by Reference

  15. Pass by Value-Results Pass by value at the time of the call and/or copy the result back to the argument at the end of the call – also calledcopy-in-copy-out. Pass by Name • Textually substitute the argument for every instance of its corresponding parameter in the function body. Originated with Algol 60 (Jensen’s device), but was dropped by Algol’s successors -- Pascal, Ada, Modula. • Exemplifies late binding, since evaluation of the argument is delayed until its occurrence in the function body is actually executed. • Associated with lazy evaluation in functional languages (e.g., Haskell). • real procedure Sum(j, lo, hi, Ej); • value lo, hi; integer j, lo, hi; real Ej; • begin • real S; S := 0; • for j := lo step 1 until hi do • S := S + Ej; • Sum := S • end; x[j]*j

  16. Recursive Functions Exemplified by foldr in lisp (letrec ((f (lambda (l) (if (null? l) '() (cons (car l) (f (cdr l))))))) (f '(1 2 3 4 5 6))) '(1 2 3 4 5 6) (letrec ((f (lambda (v l) (if (null? l) v (cons (car l) (f v (cdr l))))))) (f '() '(1 2 3 4 5 6))) '(1 2 3 4 5 6) (letrec ((f (lambda (f1 v l) (if (null? l) v (f1 (car l) (f f1 v (cdr l))))))) (f cons '() '(1 2 3 4 5 6))) '(1 2 3 4 5 6) f == foldr If f1 == cons, foldr is the identity function for a list. It‘s the same as (cons 1 (cons 2 (cons 3( cons 4 (cons 5 (cons 6 '())))))) (cons 1 || (cons 2 || (cons 3 || (cons 4 || (cons 5 || (cons 5 '())))))) (cons 1 || (cons 2 || (cons 3 || (cons 4 || (cons 5 || (cons 5 '())))))) This can be thought of as a stack with “cons”s on it. Here the stack is upside down

  17. Recursive Functions Exemplified by foldl in lisp (letrec ((f (lambda (f1 v l) (if (null? l) v (f f1 (car l) (cdr l)))))) (f cons '() '(1 2 3 4 5 6))) 6 (letrec ((f (lambda (f1 v l) (if (null? l) v (f f1 (f1 (car l) v) (cdr l)))))) (f cons '() '(1 2 3 4 5 6))) '(6 5 4 3 2 1) f == foldl If f1 == cons, foldl reverses the list. foldl is tail-recursive because nothing goes on the stack. It‘s the same as (cons 6 (cons 5 (cons 4 ( cons 3 (cons 2 (cons 1 '())))))) Nothing goes on the stack in this case.

  18. Recursive Functions A function that can call itself, either directly or indirectly, is a recursive function. $ cat test.c int factorial (int n) { int i; if (n < 2) { printf("factorial returning 1\n"); return 1; } else { i = n * factorial(n-1); printf("factorial returning %d\n", i); return i; } } int main() { printf("factorial(3) returns: %d\n", factorial(3)); } $ ./a factorial returning 1 factorial returning 2 factorial returning 6 factorial(3) returns: 6

  19. Runtime Stack • A stack of activation records: • An activation record is a block of information associated with each function call, which includes: • parameters and local variables • Return address • Each new call pushes an activation record, and each completing call pops the topmost one. • So, the topmost record is the most recent call, and the stack has all active calls at any run-time moment.

  20. Runtime Stack for Functions Program int h, i; void B(int w) { int j, k; i = 2*w; w = w+1; } void A(int x, int y) { bool i, j; B(h); } int main() { int a, b; h = 5; a = 3; b = 2; A(a, b); } • parameters and local variables • Return address • Saved registers • Temporary variables • Return value

  21. Hmm Runtime Stack for Factorial 3 Calling function: factorial BasePtr = 3, printing runtime stack null: null n: 3 null: null answer: null number: 3 Calling function: factorial BasePtr = 5, printing runtime stack null: null n: 2 null: null n: 3 null: null answer: null number: 3 Calling function: factorial BasePtr = 7, printing runtime stack null: null n: 1 null: null n: 2 null: null n: 3 null: null answer: null number: 3 Calling function: factorial BasePtr = 9, printing runtime stack null: null n: 0 null: null n: 1 null: null n: 2 null: null n: 3 null: null answer: null number: 3 int factorial(int n) { if(n < 1) { return 1; } else { return n * factorial(n - 1); } } int main() { int number, answer; number = 3; answer = factorial(number); print(answer); } Exiting function: factorial BasePtr = 9, printing runtime stack null: null n: 0 return#factorial: 1 n: 1 null: null n: 2 null: null n: 3 null: null answer: null number: 3 Exiting function: factorial BasePtr = 7, printing runtime stack return#factorial: 1 n: 1 return#factorial: 1 n: 2 null: null n: 3 null: null answer: null number: 3 Exiting function: factorial BasePtr = 5, printing runtime stack return#factorial: 1 n: 2 return#factorial: 2 n: 3 null: null answer: null number: 3 Exiting function: factorial BasePtr = 3, printing runtime stack return#factorial: 2 n: 3 return#factorial: 6 answer: null number: 3

More Related