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

lec10live.ml

parent 05ab165c
type expr =
| Constant of int
| Negate of expr (* like "-(1 + 2)" would be `a` below *)
| Add of expr * expr
| Mult of expr * expr
let a = Negate (Add(Constant(1), Constant(2)))
let rec eval((e: expr)): int =
match e with
| Constant(n) -> n
| Negate(e') -> -(eval e')
| Add(e1, e2) -> eval e1 + eval e2
| Mult(e1, e2) -> eval e1 * eval e2
(*
"meta language" vs "object language"
- meta language: the language in which the interpreter is written
- hw1/hw3: metalanguage == java
- this file: ocaml
- object language: the language being implemented
- hw1: trefoil v1
- hw3: trefoil v2
- this file: expr
funny example: you can write an OCaml interpreter in OCaml
- metalanguage and object language would be the same!
many languages are implemented
- GCC is a C compiler written in C
- Javac is a Java compiler written in Java
- ...
tangent: using features of the metalanguage to implement features of the object language
- sort of funny: use "the same" feature from the ML to implement that feature in OL
- example: trefoil v2 we have integer arithmetic
- suggested implementation strategy: use java "int"s (32 bits)
- OCaml ints are 31 bits! (or 63 bit longs)
- this inheritance is sort of cheating!
- let's us avoid spelling out the semantics of the object language
- trefoil has functions
- we implement trefoil in a language with ~functions
- John C. Reynolds -- PL researcher from back in the day
- "definitional interpreters"
- you can always do it without the feature in the metalanguage, but it might be annoying
*)
let max((n1: int), (n2: int)): int =
if n1 > n2 then n1 else n2
(** return the largest constant in the tree *)
let rec max_const((e: expr)): int =
match e with
| Constant(n) -> n
| Negate(e') -> max_const e'
| Add(e1, e2) -> max(max_const e1, max_const e2)
| Mult(e1, e2) -> max(max_const e1, max_const e2)
(** return the total number of Add nodes in the tree *)
let rec number_of_add_ops((e: expr)): int =
match e with
| Constant(n) -> 0
| Negate(e') -> number_of_add_ops(e')
| Add(e1, e2) -> 1 + number_of_add_ops(e1) + number_of_add_ops(e2)
| Mult(e1, e2) -> number_of_add_ops(e1) + number_of_add_ops(e2)
(* define our own polymorphic option type *)
type 'a myoption =
| MyNone
| MySome of 'a
let x: int myoption = MySome(3)
let x2 = MySome(3)
(* let x3: int myoption = MySome("hello") *)
let x4 = MySome("hello")
let y: int myoption = MyNone
let y2 = MyNone
let f((o: int myoption)): int =
match o with
| MyNone -> 17
| MySome(n) -> n + 4
(* built in lists are almost like:
type 'a list =
| []
| :: of 'a * 'a list
*)
let rec sum((l: int list)): int =
match l with
| [] -> 0
| x::xs -> x + sum(xs)
(* new kind of pattern: tuple pattern *)
let t: int * string * bool = (1, "hello", false)
let s =
(* bad style but illustrates tuple patterns *)
match t with
| (n, s, b) -> Int.to_string(n) ^ s ^ Bool.to_string b
(* shortcut: let expression *)
let s2 =
let (n, s, b) = t in
Int.to_string(n) ^ s ^ Bool.to_string b
(* "shortcut" shows up all the time in PL
- "syntactic sugar"
- adds new syntax to "sweeten" the language
- the meaning is explained by converting the feature into existing features
*)
(*
let this_will_raise_exception =
let x::xs = [] in
x
*)
let this_will_work =
let x::xs = [1; 2; 3] in
x
(* nested patterns *)
(* sum the list, treating None as 0 *)
let rec sum_int_option_list((l: int option list)): int =
match l with
| [] -> 0
| x::xs ->
match x with
| None -> sum_int_option_list(xs)
| Some(n) -> n + sum_int_option_list(xs)
(* now with nested patterns *)
let rec sum_int_option_list2((l: int option list)): int =
match l with
| [] -> 0
| None::xs -> sum_int_option_list2(xs)
| Some(n)::xs -> n + sum_int_option_list2(xs)
(* didn't quite finish this example on Monday *)
let rec sum_int_option_pair_list3((l: (int option * int option) list)): int =
match l with
| [] -> 0
| (None, None)::xs -> sum_int_option_pair_list3(xs)
| (None, Some(n2))::xs -> sum_int_option_list3(xs)
| (Some(n1), None)::xs -> sum_int_option_list3(xs)
| (Some(n1), Some(n2))::xs -> sum_int_option_list3(xs)
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