Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture #2, Jan. 10, 2007 Evaluating expressions Defining functions

Similar presentations


Presentation on theme: "Lecture #2, Jan. 10, 2007 Evaluating expressions Defining functions"— Presentation transcript:

1 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.

2 A note about handing in homework
When you hand in homework, please hand in the following: The complete file as you wrote it, with no extra text, etc. I should be able to load the file (as is) into SML. 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. 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. 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.

3 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, :00 – 5:30 PM Tueday Jan. 16, :00 – 5:30 Friday Jan. 19, :00 – 5:30 PM

4 Evaluation vs. Declaration
- 5; val it = 5 : int 3+4; val it = 7 : int declaration - val tim = 5 : int - tim + 7; val it = 12 : int - 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

5 Declaration Declarative forms Declarations bring new names into scope
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.

6 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

7 Finding type of functions
- length val it = fn : 'a list -> int - - val it = fn : 'a list * 'a list -> 'a list - rev; val it = fn : 'a list -> 'a list - op +; val it = fn : int * int -> int

8 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

9 Syntax of Expressions operators if 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) constants integers “abc” strings real #”a” characters true,false booleans tuples (5,x *4) (if x then 1 else 3, “abc”, true)

10 | (1::xs) => if null xs then 1 else 2 | (x::xs) => 3;
Case expressions Keyword of val ex1 = case [1,2,3] of [] => 0 | (1::xs) => if null xs then 1 else 2 | (x::xs) => 3; Clauses can span multiple lines Clauses separated by “|” The semicolon ends the “val ex1 = ” declaration not the case exp.

11 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!

12 val ex2 = let val x = 34 fun f x = x - 3 in f x - 4 end;
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”

13 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;

14 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

15 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; foo x, y, z a, b bar x, P a,b

16 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 this is an anonymous function, often called a lambda expression

17 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.

18 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)

19 Lists in ML Constant lists [3,6,8] ["red", "yellow", ""] []

20 Construction of lists The Empty List []
The "Cons" (op :: ) Constructor 4::[3,7]; val it = [4,3,7] : int list Concatenation [6,7,8] val it = [3,4,6,7,8] : int list

21 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]

22 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

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!

24 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

25 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 (::).

26 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.

27 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.

28 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

29 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

30 Searching Trees. val ex4 = search 3 tree1;
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

31 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));

32 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;

33 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”.

34 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;

35 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; Lex returns a pair, note the type and the code Library functions on Char Char constants String to a list of characters from the String library List of characters To a string

36 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; Add a char to the first component of the pair Collect a prefix which is all alpha, and the rest of the list. Help returns a pair Make an Id token

37 More help fun literal c cs = let fun help x [] = ([x],cs)
(* 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.

38 Common Errors Forgetting the “of” in the type of a constructor function: datatype Trans = Trans Start * Label * Finish; S02code.sml: Error: syntax error: inserting INFIX = Trans of Start * Label * Finish;

39 Note that some operators are overloaded
; val it = 9 : int ; 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

40 note the space between * and )
* 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 )

41 Bad patterns - fun length [] = 0 | length x :: xs = 1 + length xs;
std_in: Error: NONfix pattern required std_in: Error: clauses don't all have same number of patterns std_in: Error: data constructor :: used without argument in pattern std_in: Error: rules don't agree (tycon mismatch) expected: 'Z list -> int found: 'Y * 'X * 'W -> int rule: (x,_,xs) => + : overloaded (1,length xs) | length (x::xs) = 1 + length xs; val length = fn : 'a list -> int

42 Look closely at the types!
- fun appendall [] = [] | appendall (x::xs) = x :: (appendall xs); val appendall = fn : 'a list -> 'a list (* OOPs the wrong type *) | appendall (x::xs) = xs); val appendall = fn : 'a list list -> 'a list

43 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

44 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: Error: syntax error: inserting VAL

45 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: Error: unbound variable or constructor: term /tmp/sml.tmp.q29014:4.10 Error: unbound variable or constructor: x /tmp/sml.tmp.q29014: Error: unbound variable or constructor: term /tmp/sml.tmp.q29014: Error: operator and operand don't agree (tycon mismatch) operator domain: int * int operand: int * bool in expression: upto (0,= (# #,<exp> <exp>))

46 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 -

47 Assignment #2 CS321 Prog Lang & Compilers Assignment # 2
Assigned: Jan 10, 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 --> 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 > [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.


Download ppt "Lecture #2, Jan. 10, 2007 Evaluating expressions Defining functions"

Similar presentations


Ads by Google