View
223
Download
1
Embed Size (px)
Citation preview
Cse321, Programming Languages and Compilers
104/18/23
Lecture #2, Jan. 10, 2007•Evaluating expressions•Defining functions•Case exp•Let exp•Exceptions•Defining new data and constructors•Pattern matching over constructors•Binary Search trees•Expressions•Tokens•Simple Lexer•Common errors.
Cse321, Programming Languages and Compilers
204/18/23
A note about handing in homework• When you hand in homework, please hand in the
following:1. The complete file as you wrote it, with no extra text, etc. I should be able
to load the file (as is) into SML.
2. A trace of your test of the program. This should include commands to load the file above, and a sequence of tests that test the code you wrote. Many times I ask you to extend some code. Be sure and test the code you wrote, not my code. My code has enough errors I don’t want to know about new ones, unless it affects your code.
3. You should include enough tests to convunce me your program works. You should include enough tests so that every statement in your program is exercised at least once in some test. 3 tests per function is the minimum, some functions may require more if they have many paths.
4. An optional cover sheet where you provide any additional information I need to grade your assignment.
– Be sure that your name is clearly written on the top left hand side of what you hand in.
– If your program doesn’t load, a trace of the errors may help me figure out what went wrong, so I can suggest a fix.
Cse321, Programming Languages and Compilers
304/18/23
More on SML
• We have a lot to learn about SML
• Well will go over some high level stuff today
• We also have the three lab sessions. I hope everyone can attend at least one of the sessions.– FAB INTEL Lab (FAB 55-17) downstairs by the Engineering and
Technology Manangement’s departmental offices
– Friday Jan. 12, 2007. 4:00 – 5:30 PM
– Tueday Jan. 16, 2007 4:00 – 5:30
– Friday Jan. 19, 2005. 4:00 – 5:30 PM
Cse321, Programming Languages and Compilers
404/18/23
Evaluation vs. Declaration evaluation- 5;val it = 5 : int- 3+4;val it = 7 : int
declaration- val tim = 5 : int
evaluation- tim + 7;val it = 12 : int
declaration- fun plusone x = x + 1;val plusone = fn : int -> int
The green italicized text is what the user writes, the
black text is what the system responds
Cse321, Programming Languages and Compilers
504/18/23
Declaration
• Declarative forms– val x = 7
– fun inc x == x+1;
– data Tree = Tip Int | Node Tree Tree
• Declarations bring new names into scope
• Evaluation is mostly for two purposes– In the interactive, loop for testing and debugging
– In a file, for initialization and side effects
• Programs– A program in SML is a file with a number of function declarations.
Cse321, Programming Languages and Compilers
604/18/23
Functions• Functions are usually defined in Files and
loaded into to SML. Example:– use “lect01.sml”
• Predefined Functions on numbers– Type of numbers: int and real– overloaded operators +, *, - , / , mod– Conversion functions: floor, ceiling, trunc, round
• Predefined Functions on Booleans– Relational operators
< > <= >= = != – Combinators
andalso orelse– Examples
- 5 > 7
false
- 1==4
false
Cse321, Programming Languages and Compilers
704/18/23
Finding type of functions- length
val it = fn : 'a list -> int
-
- op @;
val it = fn : 'a list * 'a list -> 'a list
-
- rev;
val it = fn : 'a list -> 'a list
-
- op +;
val it = fn : int * int -> int
Cse321, Programming Languages and Compilers
804/18/23
Defining and using Functions
• Defined by writing equations (sometimes more than 1)
• By Declaration: fun plusone x = x+1;
• By Lambda expression: fn x => x + 1– These are anonymous functions, and are probably new to you.
Don’t let them scare you.
• Application by juxtaposition (no parenthesis needed)
• plusone 8 • (fn x => x + 1) 8
Cse321, Programming Languages and Compilers
904/18/23
Syntax of Expressions
• operators– x + 5
• function application– inc x– map f xs
• list syntax– [ ]– [x+4, inc 3]
• case expressions– case x of
pat => exp
• let expressions– let val x = exp
in exp end
• if– if x<0 then exp else exp
• anonymous functions– (fn x => x + 1)
• constants5 integers
“abc” strings
12.4 real
#”a” characters
true,false booleans
• tuples(5,x *4)
(if x then 1 else 3,
“abc”,
true)
Cse321, Programming Languages and Compilers
1004/18/23
Case expressions
val ex1 =
case [1,2,3] of
[] => 0
| (1::xs) => if null xs
then 1
else 2
| (x::xs) => 3;
Clauses separated
by “|”
Keyword of
Clauses can span multiple
lines
The semicolon ends the “val ex1 = ” declaration not the
case exp.
Cse321, Programming Languages and Compilers
1104/18/23
Using case in fun definition• The case expression uses patterns
fun length(y) =
case y of
[] => 0
| (x :: xs) => 1 + (length xs)
• In the pattern: (x :: xs)– x, stands for the hd(y)
– xs, stands for the tl(y)
• Much more about patterns later in the lecture!
Cse321, Programming Languages and Compilers
1204/18/23
Let expressions
• Let expressions allow programmers to make local declaration for both values and functions.
val ex2 =
let val x = 34
fun f x = x - 3
in f x - 4 end;
Multiple declarations allowed, both “val” and
“fun”, no separators necessary
The scope of the new declarations is the
expression between the key words “in” and “end”
Cse321, Programming Languages and Compilers
1304/18/23
Multi Argument functions: Tuples
• Functions of more than 1 argument:• tuples• currying
• fun evenprod (x,y) = even(x * y);• fun evenprod x y = even(x * y);
• Conditional Expressions: If
• fun minpair (x,y) = if x < y then x else y;
Cse321, Programming Languages and Compilers
1404/18/23
Multi Argument functions: By Currying
fun f a b c = a + b + c + 1; • has type• val f = fn : int -> int -> int -> int • READ AS: int -> (int -> (int -> int))
– f : int -> int -> int -> int – f 2 : int -> int -> int – f 2 3 : int -> int
• fun f (a,b,c) = a + b + c + 1;• val f = fn : (int * int * int) -> int
• Be sure you understand the difference between the two styles.
• fun evenprod (x,y) = even(x * y);– (int * int) -> bool
• fun evenprod’ x y = even(x * y);– int -> int -> bool
Cse321, Programming Languages and Compilers
1504/18/23
Binding and Scope
• ML has a structure which forms nested lexical scopes
val x = 34;
fun foo x y z = let val a = 10
val b = 12
in (x – a) + y * b end;
fun bar x = let data Pair = P of int * boolean
in case (P x True) of
(P a b) -> if b then a else b + 1
end;
x
x, y, z
a, b
x,
P
a,b
foo
bar
Cse321, Programming Languages and Compilers
1604/18/23
Bindings, and recursive scope:val x = 12;fun f x = x + 2;fun g y = x + 2;
• fun bindings are just like val bindings
val f = (fn x => x + 2);
• But NOT RECURSIVE PROGRAMS! why?
fun plus x y = if x = 0 then y else 1 + (plus (x-1) y); val rec plus = fn x => fn y => if x = 0 then y else 1 + (plus (x-1) y);
this is an anonymous function, often called a
lambda expression
Cse321, Programming Languages and Compilers
1704/18/23
Pattern Matching Definitions:
fun and true false = false
| and true true = true
| and false false = false
| and false true = false;
• (ORDER MATTERS)
• Variables in Patterns:
fun and true true = true
| and x y = false
Note that “and” has more than
1 equation.
Cse321, Programming Languages and Compilers
1804/18/23
Rules for patterns:
• Patterns has only Constructors, (true, false, :: ) variables (x, y, z) , and constants (3, “red”).
• All the patterns (on the left) should have
compatible types
• The cases should be exhaustive
• There should be no ambiguity as to which case applies. (Ordering fixes ambiguity if there is any)
Cse321, Programming Languages and Compilers
1904/18/23
Lists in ML
• Constant lists
• [3,6,8]
• ["red", "yellow", ""]
• []
Cse321, Programming Languages and Compilers
2004/18/23
Construction of lists
• The Empty List
[]
• The "Cons" (op :: ) Constructor
4::[3,7];
val it = [4,3,7] : int list
• Concatenation
[3,4] @ [6,7,8]
val it = [3,4,6,7,8] : int list
Cse321, Programming Languages and Compilers
2104/18/23
Taking Lists Apart? hd [1,2,3]
1
? tl [1,2,3]
[2, 3]
? List.take ([1,2,3],2)
[1,2]
? List.drop ([1,2,3],2)
[3]
Cse321, Programming Languages and Compilers
2204/18/23
Cons (::) and [ ] are enough• [1,2,3] -> 1 :: (2 :: (3 :: [ ]))
• If the infix operator (::) is right associative• 1 :: 2 :: 3 :: [ ]
• All lists are constructed in one of two ways
• [ ]
or• (x :: xs) for some element x and list xs
Cse321, Programming Languages and Compilers
2304/18/23
More about patterns• Patterns can be nested• Patterns can have wild-cards
fun double y =
case y of
(a :: (b :: [])) => true
| _ => false
• Special syntax for list Patterns
fun exactlytwo x =
Case x of
[] => false
| [x] => false
| [x,y] => true
| (x :: xs) => false;
These features can be used in “fun”
declarations with multiple clauses as
well as in “case” expressions!
Cse321, Programming Languages and Compilers
2404/18/23
Review
• A program is a collection of functions• Functions are written by a series of
equations• Function bodies are expressions• Case, let, and exceptions are rich constructs
in ML.• Case allows pattern matching without
defining a new function.• Let allows us to introduce local bindings. It
allows us to introduce more than 1 binding.• Pattern matching is a new way of making a
choice when programming• There is a rich set of functions defined over
lists– new functions can be written using pattern mathcing
Cse321, Programming Languages and Compilers
2504/18/23
Introducing new kinds of data• Objects of most types are allocated in the
heap.
• The abstract interface is to use constructor (functions) rather than malloc
• This provides some level of type checking, and abstraction.
• Constructor functions automatically defined. No need to define like constructors in Java
• Two kinds of constructors. Constants like nil ([]), and functions like cons (::).
Cse321, Programming Languages and Compilers
2604/18/23
Constant Constructors• Constant constructors are constant
• Can be allocated once at compile-time.
• Like constant pointers that never change.
• The nil constructor [] for lists is an example.
Cse321, Programming Languages and Compilers
2704/18/23
Constructor Functions• Constructor functions allocate in the heap.• Each constructor may allocate a different
amount of memory• If we had to do this in C we might write
list cons (void * hd, list tl)
{ list Block = (list) malloc (sizeof (struct listStruct));
Block->Tag = consTag;
Block->Data.consData.hd = hd;
Block->Data.consData.tl = tl;
return (Block);
};
• In ML this is done automatically.
Cse321, Programming Languages and Compilers
2804/18/23
Introducing new data and constructors
datatype Tree = Tip | Node of Tree * int * Tree;
val tree1 = Node(Node(Tip,4,Tip) ,7 ,Node(Tip,10,Tip));
Constant constructor, contains no data
Constructor function. Contains 3 fields. The function Node takes a triple with 3
components. The “of” keyword is used for constructor functions
7
4 10
Cse321, Programming Languages and Compilers
2904/18/23
Pattern Matching functions
fun sum Tip = 0
| sum (Node(x,n,y)) = n + sum x + sum y;
• using binary search tree invariant
fun search n Tip = false
| search n (Node(x,m,y)) =
if n=m
then true
else if (n < m) then search n x
else search n y;
Two constructors, two clauses
The bar “|” separates clauses
Cse321, Programming Languages and Compilers
3004/18/23
Searching Trees.fun search n Tip = false
| search n (Node(x,m,y)) =
if n=m then true
else if (n < m) then search n x else search n y;
• val ex4 = search 3 tree1;• search 3 (Node(Node(Tip,4,Tip),7,Node(Tip,10,Tip)))• search 3 (Node (Tip,4,Tip))• search 3 Tip• false
• val ex5 = search 10 tree1;• search 10 (Node(Node(Tip,4,Tip),7,Node(Tip,10,Tip)))• search 10 (Node (Tip,10,Tip))• true
Cse321, Programming Languages and Compilers
3104/18/23
Example Expressions
datatype Exp
= Const of int
| Add of Exp * Exp
| Mult of Exp * Exp
| Sub of Exp * Exp;
val exp1 = Add(Const 4,Const 3); (* 4+3 *)
val exp2 = Mult(exp1,exp1); (* (4+3)*(4+3) *)
Mult(Add(Const 4,Const 3)
, Add(Const 4,Const 3));
Cse321, Programming Languages and Compilers
3204/18/23
Pattern matching functions
fun ExpValue (Const n) = n
| ExpValue (Add(x,y))
= ExpValue x + ExpValue y
| ExpValue (Mult(x,y))
= ExpValue x * ExpValue y
| ExpValue (Sub(x,y))
= ExpValue x - ExpValue y;
Cse321, Programming Languages and Compilers
3304/18/23
Review
• New data structures are introduced by the datatype declaration (like Tree, Exp, and Token).
• A datatype declaration introduces – constructor constants (Tip, and [] )
– constructor functions (Node, Add, Mult)
» every time one of these is applied some memory is automatically allocated in the heap.
• Functions consuming these data structures make choices by using pattern matching– written using equations
– generally one equation for each kind of constructor.
– Patterns in clauses shouldn’t overlap. If they do the first pattern (in the order they are written) “wins”.
Cse321, Programming Languages and Compilers
3404/18/23
ML and compilers: Tokens
datatype Token
= Id of string
| Plus
| Times
| Eql
| Int of int
| Illegal;
id(z) eql id(x) plus id(pi) times int(12)
z = x + pi * 12
Cse321, Programming Languages and Compilers
3504/18/23
Simple Lexer(* lex : char list -> (Token * char list) *)fun lex [] = (Illegal,[]) | lex (#" " :: cs) = lex cs | lex (#"+" :: cs) = (Plus,cs) | lex (#"*" :: cs) = (Times,cs) | lex (#"=" :: cs) = (Eql,cs) | lex (c :: cs) = if Char.isAlpha c then ident c cs else if Char.isDigit c then literal c cs else (Illegal,c::cs);
fun test s = let val (token,cs) = lex(String.explode s) in (token,String.implode cs) end;
String to a list of characters from the
String library
List of charactersTo a string
Lex returns a pair, note the type and
the code
Char constants
Library functions on Char
Cse321, Programming Languages and Compilers
3604/18/23
Lexer helper functions
fun extend x (xs, cs) = ((x::xs), cs);
(* ident: char -> char list -> (Token * char list) *)
fun ident c cs =
let fun help x [] = ([x],[])
| help x (c::cs) =
if Char.isAlpha c
then extend x (help c cs)
else ([x],c :: cs)
val (lexeme,rest) = help c cs
in (Id (String.implode lexeme),rest) end;
Make an Id token
Collect a prefix which is all alpha, and the rest of the list. Help returns a
pair
Add a char to the first component of the pair
Cse321, Programming Languages and Compilers
3704/18/23
More help(* literal: char -> char list -> (Token * char list) *)
fun literal c cs = let fun help x [] = ([x],cs) | help x (c::cs) = if Char.isDigit c then extend x (help c cs) else ([x],c :: cs) val (lexeme,rest) = help c cs in case Int.fromString (String.implode lexeme) of NONE => (Illegal,rest) | SOME n => (Int n,rest) end;
datatype ‘a option = NONE | SOME of ‘a;
Turn the list of Char into a string, then use the library function to turn the string into an int. The translation
may fail, see datatype option.
Cse321, Programming Languages and Compilers
3804/18/23
Common Errors
• Forgetting the “of” in the type of a constructor function:
datatype Trans
= Trans Start * Label * Finish;
S02code.sml:129.24 Error: syntax error: inserting INFIX
datatype Trans
= Trans of Start * Label * Finish;
Cse321, Programming Languages and Compilers
3904/18/23
Note that some operators are overloaded
- 4 + 5;
val it = 9 : int
- 2.3 + 5.6;
val it = 7.9 : real
-
- fun f x y = x + y;
std_in:19.15 Error: overloaded variable cannot be resolved: +
-
- fun f x (y:int) = x + y;
val f = fn : int -> int -> int
Cse321, Programming Languages and Compilers
4004/18/23
* and comments
- fun product x = fold (op *) x 0;
std_in:21.26 Error: unmatched close comment
-
-
- fun product x = fold (op * ) x 0;
val product = fn : int list -> int
-
note the space between
* and )
Cse321, Programming Languages and Compilers
4104/18/23
Bad patterns- fun length [] = 0 | length x :: xs = 1 + length xs;std_in:26.14-26.15 Error: NONfix pattern requiredstd_in:25.5-26.34 Error: clauses don't all have same number of patterns
std_in:25.5-26.34 Error: data constructor :: used without argument in pattern
std_in:25.1-26.34 Error: rules don't agree (tycon mismatch)
expected: 'Z list -> int found: 'Y * 'X * 'W -> int rule: (x,_,xs) => + : overloaded (1,length xs)
- fun length [] = 0 | length (x::xs) = 1 + length xs;val length = fn : 'a list -> int
Cse321, Programming Languages and Compilers
4204/18/23
Look closely at the types!- fun appendall [] = []
| appendall (x::xs) = x :: (appendall xs);
val appendall = fn : 'a list -> 'a list
(* OOPs the wrong type *)
- fun appendall [] = []
| appendall (x::xs) = x @(appendall xs);
val appendall = fn : 'a list list -> 'a list
Cse321, Programming Languages and Compilers
4304/18/23
The missing “end” bug
fun e n =
let val seq = 0 upto n
fun term x = 1.0 / (real (fact x))
in term;
/tmp/sml.tmp.o29014:5.9 Error: syntax error found at EOF
Cse321, Programming Languages and Compilers
4404/18/23
The missing “val” bug
fun e n =
let seq = 0 upto n
fun term x = 1.0 / (real (fact x))
in term end;
/tmp/sml.tmp.p29014:3.5-3.7 Error: syntax error: inserting VAL
Cse321, Programming Languages and Compilers
4504/18/23
The missing “fun” bugfun e n = let val seq = 0 upto n term x = 1.0 / (real (fact x))in term end;
/tmp/sml.tmp.q29014:4.32 Error: unbound variable or constructor: x
/tmp/sml.tmp.q29014:4.5-4.8 Error: unbound variable or constructor: term
/tmp/sml.tmp.q29014:4.10 Error: unbound variable or constructor: x
/tmp/sml.tmp.q29014:5.4-5.7 Error: unbound variable or constructor: term
/tmp/sml.tmp.q29014:3.5-4.34 Error: operator and operand don't agree (tycon mismatch)
operator domain: int * int operand: int * bool in expression: upto (0,= (# #,<exp> <exp>))
Cse321, Programming Languages and Compilers
4604/18/23
Remember “as” is a keyword
fun length [] = 0
| length (a::as) = a + (length as);
/tmp/sml.tmp.r29014:3.18 Error: syntax error: replacing RPAREN with OP
/tmp/sml.tmp.r29014:3.36 Error: syntax error found at RPAREN
-
Cse321, Programming Languages and Compilers
4704/18/23
Assignment #2CS321 Prog Lang & Compilers Assignment # 2Assigned: Jan 10, 2007 Due: Mon. Jan 17, 2007
Using the primitive types (int, boolean, etc) and the data structures defined in the notes for the second lecture. Tree etc. Include your program file, and a listing where you test your functions. You must include 3 tests for each function.
1) write a function which computes n factorial. E.g. fact 0 --> 1 fact 3 --> 6 fact 5 --> 120(You will need to use recursion.)
2) write even and odd functions. e.g. even 4 --> true odd 10 --> false odd 3 --> true
(Hint the infix function "mod" is useful. 6 mod 3 --> 0, 4 mod 3 --> 1)
3) write the ncopies function. For example: ncopies 3 5 --> [5,5,5] ncopies 4 "a" --> ["a","a","a","a"] ncopies 0 true --> [](You will need an ‘if’ expression and recursion)
4) Use pattern matching to write a function to compute the depth of a Tree(you will need to include the datatype declaration for Tree in your file. You will need 2
equations. You will need to use pattern matching. You will need recursion.)
5) Can you think of a function over trees? Explaing what it does in a comment, and then write it in ML.