Commit dc05e337 authored by James R. Wilcox's avatar James R. Wilcox
Browse files

push materials for today

parent 7f50e02f
(define x 1)
(test true)
; (test false) ; red squiggle!!
; structs
; - struct bindings generate 3 things:
; - constructor
; - one field accessor function per field
; - predicate
; cond
; - multiway branch
;; OCaml:
;; type expr = Constant of int | Plus of expr * expr
;;
;; let example = Plus(Constant(1), Constant(2))
;;
;; let rec eval (e: expr) =
;; match e with
;; | Constant(n) -> n
;; | Plus(e1, e2) -> eval e1 + eval e2
(struct constant num)
(struct plus e1 e2)
(define example
(plus
(constant 1)
(constant 2)))
(define (eval e)
(cond
((constant? e) (constant-num e))
((plus? e)
(+ (eval (plus-e1 e))
(eval (plus-e2 e))))
(true 'error)))
(eval example)
;; match
;; - sort of like cond
;; - takes one expression before the clauses "scrutinee"
;; - then a bunch of clauses
(define (eval e)
(match e
((constant n) n)
((plus e1 e2)
(+ (eval e1)
(eval e2)))))
(eval example)
;; a match clause is kind of like a cond clause
;; but the left hand side is a pattern!! (not an expression!!)
;; patterns are not expressions!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;; patterns are a new "syntactic category"
;; - a syntactic category is something "expression" or "binding"
;; "(test true)" is (the concrete syntax of) a binding but not an expression
;; "(+ 1 2)" is (the concrete syntax of) an expression but not a binding (except for top-level expressions)
;; new syntactic category -> new syntax -> new explanation of the concrete syntax -> new ast type -> new semantics
;; There are N kinds of patterns
;; - variable patterns: any variable
;; - wildcard pattern: "_"
;; - integer literal patterns: any integer literal
;; - nil pattern written "nil"
;; - cons pattern, written "(cons p1 p2)" where p1 and p2 are patterns
;; - struct pattern
;; - the name of a struct followed by as many patterns as there are fields
;; - (patterns nest!!!!!) james loves nesting!!! "compositionality"
;; example: (cons nil (cons nil nil))
; (match l
; ...
; ((cons x xs) (+ x (sum xs))))
;; The semantics of match expression
;; - consider a match expression "(match e (p1 b1) ... (pn bn))"
;; - semantics are:
;; - evaluate e in the current dynamic environment to get a value v
;; - then iterate through the clauses (pi bi) in order
;; - ask pi if it matches v
;; - if yes, pi produces bindings B.
;; stop this loop through the clauses and evaluate bi in an extended environment (B @ current environment)
;; and return the resulting value
;; - if no, continue the loop
;; - if you get to the end, error
;; The semantics of a pattern is what values it matches *and* if so what variables it binds
;; For each kind of pattern, I will tell you
;; - consider a variable x (as a pattern!!).
;; - given a value v, the variable pattern always matches, and introduces the binding x -> v
;; - consider a wildcard pattern "_". answer yes without any bindings.
;; - consider a integer literal pattern n.
;; - given a value v, if v = n, then yes (no bindings), otherwise no.
;; - nil (as a pattern!!) matches v exactly when v is nil (as an expression!!) and no bindings.
;; - consider a pattern (cons p1 p2)
;; - given a value v, if v is not a cons (expression!!) then "no"
;; - if v is a cons, write v as (cons v1 v2) for some values v1 v2
;; - ask p1 if it matches v1
;; - ask p2 if it matches v2
;; - if either says no, then the whole answer is no
;; - otherwise, both say yes with bindings B1 and B2,
;; and the whole answer is yes with bindings B1 @ B2
;;
;; - for a struct pattern "(s p1 ... pn)" (n can be 0) ...
;;;;;;
;; more match examples
; (match (cons nil nil)
; ((cons nil (cons 47 true)) ....))
(define (small-number? n)
(match n
(0 true)
(1 true)
(2 true)
(_ false)))
(small-number? 1)
(small-number? 42)
(small-number? -3)
; (define (sum l)
; (match l
; (nil 0)
; ((cons x xs) (+ x (sum xs)))))
;
; (define (f x xs) (cons x xs))
;
; (sum (cons 1 (cons 2 (cons 3 nil))))
;
;
; (define l nil)
; (define l2 (cons 1 2))
(* from last time: *)
type expr =
| Constant of int
| Plus of expr * expr
| Minus of expr * expr
| Variable of string
type association_list = (string * expr) list
type dynamic_environment = association_list
let rec lookup ((assoc_list : association_list), (key: string)): expr =
match assoc_list with
| [] -> failwith "lookup failed to find key"
| (key', v) :: list ->
if key' = key
then v
else lookup (list, key)
(* this time: change this function to return an expr instead of int *)
let rec eval(dynenv, e): expr =
match e with
| Constant(n) -> e
| Plus(e1, e2) ->
(* unpack the constants, add them, and pack them back into the Constant constructor *)
let Constant(n1) = eval (dynenv, e1) in
let Constant(n2) = eval (dynenv, e2) in
Constant(n1 + n2)
| Minus(e1, e2) ->
(* unpack the constants, add them, and pack them back into the Constant constructor *)
let Constant(n1) = eval (dynenv, e1) in
let Constant(n2) = eval (dynenv, e2) in
Constant(n1 - n2)
| Variable(x) ->
lookup (dynenv, x)
(* unit: built-in type has exactly value, written "()" *)
let f () =
print_endline "hello"
let x = f ()
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