Presentation is loading. Please wait.

Presentation is loading. Please wait.

Cse321, Programming Languages and Compilers 1 6/21/2015 Standard ML In this course we will use an implementation of the language Standard ML Notes by Riccardo.

Similar presentations


Presentation on theme: "Cse321, Programming Languages and Compilers 1 6/21/2015 Standard ML In this course we will use an implementation of the language Standard ML Notes by Riccardo."— Presentation transcript:

1 Cse321, Programming Languages and Compilers 1 6/21/2015 Standard ML In this course we will use an implementation of the language Standard ML Notes by Riccardo Pucella, about programming in ML http://www.cs.cornell.edu/riccardo/smlnj.html The SML/NJ Homepage has lots of useful information: http://www.smlnj.org// http://www.smlnj.org// You can get a version to install on your own machine there. I will use the version 110.57 of SML. Earlier versions probably will work as well. I don’t foresee any problems with other versions, but if you want to use the identical version that I use in class then this is the one.

2 Cse321, Programming Languages and Compilers 2 6/21/2015 Characteristics of SML Applicative style –input output description of problem. First class functions –pass as parameters –return as value of a function –store in data-structures Less Importantly: –Automatic memory management (G.C. no new or malloc) –Use of a strong type system which uses type inference, i.e. no declarations but still strongly typed.

3 Cse321, Programming Languages and Compilers 3 6/21/2015 Syntactic Elements Identifiers start with a letter followed by digits or other letters or primes or underscores. –Valid Examples: a a3 a’b aF –Invalid Examples: 12A Identifiers can also be constructed with a sequence of operators like: !@#$%^&*+~ Reserved words include – fun val datatype if then else – if of let in end type

4 Cse321, Programming Languages and Compilers 4 6/21/2015 Interacting The normal style for interaction is to start SML, and then type definitions into the window. Types of commands –4 + 5; –val x = 34; –fun f x = x + 1; Here are two commands you might find useful. val pwd = OS.FileSys.getDir; val cd = OS.FileSys.chDir; To load a file that has a sml program type Use “file.sml”;

5 Cse321, Programming Languages and Compilers 5 6/21/2015 The SML Read-Typecheck-Eval-Print Loop Standard ML of New Jersey v110.57 [built: Mon Nov 21 21:46:28 2005] - - 3+5; val it = 8 : int - - print "Hi there\n"; Hi there val it = () : unit - - val x = 22; val x = 22 : int - - x+ 5; val it = 27 : int - -val pwd = OS.FileSys.getDir; -val pwd = fn : unit -> string - val cd = OS.FileSys.chDir; val cd = fn : string -> unit - Note the semicolon when you’re ready to evaluate. Otherwise commands can spread across several lines.

6 Cse321, Programming Languages and Compilers 6 6/21/2015 Evaluation vs. Declaration evaluation - 5; val it = 5 : int -3+4; val it = 7 : int declaration - val it = 7 : int - val tim = 5 : int evaluation - tim + 7; val it = 12 : int declaration - fun plusone x = x + 1; val plusone = fn : int -> int

7 Cse321, Programming Languages and Compilers 7 6/21/2015 Bindings and environments, and 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);

8 Cse321, Programming Languages and Compilers 8 6/21/2015 Functions Functions are usually defined in Files and loaded into to SML. Example: – use “lect01.sml” Functions on numbers –Type of numbers: Int and Real –Conversion functions: floor, ceiling, trunc, round Functions on Booleans –Relational operators = == != –Combinators andalso orelse Examples - 5 > 7 false - 1==4 false

9 Cse321, Programming Languages and Compilers 9 6/21/2015 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

10 Cse321, Programming Languages and Compilers 10 6/21/2015 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 Functions of more than 1 argument: tuples currying

11 Cse321, Programming Languages and Compilers 11 6/21/2015 Multi Argument functions: Tuples fun evenprod (x,y) = even(x * y); Conditional Expressions: If fun minpair (x,y) = if x < y then x else y;

12 Cse321, Programming Languages and Compilers 12 6/21/2015 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)) 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

13 Cse321, Programming Languages and Compilers 13 6/21/2015 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.

14 Cse321, Programming Languages and Compilers 14 6/21/2015 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)

15 Cse321, Programming Languages and Compilers 15 6/21/2015 Lists in ML Constant lists [3,6,8] ["red", "yellow", ""] []

16 Cse321, Programming Languages and Compilers 16 6/21/2015 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

17 Cse321, Programming Languages and Compilers 17 6/21/2015 Taking Lists Apart ? hd [1,2,3] 1 ? tl [1,2,3] [2, 3] ? List.take (2,[1,2,3]) [1,2] ? List.drop (2,[1,2,3]) [3]

18 Cse321, Programming Languages and Compilers 18 6/21/2015 Libraries There are lots of predefined types and functions in SML when it starts up. You can find out about them at: http://www.smlnj.org//basis/pages/top-level-chapter.html Many more can be found in the other libraries. –http://www.standardml.org/Basis/manpages.html Libraries are encapsulated in Structures which are classified by Signatures (a list of what is in the structure).

19 Cse321, Programming Languages and Compilers 19 6/21/2015 Peeking inside a Structure To see what is inside a Structure you can open it. This is somewhat of a hack, but it is useful. Standard ML of New Jersey v110.57 [built: Mon Nov 21 21:46:28 2005] - signature S = INTEGER; signature INTEGER = sig eqtype int val precision : Int31.int option val minInt : int option val maxInt : int option val ~ : int -> int val + : int * int -> int val - : int * int -> int val * : int * int -> int val div : int * int -> int val mod : int * int -> int val quot : int * int -> int val rem : int * int -> int... end

20 Cse321, Programming Languages and Compilers 20 6/21/2015 fun lastone x = hd (rev x) fun prefix x = rev (tl (rev x)) In Class Exercise 1 Define prefix and lastone in terms of head tail and reverse. First make a file “S01code.sml” Start sml Change directory to where the file resides Load the file ( use “S01code.sml” ) Test the function Standard ML of New Jersey v110.57 - K; - val cd = OS.FileSys.chDir; val cd = fn : string -> unit - cd "D:/work/sheard/courses/PsuCs321/web/notes"; - use "S01code.sml"; [opening S01code.sml] val lastone = fn : 'a list -> 'a val prefix = fn : 'a list -> 'a list val it = () : unit - lastone [1,2,3,4]; val it = 4 : int

21 Cse321, Programming Languages and Compilers 21 6/21/2015 In Class Exercise 2 define map and filter functions – mymap f [1,2,3] = [f 1, f 2, f 3] – filter even [1,2,3,4,5] = [2,4] fun mymap f [] = [] | mymap f (x::xs) = (f x)::(mymap f xs); fun filter p [] = [] | filter p (x::xs) = if (p x) then x::(filter p xs) else (filter p xs); Sample Session - mymap plusone [2,3,4] [3, 4, 5] - myfilter even [1,2,3,4,5,6] [2, 4, 6]

22 Cse321, Programming Languages and Compilers 22 6/21/2015 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.

23 Cse321, Programming Languages and Compilers 23 6/21/2015 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)

24 Cse321, Programming Languages and Compilers 24 6/21/2015 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!

25 Cse321, Programming Languages and Compilers 25 6/21/2015 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 ”

26 Cse321, Programming Languages and Compilers 26 6/21/2015 Exceptions exception Error of string; fun error s = raise (Error s); fun ex3 b = (if b then error "true branch" else "false branch") handle Error message => message | other => raise other; A new exception is declared, it carries a string as error information. Exceptions can carry any kind of data. Exceptions can be raised, to short-circuit normal evaluation. Main computation returns a string Handler also returns a string A handler, like a “case” has multiple clauses, each can handle a different kind of error. Note “|” separating clauses. Keyword handle

27 Cse321, Programming Languages and Compilers 27 6/21/2015 Syntax of “case” vs “handle” “case” is before the computation being analyzed case (revonto (g x) 4) of [] => true | (x:xs) => false “handle” is after the computation that might fail (compute (g y) (length zs)) handle Error s => g s | BadLevel n => n+1 | other => raise other

28 Cse321, Programming Languages and Compilers 28 6/21/2015 Review 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. Exceptions allow non-standard control. The key operations on exceptions are “raise” and “handle” –Handle is like a “case” in that it can have several clause, separated by “|”, the first that matches “wins”

29 Cse321, Programming Languages and Compilers 29 6/21/2015 Introducing new kinds of data Objects of an inductive type 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 (::).

30 Cse321, Programming Languages and Compilers 30 6/21/2015 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.

31 Cse321, Programming Languages and Compilers 31 6/21/2015 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.

32 Cse321, Programming Languages and Compilers 32 6/21/2015 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 410

33 Cse321, Programming Languages and Compilers 33 6/21/2015 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

34 Cse321, Programming Languages and Compilers 34 6/21/2015 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

35 Cse321, Programming Languages and Compilers 35 6/21/2015 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));

36 Cse321, Programming Languages and Compilers 36 6/21/2015 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;

37 Cse321, Programming Languages and Compilers 37 6/21/2015 More SML In SML we use library functions all the time. –Int.toString –List.exists The list library functions are particularly useful. –These library functions often take a function as an argument –List.map : ('a -> 'b) -> 'a list -> 'b list –List.find : ('a -> bool) -> 'a list -> 'a option –List.filter : ('a -> bool) -> 'a list -> 'a list –List.exists : ('a -> bool) -> 'a list -> bool –List.all : ('a -> bool) -> 'a list -> bool –List.foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b It is worth studying these functions closely

38 Cse321, Programming Languages and Compilers 38 6/21/2015 List.map captures a pattern Add one to every element of a list –fun addone [] = [] – | addone (x::xs) = (x + 1) :: addone xs addone [2,3,4]  val it = [3,4,5] : int list Turn a list of ints into a list of strings –fun stringy [] = [] – | stringy (x::xs) = (Int.toString x) :: stringy xs stringy [2,5,9]  val it = ["2","5","9"]:string list Negate every element of a list –fun negL [] = [] – | negL (x::xs) = (not x) :: negL xs negL [true,3 > 4]  val it = [false,true] : bool list

39 Cse321, Programming Languages and Compilers 39 6/21/2015 Pattern fun addone [] = [] | addone (x::xs) = (x + 1) :: addone xs fun stringy [] = [] | stringy (x::xs) = (Int.toString x) :: stringy xs fun negL [] = [] | negL (x::xs) = (not x) :: negL xs fun map f [] = [] | map f (x::xs) = (f x) :: (map f xs) val ex1 = map (fn x => (x+1)) [2,3,4]; val ex1 = [3,4,5] : int list val ex2 = map Int.toString [2,5,7]; val ex2 = ["2","5","7"] : string list val ex3 = map not [true, 3 > 4]; val ex3 = [false,true] : bool list

40 Cse321, Programming Languages and Compilers 40 6/21/2015 Anonymous functions Study: (fn x => (x+1)) –It is an anonymous function. A function without a name. –It has one parameter “x” –It adds one to its parameter, and returns the result. (fn x => (x+1)) 4; val it = 5 : int Any non-recursive function can be written anonymously. –(fn x => x = 5) »Tests if its parameter is equal to 5 map (fn x => x=5) [1,4,5,3,5]; val it = [false,false,true,false,true] : bool list –(fn x => fn y => (x,y)) »Has two parameters »Returns a pair –(fn (x,y) => (not y, x+3)) »What is the type of this function?

41 Cse321, Programming Languages and Compilers 41 6/21/2015 List.find Used for searching a list. –List.find : ('a -> bool) -> 'a list -> 'a option Uses a function as a parameter to determine if the search is successful. E.g. Is there an even element in a list? List.find even [1,3,5]; val it = NONE : int option List.find even [1,3,4]; val it = SOME 4 : int option

42 Cse321, Programming Languages and Compilers 42 6/21/2015 List.find and anonymous functions List.find (fn x => x = "Tim") ["Tom", "Jane"]; val it = NONE : string option List.find (fn x => even x andalso x>10) [2,4,5,12]; val it = SOME 12 : int option

43 Cse321, Programming Languages and Compilers 43 6/21/2015 List.filter Filter keeps some elements, and throws away others. –List.filter : ('a -> bool) -> 'a list -> 'a list It uses a function ( p ) as a parameter to decide which elements to keep ( p x = true ), and which to throw away ( p x = false ) val ex6 = List.filter even [1,2,3,4,5,6]; val ex6 = [2,4,6] : int list

44 Cse321, Programming Languages and Compilers 44 6/21/2015 List.filter and anonymous functions val people = [("tim",22),("john",18),("jane",25),("tim",8)]; val ex7 = filter (fn (nm,age) => nm <> "tim" orelse age>10) people; val ex7 = [("tim",22),("john",18),("jane",25)] : (string * int) list

45 Cse321, Programming Languages and Compilers 45 6/21/2015 List.exists “exists” is like “find” in that it searches a list –but rather than the element that completes the search it is only interested in if such an element exists. –List.exists : ('a -> bool) -> 'a list -> bool Uses a function as a parameter to determine if the search is successful. val ex8 = List.exists even [2,3,5]; val ex8 = true : bool Note that even if only 1 element in the list causes the function to be true, exists returns true.

46 Cse321, Programming Languages and Compilers 46 6/21/2015 List.all List.all tests elements in a list for a property. It returns true only if every element has that property. –List.all : ('a -> bool) -> 'a list -> bool Uses a function as a parameter to perform the test. val ex9 = List.all even [2,4,5]; val ex9 = false : bool List.exists and List.all are related functions. They are duals. –not(List.all p xs) = List.exists (fn x => not(p x)) xs

47 Cse321, Programming Languages and Compilers 47 6/21/2015 List.foldr captures a pattern Add up every element in a list. fun sum [] = 0 | sum (x::xs) = x + (sum xs); Compute the maximum element in a list of natural numbers (Integers >= 0). fun maximum [] = 0 | maximum (x::xs) = Int.max(x,maximum xs); Compute if every element in a list of boolean is true. fun allTrue [] = true | allTrue (x::xs) = x andalso (allTrue xs);

48 Cse321, Programming Languages and Compilers 48 6/21/2015 Pattern fun sum [] = 0 | sum (x::xs) = x + (sum xs); fun maximum [] = 0 | maximum (x::xs) = Int.max(x,maximum xs); fun allTrue [] = true | allTrue (x::xs) = x andalso (allTrue xs); fun foldr acc base [ ] = base | foldr acc base (x::xs) = acc(x,foldr acc base xs);

49 Cse321, Programming Languages and Compilers 49 6/21/2015 See the pattern in use. fun sum [] = 0 | sum (x::xs) = x + (sum xs); fun sum xs = foldr (op +) 0 xs; fun maximum [] = 0 | maximum (x::xs) = Int.max(x,maximum xs); fun maximum xs = foldr Int.max 0 xs; fun allTrue [] = true | allTrue (x::xs) = x andalso (allTrue xs); fun allTrue xs = foldr (fn (a,b) => a andalso b) true xs;

50 Cse321, Programming Languages and Compilers 50 6/21/2015 Take another look What does this function do? fun ok [] = false | ok xs = not(exists (fn ys => xs=ys) (!old)) andalso not(exists (fn ys => xs=ys) (!worklist))

51 Cse321, Programming Languages and Compilers 51 6/21/2015 The Option Library - open Option; opening Option datatype 'a option = NONE | SOME of 'a exception Option val getOpt : 'a option * 'a -> 'a val isSome : 'a option -> bool val valOf : 'a option -> 'a val filter : ('a -> bool) -> 'a -> 'a option val join : 'a option option -> 'a option val app : ('a -> unit) -> 'a option -> unit val map : ('a -> 'b) -> 'a option -> 'b option val mapPartial : ('a -> 'b option) -> 'a option -> ‘ b option

52 Cse321, Programming Languages and Compilers 52 6/21/2015 Interesting functions that use Options Int.fromString: string -> int option Int.fromString "234"; val it = SOME 234 : int option Int.fromString "abc"; val it = NONE : int option String.extract: string * int * int option -> string String.extract("abcde",1,SOME 3); val it = "bcd" : string String.extract("abcde",1,NONE); val it = "bcde" : string

53 Cse321, Programming Languages and Compilers 53 6/21/2015 More option functions List.find: ('a -> bool) -> 'a list -> 'a option List.find even [1,3,5]; val it = NONE : int option List.find (fn x => x="tim") ["tom","tim","jane"]; val it = SOME "tim" : string option List.getItem: 'a list -> ('a * 'a list) option –List.getItem [1,2,3,4]; –val it = SOME (1,[2,3,4]) –List.getItem []; –val it = NONE

54 Cse321, Programming Languages and Compilers 54 6/21/2015 Using While Loops fun ident c cs = let val xs = ref cs val x = ref c val ans = ref [] in while (not(null(!xs)) andalso Char.isAlpha (hd (!xs))) do ( ans := !ans @ [!x] ; x := hd(!xs) ; xs := tl(!xs) ); (Id (String.implode (!ans @ [!x])), !xs) end Don’t forget to test for empty list


Download ppt "Cse321, Programming Languages and Compilers 1 6/21/2015 Standard ML In this course we will use an implementation of the language Standard ML Notes by Riccardo."

Similar presentations


Ads by Google