;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname lect05bc) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) (define (root1 a b c) (let* {[discriminant (- (* b b) (* 4 a c))] } (/ (+ (- b) (sqrt discriminant)) (* 2 a)))) ; Note that `let*` is not an *essential* part of the language; ; it is syntactic sugar for making a helper function: #| (define (root1 a b c) (helper-root1 a b c (- (* b b) (* 4 a c)))) (define (helper-root1 a b c discriminant) (/ (+ (- b) (sqrt discriminant)) (* 2 a))) (root1 1 2 3) |# ; Previously: ; - local variables: avoiding repeated computation can be very important ; - `let` is equivalent to making a helper function ; (So even if your language didn't provide local variables, ; if it allowed writing helper functions, with their own parameters, ; then you haven't lost any power.) ; (To think about: the other way around -- can we replace every ; function-call with a `let` -- that is, can we in-line every function call? ; A: Often, but NO not always: consider `pipe-area` vs `sum`) ; Stepper ; Example: tee; sum ;;; step through: (define (sum nums) (cond [(empty? nums) 0] [(cons? nums) (+ (first nums) (sum (rest nums)))])) (sum (cons 2 (cons 9 (cons 1 (cons 44 empty))))) ;;; Note: we will *not* talk about tail-recursion yet -- ;;; let's get more practice with regular ol' functions. ;;; (But we can point out how the stack piles up, for `sum`.) ;;;; ;; lect05c (Fri): ; The Law of Scheme ; lambda (λ) ; let and friends (revisited) #| In Racket, we have *expressions*; every expression *evaluates* to a *value*. E.g. (+ 2 3) evaluates to 5 That's all(*) we do, in racket! An *expr* (syntax) is either: - a value - an identifier - a function-application: (expr_0 expr_1 ... expr_n) - a special form: - (define id expr) - (cond [expr_q0 expr_a0] [expr_q1 expr_a1] ... [expr_qn expr_an]) - if: (if expr_tst expr_thn expr_els) - define-struct Examples: - values 17 #t 'ehllo "eh?" empty (λ (n) (* 3 n)) - identifiers pi e + - function application (+ 2 3) (sqrt 23) (* 2 pi (sqrt 23) (+ 2 3)) = (+ 2 3.14 4.87 5) - let (see below for examples) Semantics: - values evaluate to themselves! - identifiers go find the corresponding `define`, use that value. - function application (expr_0 expr_1 ... expr_n) Evaluate each expression, getting values val_0, val_1, ..., val_n Note: val_0 had better be a function! In the body of val_0, replace each parameter with val_1,..., val_n; evaluate that resulting expression. - special forms: - define - (cond [expr_q0 expr_a0] [expr_q1 expr_a1] ... [expr_qn expr_an]) Evaluate expr_q0 (it had better be a boolean); if the value is true, then evaluate expr_a0 and return that result else evaluate (cond [expr_q1 expr_a1] ... [expr_qn expr_an]) (cond) evaluates to an error. - if: (if expr_cond expr_then expr_else) evaluate expr_cond (it had better be a boolean); call the result v_cond. If v_cond is true, return result of eval'ing expr_then; otherwise return result of eval'ing expr_else alternately: the result of eval'ing `if` is: the result of evaling (cond [expr_cond expr_then] [else expr_else]) - and, or - define-struct - let*, let Hey: let's look more closely at functions: In "function-application" semantics, we say that the function-application simplifies to "the body of the function, where parameters(identifiers) have been substituted with the arguments(values)" But: what about the very (*) Okay, I'm fudging a bit: `define` isn't really an expression; you can't write (+ 7 (define x 99) 3) However, note that `let` *is* an expression, and it's not too hard to imagine a world where your entire file is really surrounded by one big `let`. ...And we saw that `let` can be translated to a lambda ... ...so can we make a language that doesn't use `define` at all, just uses `lambda` and parameters? See: "the lambda calculus"; "the Y combinator"; "church numerals". |# ;;;;;;;;;;;;;;;; lect06a ; we saw: ; - syntax,semantics of scheme ; - lambda is a value. ; ; New: ; We can pass functions: e.g. sort [moved this to lect06b] ; (How do we do this in Java?) ; - So, back to: semantics of 'let', 'let*'.