Cse321, Programming Languages and Compilers Lecture #2, Jan. 10, 2007 •Evaluating expressions •Defining functions •Case exp •Let exp •Exceptions •Defining new data and constructors •Pattern matching over constructors •Binary.

Download Report

Transcript Cse321, Programming Languages and Compilers Lecture #2, Jan. 10, 2007 •Evaluating expressions •Defining functions •Case exp •Let exp •Exceptions •Defining new data and constructors •Pattern matching over constructors •Binary.

Cse321, Programming Languages and Compilers
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.
11/7/2015
1
Cse321, Programming Languages and Compilers
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.
11/7/2015
2
Cse321, Programming Languages and Compilers
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
11/7/2015
3
Cse321, Programming Languages and Compilers
Evaluation vs. Declaration
evaluation
- 5;
val it = 5 : int
- 3+4;
val it = 7 : int
The green italicized text is
what the user writes, the
black text is what the
system responds
declaration
- val tim = 5 : int
evaluation
- tim + 7;
val it = 12 : int
declaration
- fun plusone x = x + 1;
val plusone = fn : int -> int
11/7/2015
4
Cse321, Programming Languages and Compilers
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.
11/7/2015
5
Cse321, Programming Languages and Compilers
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
11/7/2015
false
=
!=
6
Cse321, Programming Languages and Compilers
Finding type of functions
- length
val it =
- op @;
val it =
- rev;
val it =
- op +;
val it =
11/7/2015
fn : 'a list -> int
fn : 'a list * 'a list -> 'a list
fn : 'a list -> 'a list
fn : int * int -> int
7
Cse321, Programming Languages and Compilers
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
11/7/2015
8
Cse321, Programming Languages and Compilers
Syntax of Expressions
• operators
– x + 5
– if x<0 then exp else exp
• function application
– inc x
– map f
• anonymous functions
– (fn x => x + 1)
xs
• list syntax
– [ ]
– [x+4, inc 3]
• case expressions
– case x of
pat => exp
• let expressions
– let val x = exp
in exp end
11/7/2015
• if
• constants
5
“abc”
12.4
#”a”
true,false
integers
strings
real
characters
booleans
• tuples
(5,x *4)
(if x then 1 else 3,
“abc”,
true)
9
Cse321, Programming Languages and Compilers
Case expressions
Keyword
of
val ex1 =
case
[1,2,3]
of
Clauses can
Clauses
span multiple
separated
lines
[] => 0
by “|”
| (1::xs) => if null xs
then 1
else 2
| (x::xs) => 3;
11/7/2015
The semicolon ends
the “val ex1 = ”
declaration not the
case exp.
10
Cse321, Programming Languages and Compilers
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!
11/7/2015
11
Cse321, Programming Languages and Compilers
Let expressions
• Let expressions allow programmers to make local
declaration for both values and functions.
Multiple declarations allowed,
both “val” and “fun”, no
separators necessary
val ex2 =
let val x = 34
fun f x = x - 3
in f x - 4 end;
The scope of the new
declarations is the
expression between the key
words “in” and “end”
11/7/2015
12
Cse321, Programming Languages and Compilers
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;
11/7/2015
13
Cse321, Programming Languages and Compilers
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);
–
11/7/2015
int -> int -> bool
14
Cse321, Programming Languages and Compilers
Binding and Scope
• ML has a structure which forms nested lexical
scopes
x
val x = 34;
x, y, z
foo
fun foo x y z = let val a = 10
val b = 12
a, b
in (x – a) + y * b end;
bar
x,
fun bar x = let data Pair = P of int * boolean
P
in case (P x True) of
a,b
(P a b) -> if b then a else b + 1
end;
11/7/2015
15
Cse321, Programming Languages and Compilers
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);
this is an anonymous
function, often called a
lambda expression
• 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);
11/7/2015
16
Cse321, Programming Languages and Compilers
Pattern Matching Definitions:
fun
|
|
|
and
and
and
and
true false = false
true true = true
false false = false
false true = false;
Note that “and”
has more than 1
equation.
• (ORDER MATTERS)
• Variables in Patterns:
fun and true true = true
| and x y = false
11/7/2015
17
Cse321, Programming Languages and Compilers
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)
11/7/2015
18
Cse321, Programming Languages and Compilers
Lists in ML
• Constant lists
• [3,6,8]
• ["red", "yellow", ""]
• []
11/7/2015
19
Cse321, Programming Languages and Compilers
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
11/7/2015
20
Cse321, Programming Languages and Compilers
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]
11/7/2015
21
Cse321, Programming Languages and Compilers
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)
11/7/2015
for some element x and list xs
22
Cse321, Programming Languages and Compilers
More about patterns
• Patterns can be nested
• Patterns can have wild-cards
fun double y =
case y of
(a :: (b :: [])) => true
| _ => false
These features can be
used in “fun”
declarations with
multiple clauses as
well as in “case”
expressions!
• Special syntax for list Patterns
fun exactlytwo x =
Case x of
[] => false
| [x] => false
| [x,y] => true
| (x :: xs) => false;
11/7/2015
23
Cse321, Programming Languages and Compilers
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
11/7/2015
24
Cse321, Programming Languages and Compilers
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 (::).
11/7/2015
25
Cse321, Programming Languages and Compilers
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.
11/7/2015
26
Cse321, Programming Languages and Compilers
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.
11/7/2015
27
Cse321, Programming Languages and Compilers
Introducing new data and constructors
datatype Tree
Constant constructor,
contains no data
= Tip
| Node of Tree * int * Tree;
Constructor function. Contains 3 fields. The
function Node takes a triple with 3
components. The “of” keyword is used for
constructor functions
val tree1 =
Node(Node(Tip,4,Tip)
,7
,Node(Tip,10,Tip));
11/7/2015
7
4
10
28
Cse321, Programming Languages and Compilers
Pattern Matching functions
fun sum Tip = 0
| sum (Node(x,n,y)) = n + sum x + sum y;
Two constructors, two
clauses
• using binary search tree invariant
fun search n Tip = false
| search n (Node(x,m,y)) =
if n=m
then true
The bar “|”
separates
else if (n < m) then search n x
clauses
else search n y;
11/7/2015
29
Cse321, Programming Languages and Compilers
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
11/7/2015
30
Cse321, Programming Languages and Compilers
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));
11/7/2015
31
Cse321, Programming Languages and Compilers
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;
11/7/2015
32
Cse321, Programming Languages and Compilers
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”.
11/7/2015
33
Cse321, Programming Languages and Compilers
ML and compilers: Tokens
z = x + pi * 12
id(z)
eql
id(x)
plus
id(pi)
times
int(12)
datatype Token
= Id of string
| Plus
| Times
| Eql
| Int of int
| Illegal;
11/7/2015
34
Cse321, Programming Languages and Compilers
Simple Lexer
(* lex : char list -> (Token * char list) *)
fun lex [] = (Illegal,[])
Lex returns a pair,
| lex (#" " :: cs) = lex cs
note the type and
| lex (#"+" :: cs) = (Plus,cs)
the code
| lex (#"*" :: cs) = (Times,cs)
| lex (#"=" :: cs) = (Eql,cs)
Library functions
on Char
| lex (c :: cs) =
if
Char.isAlpha c then ident c cs
else if Char.isDigit c then literal c cs
Char
constants else (Illegal,c::cs);
String to a list of
characters from the
String library
fun test s =
let val (token,cs) = lex(String.explode s)
in (token,String.implode cs) end;
List of characters
To a string
11/7/2015
35
Cse321, Programming Languages and Compilers
Lexer helper functions
fun extend x (xs, cs) = ((x::xs), cs);
Add a char to the first
component of the pair
(* ident: char -> char list -> (Token * char list) *)
fun ident c cs =
Collect a prefix
let fun help x [] = ([x],[])
which is all alpha,
and the rest of the
| help x (c::cs) =
list. Help returns a
pair
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;
11/7/2015
Make an Id
token
36
Cse321, Programming Languages and Compilers
More help
(* literal: char -> char list -> (Token * char list)
*)
fun literal c cs
let fun help x
| help x
if
=
[] = ([x],cs)
(c::cs) =
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)
Turn the list of Char into a
string, then use the library
end;
datatype ‘a option
= NONE
| SOME of ‘a;
11/7/2015
function to turn the string
into an int. The translation
may fail, see datatype
option.
37
Cse321, Programming Languages and Compilers
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;
11/7/2015
38
Cse321, Programming Languages and Compilers
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
11/7/2015
39
Cse321, Programming Languages and Compilers
* and comments
- fun product x = fold (op *) x 0;
std_in:21.26 Error: unmatched close comment
note the space between
* and )
- fun product x = fold (op * ) x 0;
val product = fn : int list -> int
-
11/7/2015
40
Cse321, Programming Languages and Compilers
Bad patterns
- fun length [] = 0
| length x :: xs = 1 + length xs;
std_in:26.14-26.15 Error: NONfix pattern required
std_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
11/7/2015
41
Cse321, Programming Languages and Compilers
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
11/7/2015
42
Cse321, Programming Languages and Compilers
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
11/7/2015
43
Cse321, Programming Languages and Compilers
The missing “val” bug
fun e n
let seq
fun
in term
=
= 0 upto n
term x = 1.0 / (real (fact x))
end;
/tmp/sml.tmp.p29014:3.5-3.7 Error: syntax
error: inserting VAL
11/7/2015
44
Cse321, Programming Languages and Compilers
The missing “fun” bug
fun 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>))
11/7/2015
45
Cse321, Programming Languages and Compilers
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
-
11/7/2015
46
Cse321, Programming Languages and Compilers
Assignment #2
CS321 Prog Lang & Compilers
Assigned: Jan 10, 2007
Assignment # 2
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.
11/7/2015
47