Functions and Recursion. Dr. Philip Cannata 1

Similar documents
Functions and Recursion

Reminder About Functions

22c:111 Programming Language Concepts. Fall Functions

known as non-void functions/methods in C/C++/Java called from within an expression.

Higher-Order Functions

Names and Types. standard hue names. Dr. Philip Cannata 1

CS 345. Functions. Vitaly Shmatikov. slide 1

Cost of Substitution

Fall 2012 CS345 Project Requirements and Suggestions (Version 4)

Name EID. (calc (parse '{+ {with {x {+ 5 5}} {with {y {- x 3}} {+ y y} } } z } ) )

Project 2: Scheme Interpreter

Implementing Recursion

Higher-Order Functions (Part I)

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Typed Recursion {with {mk-rec : (((num -> num) -> (num -> num)) -> (num -> num)) {fun {body : ((num -> num) -> (num -> num))} {{fun {fx :

Name SOLUTIONS EID NOTICE: CHEATING ON THE MIDTERM WILL RESULT IN AN F FOR THE COURSE.

Functional Programming - 2. Higher Order Functions

Functional Programming. Pure Functional Programming

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

fjyswan Dr. Philip Cannata 1

CS 415 Midterm Exam Spring 2002

Every language has its own scoping rules. For example, what is the scope of variable j in this Java program?

Comp 311: Sample Midterm Examination

cs173: Programming Languages Midterm Exam

cs173: Programming Languages Final Exam

Principles of Programming Languages 2017W, Functional Programming

MIDTERM EXAMINATION - CS130 - Spring 2005

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

CMSC 330: Organization of Programming Languages. Operational Semantics

COP4020 Programming Assignment 1 - Spring 2011

Discussion. Type 08/12/2016. Language and Type. Type Checking Subtypes Type and Polymorphism Inheritance and Polymorphism

CS 275 Name Final Exam Solutions December 16, 2016

Threads. {seqn {spawn EXPR 1 } {spawn EXPR 2 }} Runs EXPR 1 and EXPR 2 in any order, even interleaved with each other

Simple Lisp. Alonzo Church. John McCarthy. Turing. David Hilbert, Jules Richard, G. G. Berry, Georg Cantor, Bertrand Russell, Kurt Gödel, Alan

Running FAE Programs Natively

State. Substitution relies on an identifer having a fxed value

The Compiler So Far. Lexical analysis Detects inputs with illegal tokens. Overview of Semantic Analysis

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Functional Programming. Big Picture. Design of Programming Languages

Programming Languages. Dr. Philip Cannata 1

Programming Languages

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Recursion & Iteration

CS450: Structure of Higher Level Languages Spring 2018 Assignment 7 Due: Wednesday, April 18, 2018

CSE413 Midterm. Question Max Points Total 100

Principles of Programming Languages

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Types and Type Inference

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

The role of semantic analysis in a compiler

A LISP Interpreter in ML

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

Scheme as implemented by Racket

Programming Languages. Dr. Philip Cannata 1

Functional Programming Languages (FPL)

Stack ADT. ! push(x) puts the element x on top of the stack! pop removes the topmost element from the stack.

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

CSCI312 Principles of Programming Languages!

CS 415 Midterm Exam Fall 2003

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

LECTURE 18. Control Flow

An Introduction to Functions

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Types, Type Inference and Unification

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

CS4215 Programming Language Implementation

Organization of Programming Languages CS3200/5200N. Lecture 11

Lecture 8: Recursion and Iteration. Exceptions. Declarative Programming.

NOTE: Answer ANY FOUR of the following 6 sections:

Box-and-arrow Diagrams

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Functional Programming. Pure Functional Languages

Functional Programming. Pure Functional Languages

Lecture 16: Static Semantics Overview 1

Non-Functional Procedures

CS 415 Midterm Exam Spring SOLUTION

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

Functional Programming and Haskell

Functional Programming

Parsing Scheme (+ (* 2 3) 1) * 1

CS 314 Principles of Programming Languages

Implementing Subprograms

Chapter 15. Functional Programming Languages

CS558 Programming Languages

Logic - CM0845 Introduction to Haskell

Functional Languages. Hwansoo Han

Midterm 2 Solutions Many acceptable answers; one was the following: (defparameter g1

The results for a few specific cases below are indicated. allequal ([1,1,1,1]) should return true allequal ([1,1,2,1]) should return false

Scheme Quick Reference

UNIVERSITY OF TORONTO Faculty of Arts and Science. Midterm Sample Solutions CSC324H1 Duration: 50 minutes Instructor(s): David Liu.

Types and Type Inference

LECTURE 16. Functional Programming

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

CPSC 311, 2010W1 Midterm Exam #2

Programming Languages. Dr. Philip Cannata 1

Lecture 15 CIS 341: COMPILERS

CPS 506 Comparative Programming Languages. Programming Language Paradigm

CS 11 Haskell track: lecture 1

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

Transcription:

Functions and Recursion Dr. Philip Cannata 1

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

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 -------- (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) Dr. Philip Cannata 3 C

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) Dr. Philip Cannata 4

Static scoping: Static and 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 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)))))) Dr. Philip Cannata 5

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 Page remainder 27 - " 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. Dr. Philip Cannata 6

$ 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)))) empty Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a))) Evaluating: (\ (x y) (- x (+ y z))) Result: (\ (x y) (- x (+ y z))) [] Evaluating: (let ((z 10) (a 5)) (x z a)) z: 3 x: (\ (x y) (- x (+ y z))) [] Evaluating: (x z a) z: 10 x: (\ (x y) (- x (+ y z))) [] Evaluating: (- x (+ y z)) y: 5 x: 10 Evaluating: (+ y z) y: 5 x: 10 Result: 22 Result: -12 Result: -12 Result: -12 Result: -12 Result: -12 In Crono, \ mean lambda Dr. Philip Cannata 7

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)))) empty Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z a))) Evaluating: (\ (x y) (- x (+ y z))) Result: (\ (x y) (- x (+ y z))) [] Evaluating: (let ((z 10) (a 5)) (x z a)) z: 3 x: (\ (x y) (- x (+ y z))) [] Evaluating: (x z a) z: 10 x: (\ (x y) (- x (+ y z))) [] Evaluating: (- x (+ y z)) y: 5 z: 10 x: 10 Evaluating: (+ y z) y: 5 z: 10 x: 10 Result: 15 Result: -5 Result: -5 Result: -5 Result: -5 Result: -5 Dr. Philip Cannata 8

(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))))) empty Evaluating: (let ((z 3) (a 5) (x (\ (x y) (- x (+ y z))))) (let ((z 10) (a 5)) (x z (x 0 0)))) Evaluating: (\ (x y) (- x (+ y z))) Result: (\ (x y) (- x (+ y z))) [] Evaluating: (let ((z 10) (a 5)) (x z (x 0 0))) z: 3 x: (\ (x y) (- x (+ y z))) [] Evaluating: (x z (x 0 0)) z: 10 x: (\ (x y) (- x (+ y z))) [] Evaluating: (x 0 0) z: 10 x: (\ (x y) (- x (+ y z))) [] Evaluating: (- x (+ y z)) y: 0 x: 0 Evaluating: (+ y z) y: 0 x: 0 Result: 17 Result: -17 Result: -17 Evaluating: (- x (+ y z)) y: -17 x: 10 Evaluating: (+ y z) y: -17 x: 10 Result: 0 Result: 10 Result: 10 Result: 10 Result: 10 Result: 10 Notice function application here. Dr. Philip Cannata 9

(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)))))) 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))))) Evaluating: (\ (x y) (- x (+ y z))) Result: (\ (x y) (- x (+ y z))) [, ] Evaluating: (let ((z 10) (a 5)) (x z (x 0 ((\ (x) x) i)))) z: 3 x: (\ (x y) (- x (+ y z))) [, ] Evaluating: (x z (x 0 ((\ (x) x) i))) z: 10 x: (\ (x y) (- x (+ y z))) [, ] Evaluating: (x 0 ((\ (x) x) i)) z: 10 x: (\ (x y) (- x (+ y z))) [, ] Evaluating: ((\ (x) x) i) z: 10 x: (\ (x y) (- x (+ y z))) [, ] Evaluating: (\ (x) x) z: 10 x: (\ (x y) (- x (+ y z))) [, ] Result: (\ (x) x) [,, z: 10, x: (\ (x y) (- x (+ y z)))] Result: 22 Evaluating: (- x (+ y z)) y: 22 x: 0 Evaluating: (+ y z) y: 22 x: 0 Result: 39 Result: -39 Result: -39 Evaluating: (- x (+ y z)) y: -39 x: 10 Evaluating: (+ y z) y: -39 x: 10 Result: -22 Result: 32 Result: 32 Result: 32 Result: 32 Result: 32 Dr. Philip Cannata 10

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

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. Parameter and Arguments 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); Dr. Philip Cannata 12

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 Parameter Passing Mechanisms Dr. Philip Cannata 13

int h, i; void B(int w) { int j = 1, k = 2; i = 2*w; w = w+1; Pass by Value 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); int h, i; void B(int *w) { int j = 1, k = 2; i = 2*(*w); *w = *w + 1; Pass by Reference 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 $./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 Dr. Philip Cannata 14

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 called copy-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. real procedure Sum(j, lo, hi, Ej); x[j]*j 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; 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). Dr. Philip Cannata 15

This can be thought of as a stack with cons s on it. (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (cons 5 '())))))) 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 '())))))) Dr. Philip Cannata 16 (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (cons 5 '())))))) Here the stack is upside down

Recursive Functions Exemplified by foldl in lisp Nothing goes on the stack in this case. (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 '())))))) Dr. Philip Cannata 17

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 Dr. Philip Cannata 18

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. Dr. Philip Cannata 19

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 Dr. Philip Cannata 20

Calling function: factorial BasePtr = 3, printing runtime stack n: 3 answer: null number: 3 Calling function: factorial BasePtr = 5, printing runtime stack n: 2 n: 3 answer: null number: 3 Calling function: factorial BasePtr = 7, printing runtime stack n: 1 n: 2 n: 3 answer: null number: 3 Calling function: factorial BasePtr = 9, printing runtime stack n: 0 n: 1 n: 2 n: 3 answer: null number: 3 Hmm Runtime Stack for Factorial 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 n: 0 return#factorial: 1 n: 1 n: 2 n: 3 answer: null number: 3 Exiting function: factorial BasePtr = 7, printing runtime stack return#factorial: 1 n: 1 return#factorial: 1 n: 2 n: 3 answer: null number: 3 Exiting function: factorial BasePtr = 5, printing runtime stack return#factorial: 1 n: 2 return#factorial: 2 n: 3 answer: null number: 3 Exiting function: factorial BasePtr = 3, printing runtime stack return#factorial: 2 n: 3 return#factorial: 6 answer: null number: 3 Dr. Philip Cannata 21