Presentation is loading. Please wait.

Presentation is loading. Please wait.

SML-97 Specifics SML/NJ 110 cs7120(Prasad) L4-SML.

Similar presentations


Presentation on theme: "SML-97 Specifics SML/NJ 110 cs7120(Prasad) L4-SML."— Presentation transcript:

1 SML-97 Specifics SML/NJ 110 cs7120(Prasad) L4-SML

2 Getting Started Invoking interpreter (actually a compiler in interactive mode!) % sml Loading ML program - use “~/eg.sml”; Accessing a structure element Int.max; Opening a structure open Real; Top-level environment contains a selected set of useful functions. A more complete set of standard functions is organized into structures (Int, Real, String, etc) that forms the standard basis. - Real.Math.sqrt(4.0) - List.take(2,[1,2,3]) Interpreter vs compiled interactive mode cs7120(Prasad) L4-SML

3 Expressions ~ 1 + 21 ; tab, newline,…
val it = 20 : int; “1\t\na\t\n”; tab, newline,… “\\\”” ^ “abc”; Slash, double quotes, concatenation - #“a”; character #“Z” < #“a” ; “abd” < “ac”; 1 <> 2; 1<2 orelse 1.0/0.0; if true andthen not (1>=2) then 3.0 else ; if-then control structure is legal, but not expression. Unary minus vs binary minus: different symbols;; Lexicographic ordering cs7120(Prasad) L4-SML

4 “Tip of the” Type Errors
; No coercion real(1) + 2.0; 1 + floor(2.0); 1/2; #“a” ^ “bb”; if true then #“a” else “bb”; 1::[2.0]; real is not an equality type. Portability reasons. (Cf. (int->int) is not an equality type for computability reasons.) In the absence of rounding errors, (r=s) is equivalent to (r<=s) andalso (s<=r). Real.== (2.0, 2.0) is true; floor, ceil, trunc, round, … op / : real * real -> real 1 div 2; (op div) (1,2); = 0 1 mod 2; (op mod) (1,2); = 1 cs7120(Prasad) L4-SML

5 Identifiers Alphanumeric Identifiers Symbolic Identifiers Separators
a’1_b2, B2_bomber, …, etc ordinary variables ’a’b’c, ’’a, etc type variables Symbolic Identifiers <>=, @%$#, |?:&, +, /, etc Separators ( , ) , [ ,] ,{ ,} , ” , . , , , ; ML is case-sensitive. 1. Keywords are reserved words and cannot be used as identifiers. 2. Certain standard sequence of special characters such as >=, <=, <>, etc has special meaning and cannot be used as symbolic identifiers. (Can control associativity and precedence of operators.) 3. Care must be taken to introduce spaces in expressions appropriately to ensure proper tokenization. 8+~4 generates an error while 8 + ~4 is fine because +~ is intrepreted as a symbolic identifier. cs7120(Prasad) L4-SML

6 Variables Identifiers vs Variables vs Values Environment vs Store
Adding new variable and binding val i = 10; val i = [1,2,3]; (Cf., “:=” in Pascal and “=” in C.) Static scoping (Closure) val a = 2; fun ax(x) = a * x; val a = 5; ax 10; (* ax 10 = 20 *) If f depends on g, then modifying the definition of g requires reloading of definition of f in the interactive mode because of static binding. (On the other hand, accidental reuse of older identifiers cannot interfere with the definitions that use the earlier bindings.) (Dynamic binding earned notoriety for breaking existing code with seemingly innocuous but unfortunate (re)definitions.) Reference to global definitions thro free variables (closure) implies that the earlier definitions cannot be garbage collected even though they are not visible or directly accessible. cs7120(Prasad) L4-SML

7 Patterns Illegal cases: Term Matching (cf. Unification)
fun merge (L as x::xs, M as y::ys) = … fun comb(_,0) = … fun f ((x,y)::z::xs) = … Illegal cases: fun length [x]) = … fun f (x+1) = … fun g (0.0) = … Term Matching (cf. Unification) Match only term-trees: i.e., concrete data structures, not (computable) expressions. Constructor patterns = Normal form of representation Other term patterns are reduced to constructor patterns through computation using definitions Syntactic match supported not semantic equivalence testing (which requires simplified theorem proving). Unification requires non-trivial equality checking. Require associativity of :: before inferring type of (x,y)::z::xs ) List of pairs 2) List of List of pairs Term-matching binds values to variables :: actual is ground – formal pattern has variables (but with no implicit equality constraints) cs7120(Prasad) L4-SML

8 Error: duplicate variable in pattern
fun same (n,n) = 0 | same _ = 1; Error: duplicate variable in pattern (* requires equational reasoning *) fun fp nil = 0 | fp (x::xs) = 1; val fp = fn : 'a list -> int fun feq xs = if (xs = nil) then 0 else 1; val feq = fn : ''a list -> int nil and [] are synonymous. Patterns that require data structure match is allowed Matching against nil is not considered an equality test. fun same (n,m) = if (n=m) then 1 else works for equality type n, m Patterns that may involve additional computation and propagation of equality constraints are banned. (Unification vs term-matching) cs7120(Prasad) L4-SML

9 Match Expressions val rec reverse = fn nil => nil
| x::xs => [x] ; rule : pattern => expression case x < y of true => x | false => y ; if x < y then #“1” else 1; Error: Type of rules do not agree. cs7120(Prasad) L4-SML

10 Skip what follows cs7120(Prasad) L4-SML

11 Limitations on the use of polymorpic functions
fun id x = x; (* id :’a -> ’a *) id 0; (* id : int -> int *) id id 0; (* id :(int -> int) -> (int -> int) *) val id = fn x => x; (* id :’a -> ’a *) To ensure that a bound variable has the same meaning as its binding, the variable introduced by a val-declaration is allowed to be polymorphic only if the right-hand side is a value (and not a computation). val id = fn x => hd (x :: nil); (* legal *) val id1 = fn x => [(x,x),(x,x)]; (* legal *) val id2 = fn x => x 1; (* legal *) val id3 = fn x => (x 1, x “a”); (* ILLEGAL *) What constitutes a representation for function value? (normal form) Expressions presented for evaluation cannot have polymorphic type because “values” are not polymorphic???? cs7120(Prasad) L4-SML

12 val J = id id; (*illegal*)
Motivation: Contexts (such as (J 5, J “a”) ) that replicate the binding may impose conflicting requirements on the type. (cf. Multiple evaluation of side-effect causing expressions.) (cf. Referential transparency violated if two occurrences of an expression is not equivalent to two occurrences of its value.) Value Restriction is too conservative. val k = nil; (* illegal *) In older SML and traditional denotational descriptions, the first two declarations are equivalent. J1 : int -> int J2: string -> string Value restriction not necessary. It is a sufficient condition that is easy to state. However, it does throw away some perfectly “good-looking” programs. val x = i++; vs val x = 5; (x,x) (i++, i++) (x,x) (simplicity > flexibility) Unanswered questions: 1. For the example at hand, can we not derive the most general type for J and use its instances? Give an example that forebodes doom, motivating value restriction. cs7120(Prasad) L4-SML

13 Value Restriction on Polymorphic Declaration
ILLEGAL: id id; id foldr; LEGAL: fun J x = id id x; id id “a”; id Int.max; let val v = id id in v “a” end; cs7120(Prasad) L4-SML

14 Polymorphic type variable: ’a
Generalizable (universal quantification) for every type T, there is an instance of this object Non-generalizable (existential quantification) there exists a fixed but arbitrary type T for this object For compile-time guarantees, SML-97 requires that the expressions at the top-level be such that the generalizable interpretation of type variables is appropriate. cs7120(Prasad) L4-SML

15 Non-expansive Expressions
A constant or a variable is non-expansive. A function definition is non-expansive. A tuple of non-expansive expressions is non-expansive. A non-expansive expression may be preceded by a data/exception constructor. Expressions that are not of these forms are expansive and are not allowed to have type variables. Generates a “type variable not generalizable” error. cs7120(Prasad) L4-SML

16 Non-generalizable type variable error
All the following conditions must be met for the error to occur: The expression is at the top-level. The type of the expression involves at least one type variable. The form of the expression does not meet the conditions for it to be non-expansive. cs7120(Prasad) L4-SML

17 Examples id id ; (* error *) (id, id) ; id (id:int-> int) ;
val it = <poly-record> : ('a -> 'a)*('b -> 'b) id (id:int-> int) ; [id, id] val it = [fn,fn] : ('a -> 'a) list (* Allowed by SML97 even though according to Ullman’s book it is illegal? *) Why value restriction? Strong sufficient condition that can be checked by mere inspection. Convenient but inflexible. There are examples that compromise type safety whose signatures contain type variables. However, we still need examples to justify value-strong restriction. That is we need cases where any type constraint back-propagation can cause damage to type safety. Emphasis on top-level If the expression is not top-level but instead appears in a local declaration context such that all its uses (restricted incarnations) are known, then we can permit it. (PTO.) cs7120(Prasad) L4-SML

18 (cont’d) (* Error: operator and operand don't agree.*)
let val x = (id id) in x(1) end; (* Legal (id id) is not top-level. *) in (x 1, x “a”) end; (* Error: operator and operand don't agree.*) (id 1, id “a”) ; (* val it = (1,"a") : int * string *) let val x = id Allowed because the final expression type is int. (value 1) If the expression were top-level, at a later time conflict could be introduced due to global scope. 2. First x: int -> int conflicts with second x : string -> string (nongeneralizable) 3. Separate invocations of a polymorphic function (using generalizable variable) cs7120(Prasad) L4-SML


Download ppt "SML-97 Specifics SML/NJ 110 cs7120(Prasad) L4-SML."

Similar presentations


Ads by Google