Table of Contents

The posts in this series will be notes & highlights from working through “Programming in Standard ML” by Robert Harper. See Getting Started with Standard ML for a link to the PDF. I may not always use quotes in this series, but it should be assumed that any factual information about Standard ML that I write in this series has been obtained from the PDF above – this series is, in effect, a summarization of Robert Harper’s PDF.

Overview

Attributes of Standard ML:

Type-safe programming language

Statically typed

Extensible type system

Polymorphic type inference

Automatic storage management

Encourages functional (effect-free) programming

Allows imperative (effect-ful) programming where appropriate

Pattern matching

Extensible exception mechanism for handling error conditions

Expressive and flexible module system

Portable due to its precise definition

Portable standard basis library

Chapter 1 – Programming in Standard ML

This chapter provides a brief overview of the language by considering an implementation of a regular expression package. It was slightly more familiar to me because of my brief studies of Haskell; otherwise, I think it would’ve appeared very foreign. I prefer more of a bottom up approach as much as possible instead of looking at language features that haven’t been described.

Currying

I do think that currying & partial application are cool features. Consider the following function declaration:

val match : RegExp.regexp -> string -> bool

Coming from a non-currying background, I would describe match as a function that accepts a regular expression and a string, and returns a boolean value indicating whether the string matches the regular expression, but Robert describes it this way:

It contains a function match that, when given a regular expression, returns a function that determines whether or not a given string matches that expression.

This was one of the features that made a strong impression on me when I first started looking at functional programming languages.

Chapter 2 – Types, Values, and Effects

Computation in ML is of a somewhat different nature. The emphasis in ML is on computation by evaluation of expressions, rather than execution of commands.

An expressions has three characteristics:

It may or may not have a type

It may or may not have a value

It may or may not create an effect

Effects will be ignored until chapter 13, so until then, it’s assumed that all expressions are effect-free, or pure. A type is defined by specifying three things:

a name for the type,

the values of the type, and

the operations that may be performed on values of the type

Notes:

Negative numbers, as literals, are indicated with a tilde instead of a hypen e.g. ~7

div is used for integers, / for reals

A typing assertion has the form: exp : typ For example: 3 : int 4 div 3 : int ML does not perform any implicit conversions between types. Use real(3) + 4.3, or 3 + round(4.3) Conditional expression (exp1 and exp2 must have the same type): if exp then exp1 else exp2 if not exp then exp1 else exp2

Chapter 3 – Declarations

Once a variable is bound to a value, it is bound to it for life; there is no possibility of changing the binding of a variable once it has been bound. Examples of type bindings:

type float = real type count = int and average = real

Examples of value bindings:

val m : int = 3+2 val pi : real = 3.14 and e : real = 2.17

One thing to keep in mind is that binding is not assignment. The binding of a variable never changes; once bound to a value, it is always bound to that value (within the scope of the binding). However, we may shadow a binding by introducing a second binding for a variable within the scope of the ﬁrst binding.

Limiting scope with let expressions:

let val m : int = 3 val n : int = m*m in m*n end

The following expression evaluates to 54 because the binding of m is temporarily overridden during the evaluation of the let expression, then restored upon completion of this evaluation:

val m : int = 2 val r : int = let val m : int = 3 val n : int = m*m in m*n end * m