In the REPL, each statement must end in a semicolon. This is optional in files.
val x = 34;
This will bind x to 34 and make it an integer.
You can put apostrophe in variable names (e.g. xs').
val x = 34; val x = 23;
In this code, x is not replaced with 23. Instead, a new x is created, and it shadows the original x. The environment will show both of the variables.
Also, the type of the new x need not match the type of the old x. It really is a new variable altogether!
There is a static and a dynamic environment. The static environment holds information about the types of each variable. The dynamic environments hold the results of expressing each variable.
val y = if z < 0 then 0-z else z;
Loading Code in SML Interpreter
In the interpreter, type:
to load the code in the file. It will execute each statement as if typed in.
Do not reload it without restarting the interpreter. This is because it will merely shadow the original bindings, somewhat polluting the environment (try it and see!)
Syntax, Type Checking and Evaluation
There are three aspects to each expression in Standard ML:
- Type Checking: Produce a type for the expression or fail.
- Evaluation: Produces a value, throws an exception, or gets stuck in an infinite loop.
Syntax: A sequence of digits
Type-checking: type int
Evaluation: It evaluates to itself.
Syntax: e1+e2 where e1 and e2 are expressions.
Type-checking: We require e1 and e2 to be int. Then the result is int. Otherwise type checking fails.
Evaluation: If e1 evaluates to v1 and e2 evaluates to v2, then the final evaluation is v1+v2.
Syntax: if e1 then e2 else e3. if, then, else are keywords. e1, e2, e3 are expressions.
Type-checking: Require e2 to be bool and e2, e3 to be of the same types. The type for the whole expression is the same as the type of e2.
Evaluation: As you would expect…
A bool has value true or false. Note that an int cannot be used when a bool is expected.
Cannot write -5 and expect it to work. - is used for subtraction, which takes two operators. Either write 0-5 or ~5 (or even ~ 5).
/ is for float. Use div for integers.
andalso is and.
orelse is or.
Both have short circuit behavior. Because of this, these are not functions! Because f(e1, e2) will evaluate both e1 and e2.
not is not. It is a function.
<, >, =, <>, >=, <= are comparison operators for int.
Reals have the above, but no = and no <>.
You cannot do 3.0 >= 2. This is a type violation!
^ will concatenate two strings. It is an infix operator.
o is an infix function composition:
val result = (f o g) x val same = f(g(x))
Running Multiple Statements
(e1 ; e2)
In the above code, e1 is evaluated, and its result is discarded. The result of the expression is the value of e2. This is useful if we evaluate e1 only for its side effects.
(e1 e2 e3 e4) (* Short for... *) (((e1 e2) e3) e4)