#lang racket ; let.rkt: CS 251 Let Bindings and Scope examples ; env: . (let ([x 2]) ; env: x --> 2, . (let ([x (* x x)]) ; env: x --> 4, x --> 2, . (+ x 3))) ; env: . ; 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-better x) (letrec ([count (lambda (from) (if (= from x) (cons x null) (cons from (count (+ from 1)))))]) (count 1))) ; inefficient max (define (bad-max xs) (if (null? xs) null ; max is not defined on empty list (if (null? (cdr xs)) (car xs) (if (> (car xs) (bad-max (cdr xs))) (car xs) (bad-max (cdr xs)))))) ; efficient max (define (good-max xs) (if (null? xs) null (if (null? (cdr xs)) (car xs) (let ([rest-max (good-max (cdr xs))]) (if (> (car xs) rest-max) (car xs) rest-max)))))