#lang racket ; let.rkt: CS 251 Local Bindings and Scope examples ; E: . (let ([x 2]) ; E: x --> 2, . (let ([x (* x x)]) ; E: x --> 4, x --> 2, . (+ x 3))) ; E: . ; BAD: (+ (let ([x 4]) x) x) <-- second x not in scope ; A local function binding (define (quad x) (let ([square (lambda (x) (* x x))]) (square (square x)))) ; A local function binding with recursion (define (count-up-from-1 x) (letrec ([count (lambda (from to) (if (= from to) (cons to null) (cons from (count (+ from 1) to))))]) (count 1 x))) ; A nicer local function binding that exploits the environment. (define (count-up-from-1 x) (letrec ([count-to-x (lambda (from) (if (= from x) (cons x null) (cons from (count-to-x (+ from 1) x))))]) (count-to-x 1))) ; inefficient max (define (bad-max xs) (if (null? xs) null ; not defined on empty list (if (null? (rest xs)) (first xs) (if (> (first xs) (bad-max (rest xs))) (first xs) (bad-max (rest xs)))))) ; efficient max (define (good-max xs) (if (null? xs) null ; not defined on empty list (if (null? (first xs)) (first xs) (let ([rest-max (good-max (rest xs))]) (if (> (rest xs) rest-max) (rest xs) rest-max))))) ; efficient and concise max (define (maxlist xs) (if (null? xs) null ; not defined on empty list (max (first xs) (maxlist (rest xs)))))