Typing Typing Typing and ML Typing and ML “A name for a set of values and some operations which can be performed on that set of values.” CSC324 “A collection of computational entities that share some common property.” Winter 2007 E.g., Sheila McIlraith reals integers Acknowledgement: strings The material in these notes is derived from a variety of sources, including: int � bool Elements of ML Programming (Ullman), (int � int) � bool Concepts in Programming Languages (Mitchell) and the notes of Wael Aboelsaddat, Tony Bonner, What constitutes a type is language dependent. Eric Joanis, Gerald Penn, and Suzanne Stevenson. 1 2 Uses/Merits Uses/Merits Type errors Type errors Definition Program organization and documentation • A type error occurs when execution of program • Separate types for separate concepts is not faithful to the intended semantics, i.e., the • Indicate intended use of declared identifiers programmer’s intended interpretation. Identify and prevent errors Hardware errors • Compile-time or run-time checking can prevent • function call y() where y is not a function meaningless computation such as • may cause jump to instruction that does not 5 + true - Charlotte contain a legal op code Unintended semantics Support optimization • int_add(3, 4.5) • Compiler can generate better code if it knows • not a hardware error but the bits representing 4.5 what’s in each variable, e.g., short integers will be interpreted as an integer require fewer bits. • Access record component by known offset 3 4
Type Safety Type Safety Compile- Compile - vs. Run vs. Run- -time time & Type Checking & Type Checking • Scheme: run-time (dynamic) type checking • A programming language is type safe if no (car x) checks first to make sure x is a list program is allowed to violate its type distinctions. • ML and Java: compile-time (static) type checking – Scheme, ML and Java are type safe. – C and C++ are not. f(x) must have f: A � B and x:A • The process of verifying and enforcing the Trade-off: constraints of types is called type checking . • Both prevent type errors • Run-time checking slows down execution • Compile-time checking restricts program flexibility • Type checking can either occur at compile- E.g., Scheme list elements can have diff. types, time (static) or at run-time (dynamic). ML lists elements must have the same type • Static typing can make programming more difficult, initially. It’s harder to get things to compile, and 5 6 Type Checking Type Checking Type Inference Type Inference vs. Type Inference vs. Type Inference This is type inference: E.g. A3 := B4 + 1; Standard Type Checking: Q: What type is A3 and B4 ? int f(int x) { return x+1;}; A: Must be integer E.g. if test then … int g(int y) {return f(y+1)*2;}; Q: What type is test ? – Look at body of each function and use declared A: Must be Boolean types to check for agreement. Sound type system: a type system in which all types can always be inferred in any valid program. Type Inference: • Looks at code without type info and figures out ML’s Type Inference Algorithm (Mitchell): what types could have been declared. 1. Assign a type to the expression and each • ML is designed to make type inference subexpression by using the known type of a tractable. symbol of a type variable. 2. Generate a set of constraints on types by using • A cool algorithm! the parse tree of the expression. • Widely regarded as an important language 3. Solve these constraints by using unification, which innovation. is a substitution-based algorithm for solving systems of equations. • ML type inference gives you some idea of how other static analysis algorithms might work. It uses constraint satisfaction techniques. 7 8
ML ML ML: Main Features ML: Main Features Functional Language Developed at Edinburgh (early ’80s) as Meta- HOFs, recursion strongly encouraged, etc. Language for a program verification system Combination of Lisp and Algol features • Now a general purpose language Strong, static typing w/ type inference • There are two basic dialects of ML Quite a fancy type system! – Standard ML (1991) & ML 2000 Polymorphism – Caml (including Objective Caml, or OCaml) a function can take arguments of various types Abstract & recursive data types A pure functional language supported through an elegant type system, • Based on typed lambda calculus the ability to construct new types, and • Grew out of frustration with Lisp! constructs that restrict access to objects of a • Major programs can be written w/o variables given type through a fixed set of ops defined for that type. Widely accepted Pattern matching • reasonable performance (claimed) Function as a template • can be compiled Exception handling • syntax not as arcane as LISP (nor as simple…) Allow you to handle errors/exception Elaborate module system Most highly developed of any language 9 10 ML Patterns & Declarations ML: Tutorial Review ML: Tutorial Review Patterns & Declarations (see your tutorial notes for complete details) Patterns can be used in place of variables <pat> ::= <id>|<tuple>|<cons>|<record>|… SML environment basics Value declaration (general form): Each ML expression has a type associated w/ it. val <pat> = <exp> • Interpreter builds the type expression • Cannot mix types in expressions E.g. (Declarations), - val myTuple = (“Jen”,”Brad”); • Must explicitly coerce/type-case val myTuple = (“Jen",“Brad") : string * string e.g. real(2) + 3.0 : real - val(x,y) = myTuple; Data types (w/ operators): val x = “Jen" : string Basic: unit, bool, integer, real, string val y = “Brad" : string Constructors : list, tuple, array, record, function operators infix, can be overloaded. - val myList = [1,2,3,4]; val myList = [1,2,3,4] : int list Read-eval-print - val x::rest = myList; • Compiler infers type before compiling & executing. val x = 1 : int E.g., val rest = [2,3,4] : int list - (5+3)-2; > val it = 6 : int - If 5>3 then “Bob” else “Carol”; >val it=“Bob” : string 11 12
ML ML Declarations Pattern Matching Declarations Pattern Matching Pattern matching is powerful: ML has let too! • Allows programmers to see the arguments • No more heads and tails (cars/cdrs) Local declarations: - let val x = 2+3 in x*4 end; Tupple pattern matching val it = 20 : int -val v=((2, "Test"),(3.2,#"A")); val v = ((2,"Test"),(3.2,#"A")) : (int * string) * (real * char) - let -val ((i,s),(r,c))=v; val m=3 (* ; is optional *) val i = 2 : int val n=m*m val s = "Test" : string in val r = 3.2 : real m+n val c = #"A" : char end; val it = 12 : int -val (p1,p2)=v;val p1 = (2,"Test") : int * string val p2 = (3.2,#"A") : real * char -val (_,(r,_))=v; (*_ (“don’t care”) matches anything!*) val r = 3.2 : real 13 14 ML ML Pattern Matching Functions Pattern Matching Functions Like Scheme there are: Record pattern matching • Defined functions -type stInfo={name:string, id:int, gpa:real}; • Anonymous functions type stInfo = {gpa:real, id:int, name:string} • Recursive functions • Higher-order functions -val st1:stInfo={name=“jen", id=123, gpa=4.0}; • And you can pass functions as parameters, and return val st1 = {gpa=4.0,id=123,name="jen"} : stInfo them as values. -val {name=N, gpa=G, id=_}=st1; (* order doesn't matter! *) Unlike Scheme, val G = 4.0 : real • we call these things “functions” not “procedures” val N = “jen" : string f: A � B means -val {gpa,id, name}=st1; (* this is an abbreviation in ML *) for every x � A, val gpa = 4.0 : real val id = 123 : int some element y=f(x) � B val name = “jen" : string f(x) = run forever terminate by raising an exception -val {name,...}=st1l; (* to specify subset of fields *) val name = “jen" : string A function maps a type to another one: accepts only one argument. What if we need multiple arguments? 15 16
Recommend
More recommend