ML - Basics">

Standard ML - Basics

Posted by Beetle B. on Thu 28 July 2016

Comments

Comments begin with (* and end with *). You can nest comments.

Statement Ends

In the REPL, each statement must end in a semicolon. This is optional in files.

Basic Bindings

val x = 34;

This will bind x to 34 and make it an integer.

You can put apostrophe in variable names (e.g. xs').

Shadowing

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!

Environments

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.

Conditional

val y = if z < 0 then 0-z else z;

Loading Code in SML Interpreter

In the interpreter, type:

use "filename.sml";

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:

  • Syntax
  • Type Checking: Produce a type for the expression or fail.
  • Evaluation: Produces a value, throws an exception, or gets stuck in an infinite loop.

Integer

Syntax: A sequence of digits

Type-checking: type int

Evaluation: It evaluates to itself.

Addition

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.

Conditionals

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…

Bools

A bool has value true or false. Note that an int cannot be used when a bool is expected.

Operators

Negation

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).

Division

/ is for float. Use div for integers.

Logical Operators

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.

Comparison Operators

<, >, =, <>, >=, <= are comparison operators for int.

Reals have the above, but no = and no <>.

You cannot do 3.0 >= 2. This is a type violation!

String Concatenation

^ will concatenate two strings. It is an infix operator.

Function Composition

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.

Multiple Expressions

(e1 e2 e3 e4)

(* Short for... *)
(((e1 e2) e3) e4)