----------------------------------------
Tutorial notes #1 for 2/12 or 2/13/2007

TA:       Stephen McCamant
Email:    smcc@mit.edu
Location: 36-113A or 36-115
----------------------------------------

* About me

* About you

----------------------------------------

Scheme evaluation rules:

1. If it's self-evaluating (e.g. number),
   return value
2. If it's a name (e.g., x, +), look up
   in environment and return associated
   value
3. If it's a special form:
   a. define: evaluate 2nd arg, bind
      1st to that value
   b. lambda: return procedure
   c. if: evaluate 1st arg; if not #f,
      eval 2nd, else eval 3rd.
4. If it's a combination:
   a. Evaluate each subexpression
   b. Apply 1st to rest
      1. If primitive, just do it
      2. If compound procedure,
         replace formal parameters with
         actual arguments and evaluate

----------------------------------------

DrScheme basics

----------------------------------------

Examples: define and simple expressions

12
;-> 12

(+ 12 18)
;-> 30

(* 1 2 3 4 5)
;-> 120

(*)
;-> 1

(+ (* 2 3) (* 4 5))
;-> 26

(+ 1 (+ 2 (+ 3 (+ 4 5))))
;-> 15

((+ 1 2))
;-> error: expected procedure, got 3

(define pi 3.14)
;-> unspecified

(* 2 pi)
;-> 6.28

(- 10)
;-> -10

(/ 5)
;-> 1/5

(/ 5.0)
;-> 0.2

(define e (+ 1.0 (/ 1) (/ 2) (/ 6) (/ 24)
                 (/ 120) (/ 720)))
;-> unspecified

e
;-> 2.71805

(define x x)
;-> error

(define x 2)
;-> unspecified

(define x x)
;-> unspecified

(+ x x)
;-> 4

----------------------------------------
Examples: lambda

(lambda (x) x)
;-> procedure

(lambda () 5)
;-> procedure

((lambda (x y) (+ x y)) 2 3)
;-> 5

((lambda () 42))
;-> 

(define square (lambda (x) (* x x)))
;-> unspecified

(square 5)
;-> 25

(square (square 3))
;-> 81

((lambda (x y) x) 1 2)
;-> 1

(/ 0 0)
;-> error

(* 0 (/ 0 0))
;-> error

((lambda (x y) x) 1 (/ 0 0))
;-> error

Examples: if

(if #t 2 3)
;-> 2

(if #f 2 3)
;-> 3

(= 2 2)
;-> #t

(< 2 3)
;-> #t

(<= 2 2)
;-> #t

(if (< 12 10) 12 10)
;-> 10

(+ 10 (if (< 12 10) 2 0))
;-> 10

(define x 2)
(if (< x 10)
    (if (< x 5) 0 5)
    (if (< x 15) 10 15))
;-> 0

((if (< x 10) + *) 2 3)
;-> 5

(if #t 5 (/ 0))
;-> 5

----------------------------------------

(cond (condition1 value1)
      (condition2 value2)
      (condition3 value3)
      (else value4))

Is "cond" syntactic sugar
   or a special form?
Yes, both.

It's syntactic sugar because it can be rewritten using just "if":
(if condition1 value1
    (if condition2 value2
        (if condition3 value3
            value4)))

It's a special form because it doesn't follow the usual rules for
evaluation of combinations; not all of the subexpressions are
evaluated, condition1 isn't applied as a procedure to value1, etc.

(or (< 2 3) (<= 2 3))
;-> #t


Write these functions:

(celsius-to-farenheit 0)    -> 32
(celsius-to-farenheit 100)  -> 212
(celsius-to-farenheit 37.0) -> 98.6
;; F = 32 + (9/5)*C




(define celsius-to-farenheit
  (lambda (c)
    (+ 32 (* (/ 9 5) c))))

(feet-to-meters 6) -> 1.8288
;; one inch is 2.54 centimeters
;; one foot is 12 inches




;; Using helper functions here makes it easier to make sure you've
;; got all the parts right.
(define feet-to-inches
  (lambda (f)
    (* f 12)))

(define inches-to-centimeters
  (lambda (i)
    (* i 2.54)))

(define centimeters-to-meters
  (lambda (c)
    (/ c 100)))

(define feet-to-meters
  (lambda (f)
    (centimeters-to-meters
     (inches-to-centimeters
      (feet-to-inches f)))))

(hamburger-price <patties> <cheese?>)
;; a single burger is $1.19
;; a double burger is $1.69
;; a triple burger is $1.99
;; cheese is 20 cents extra



(define hamburger-price
  (lambda (patties cheese)
    (+ (if cheese 0.20 0)
       (cond ((= patties 1) 1.19)
             ((= patties 2) 1.69)
             ((= patties 3) 1.99)
             (else (error "Heart attack"))))))

;; (cos x) computes the cosine of x in
;; radians.
;; Write a function to find a value x
;; such that cos(x) = x.



;; Note that we're relying on the fact that inexact Scheme numbers
;; have a finite precision; otherwise this wouldn't stop.
(define cos-fixed-point
  (lambda (x)
    (if (= x (cos x))
        x
        (cos-fixed-point (cos x)))))

(donut-price <quantity>)
;; Donuts are 79 cents each,
;; or $3.99 for 6, or
;; $7.49 per dozen. What's the
;; best price for n donuts?



(define donut-price
  (lambda (n)
    (cond ((>= n 12) (+ 7.49 (donut-price (- n 12))))
          ((= n 11) (donut-price 12)) ;; cheaper by the dozen
          ((>= n 6) (+ 3.99 (donut-price (- n 6))))
          ((>= n 0) (* n 0.79))
          (else (error "We can't sell that many donuts")))))