#lang racket ;; CSE 413 23sp ;; Lecture 8-9 sample code ;; Hal Perkins ;; Some review/reminders: ;; ;; (define (add x y) (+ x y)) is simply a convenient way of writing ;; the actual definition which is: ;; (define add (lambda (x y) (+ x y)) ;; ;; (define seven (+ 3 4)) ;; ;; Remember that (define id expr) evaluates expr and then binds value to id ;; Same thing happens if expr is a lambda expression. ;; Lambda expression evaluates to closure where: ;; envp is a pointer to the current environment where lambda is evaluated ;; code is (params) expr - the function body ;; so (lambda (x y) (+ x y)) evaluates to (+ x y)> ;; ;; Steps to evaluate (f args): ;; 0) f must evaluate to a closure ;; 1) Create new environment for bindings of function parameters ;; Static (environment) link of new environment is the envp link ;; from the closure - regardless of what environment is current ;; when this new function environment (evaluation) is created ;; 2) Bind parameter names (from closure code) to argument values ;; 3) Evaluate function body expression (from closure code) in this ;; new environment. ;; some data for examples (define x 10) (define ab '(a b)) (define xyz '(x y z)) (define nums '(1 2 3 4 5 6)) (define nums2 '(1 2 3 -17 413 -143 42 12)) (define colors '(red green blue)) (define alist '(a (b c) d e)) ;; I. Example of expressions involving nested scopes (environments) (let ([x 1] [y (+ x 1)]) (+ x y)) (let* ([x 1] [y (+ x 1)]) (+ x y)) (let ([x 1]) (letrec ([f (lambda (n) (+ x n))]) (f x))) (let ([x 2]) (letrec ([f (lambda (n) (+ x n))]) (let ([x 17]) (f x)))) ;; II. Function closures and global names ;; static scoping - how does this x interact with global x? (define addtox (lambda (x) (+ x (plusx x)))) ;; = n + (global) x (define plusx (lambda (n) (+ x n))) ;; (plusx 2) ;; (addtox 2) ;; III. Functions as return values: curried add. ;; What exactly is in the closure and what happens when it is applied? ;; ordinary add function (define add (lambda (x y) (+ x y))) ;; curried add (define cadd (lambda (x) (lambda (y) (+ x y)))) (define plus2 (cadd 2)) ;; (plus2 3) ;; (plus2 x) ;; IV. letrec and and tail-recursive factorial example ;; regular recursive factorial (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) ;; letrec ;; n! tail recursive with local helper function (define factloc (lambda (n) (letrec ([aux (lambda (n acc) (if (= n 0) acc (aux (- n 1) (* n acc))))]) (aux n 1)))) ;; V. map functions ;; small functions to use with map ;; (define (incr n) (+ 1 n)) ;; (define (dbl n) (* 2 n)) ;; defined with explicit lambdas (define incr (lambda (n) (+ 1 n))) (define dbl (lambda (n) (* 2 n))) ;; map and closures (define maplst (lambda (f lst) (if (null? lst) '() (cons (f (car lst)) (maplst f (cdr lst)))))) ;; (maplst plus2 nums) ;; add number to list (define add-n-to-list (lambda (n lst) (maplst (lambda (x) (+ n x)) lst))) ;; (add-n-to-list 5 nums2) ;; curried add n to list function (define cadd-n-to-list (lambda (n) (lambda (lst) (maplst (lambda (x) (+ n x)) lst)))) ;; ((cadd-n-to-list 5) nums2) (define incr-list (cadd-n-to-list 1)) ;; (incr-list nums2) (define (cmap f) (lambda (lst) (map f lst))) (define oddlist (cmap odd?)) ;; (oddlist nums2)