### lec08 code

parent 0b67026b
 ... ... @@ -6,4 +6,17 @@ type myrecord = { } let r = { name = "james"; height = 75} let who = r.name \ No newline at end of file let who = r.name let s = ("james", 75) let who2 = fst s (* both records and tuples are "each of" types. ("all of") a value has "each of" its components r has each of {name, height} s has each of {fst, snd} *)
 ; bonus material!!!!!!!!! ; ; goal: define "a > b" operator without having to add it to the language ; ; the language has recursion, arithmetic, and = on integers ; ; first idea: suffices to implement the "n > 0" operator, since "a > b" ; is equivalent to (a - b) > 0. ; ; second idea: we can "search downwards for zero" by repeatedly subtracting 1 from n. ; if n is positive, we will eventually find zero. ; if n is negative, this will loop forever. ; ; third idea: on the other hand, with a negative number, we could "search upwards" ; by repeatedly adding 1 to n. ; if n is negative, we will eventually find zero. ; if n is positive, this will loop forever. ; fourth idea: do both searches "at the same time". one of them is guaranteed to terminate. ; and whichever one terminates tells you whether the original n was positive or negative ; :) ; precondition: either down is >= 0 or up is <= 0 ; repeatedly decrements down and increments up ; if down hits zero, returns true. ; if up hits zero, returns false. ; if they hit zero at the same time, returns true. (define (downup-search down up) (if (= down 0) true (if (= up 0) false (downup-search (- down 1) (+ up 1))))) ; a function whose name is ">=0" just for fun (define (>=0 n) (downup-search n n)) (test (>=0 0)) (test (>=0 -0)) (test (>=0 1)) (test (>=0 100)) (define (not b) (if b false true)) (test (not (>=0 -1))) (test (not (>=0 -100))) ; warning: not short-circuiting! (define (and b1 b2) (if b1 b2 false)) (define (>0 n) (and (>=0 n) (not (= n 0)))) (test (not (>0 0))) (test (not (>0 -0))) (test (>0 1)) (test (>0 100)) (test (not (>0 -1))) (test (not (>0 -100))) (define (> a b) (>0 (- a b))) (test (> 10 3)) (test (not (> -1 5)))
 (test true) (test false) (test 0) (test 1) (define x true) (define y false) (define z 0) (define w 1) (if x 17 42) (if y 17 42) (if z 17 42) (if w 17 42) (test x) (test y) (test z) (test w)
 ; test bindings (test true) (test false) ; a test fails if it does not return true (test 17) ; a test fails if it does not return true (define a 5) a (test (= a 5)) (define x true) (define y false) (define z 0) (define w 1) (test x) ; x is "truthy" (test y) ; y is "falsey" (test z) ; z is "falsey" from a test binding perspective (test w) ; w is "falsey" from a test binding perspective ;; different in if expressions!!! (if x 17 42) ; x is "truthy" (if y 17 42) ; y is "falsey" (if z 17 42) ; z is "truthy" from a if expression perspective (if w 17 42) ; w is "truthy" from a if expression perspective ; why is this useful in if expression ; it would be fun to implement n > 0 as a function :) ; return n - 1 if n > 0, otherwise return "None" ; in ocaml: we would return an "int option" (define (f n) (if (= n 0) ; #f ; unbound variable "#f" ; oops racket brain false (- n 1))) (f 0) (f 1) ; (define (g n) ; (let ((y (f n))) ; (if y ; ; "Some" case ; ... do something with y now that we know it's an integer ; ; "None" case ; ... y is false, do some kind of error recovery))) ; functions and the dynamic environment ; dynamic environment: empty (define x 1) ; dynamic environment: x -> 1 (define (f n) ; every time a function is defined, save the current dynamic environment (+ n x)) ; dynamic environment: x -> 1, f -> (function definition, ; the defining environment sneakily modified with ; f -> this pair) ; ;; or, better put: f -> (function definition, this whole environment) (f 0) ; call a function ; 0. look up f in the current dynamic environment ; - get the function definition and the defining environment ; 1. evaluate the arguments in the current dynamic environment ; 2. evaluate the body of the definition of f in a new (temporary!) dynamic environment ; - start with the defining environment (lexical scope!!) ; - extended by argument name -> argument value for all arguments ; 3. the value that the body evaluates to is the return value of the function ; (f 17) (define x 2) x (f 0) ; 1!! (f 17) ; dynamic scope: ; - evaluate the function body in the environment of the caller ; lexical scope (static scope): ; - evaluate the function body in the environment from when it was defined ; - requires saving the old dynamic environment!! ; what about recursion? ; imagine dynamic environment is empty at this point (define (pow base exp) (if (= exp 0) 1 (* base (pow base (- exp 1))))) (pow 2 3) ; evaluate: ;(if (= exp 0) ; 1 ; (* base (pow base (- exp 1)))) ; in an environment ; base -> 2, exp -> 3 ;; ; why would OCaml not just make all functions recursive? ;; ; (define foo 17) ; ; (define (foo x) ; (+ x foo)) ;; no way to refer to the variable foo here, ; ;; because foo is bound to the function foo ; ; (foo 10)
 (* variants *) (* "one of" type a value of a variant has "one of" its component *) type my_variant = | Name of string | Height of int let a = Name "james" (* choose string/Name *) let b = Height 75 (* choose int/Height *) (* list that has strings and ints!!! *) let l: my_variant list = [a; b]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment