Mechanics of a ML session. -- New Jersey ML (University of Ottawa, March, 2001) ========================== undergraduates can access ML on the Unix machines available to them. * to call ML: sml that's the 1991 version. To get the 1999 version: sml99 * to terminate a ML session: ^D (control-D) * Like most UNIX processes, ML can be suspended with ^Z and resumed with fg. All "programs" within ML are simply expressions. Some expressions result in additions to the current environment, for example, a function definition is an expression that adds the function name (and its executable code) to the environment. All your interaction with ML will be typing expressions, or loading in expressions ("programs") from a file. Within ML there are two prompts: - you may enter an expression to be evaluated. = you're in the middle of entering an expression (i.e. expressions may be typed across several lines). If you get this unexpectedly, you've probably forgotten to type a semicolon or closing double-quote. When you finish typing your expression (ending in semicolon, carriage-return) it will be evaluated. If no errors occur ML will print a line of the form val VAR = VALUE : TYPE where VALUE and TYPE are filled in appropriately and VAR is the name you gave to VALUE (if you don't specify a name, ML calls it "it") Reading in programs from a file. ================================ There is a built-in function called "use" that takes a string, interprets it as a filename, and evaluates the text in the file as if it had been typed in by the user. These files may "use" others. example: use "fred"; (* fred could contain use "mary"; *) Error Messages ============== Parse errors. ------------- example: if 1=2 then 3; Error: expected ELSE, found SEMICOLON Error: atomic expression expected, found SEMICOLON The error messages from this compiler are sometimes cryptic. Type errors. ------------ example: 1 + 3.2; Error: operator and operand don't agree (tycon mismatch) operator domain: int * int operand: int * real in expression: 1 + 3.2 explanation: "+" requires both its arguments to be of the same type. The first argument (1) is an integer ("int"), so ML infers that the second argument must also be int. However, the second argument actually provided (3.2) is of a type (real) that cannot be unified with the type (int) ML is expecting. example: fun F x = if x=0 then [] else [F (x-1)]; Error: pattern and expression in val rec dec don't agree (circularity) pattern: int -> 'S expression: int -> 'S list in declaration: F = (fn x => (case = of => | => )) explanation: This is the most subtle type error. The problem that ML cannot solve in this example is -- what is the type of the value returned by the function F ? (the argument to F is obviously an integer). The trouble arises in the "else" clause. According to this clause, the type returned by F (call it 'a) is a list whose elements are type 'a. ML cannot unify the type 'a with type 'a list. Runtime errors. --------------- example: 3 div 0; ("div" is integer division) [missed constant fold (1 >> 1)] uncaught exception Div All "failures" can be caught by the user program, with the "handle" mechanism. (3 div 0) handle Div => 99; [missed constant fold (1 >> 1)] val it = 99 : int