[MLton-user] SML newbie mistakes

Vesa Karvonen vesa.karvonen at cs.helsinki.fi
Thu Aug 10 07:13:58 PDT 2006


I've been thinking about starting a page (or two) aimed at
beginning SML programmers.  The page would briefly (not always
exhaustively) discuss some mistakes that SML newbies tend to make
and also some basic tips for using SML effectively.

Below is the raw wiki markup for a draft of the page describing
recurring newbie mistakes.  It is unlikely to be comprehensive.
If you can recall other newbie mistakes, or have corrections to
the below, just mention them.  I'll add the page to the wiki in
the near future unless there are objections.

-Vesa Karvonen

== Recurring newbie mistakes ==

Below are brief explanations of some recurring SML newbie gotchas.

=== and ===

It is a common mistake to misuse the {{{and}}} keyword or to not know how
to introduce mutually recursive definitions.  The purpose of the {{{and}}}
keyword is to introduce mutually recursive definitions of functions and
datatypes.  For example,

{{{#!syntax sml
fun isEven 0w0 = true
  | isEven 0w1 = false
  | isEven n = isOdd (n-0w1)
and isOdd 0w0 = false
  | isOdd 0w1 = true
  | isOdd n = isEven (n-0w1)
}}}

and

{{{#!syntax sml
datatype decl = VAL of id * pat * expr
           (* | ... *)
     and expr = LET of decl * expr
           (* | ... *)
}}}

You can also use {{{and}}} as a shorthand in a couple of other places, but
it is not obligatory.

=== Declarations and expressions ===

It is a common mistake to confuse expressions and declarations.  Normally
a SML source file should only contain declarations.  The following are
declarations:

{{{#!syntax sml
val v = ...
fun f x = ...
structure Struct = ...
signature SIG = ...
functor Fn (...) = ...
local ... in ... end
}}}

Note that {{{let ... in ... end}}} isn't a declaration.

To specify a side-effecting computation in a source file, you can write:

{{{#!syntax sml
val () = ...
}}}

=== Nested cases ===

It is a common newbie mistake to write nested case expressions.  See
["UnresolvedBugs"].

=== (op *) ===

It is common mistake to parenthesize {{{op *}}} as {{{(op *)}}}.
Unfortunately, {{{*)}}} is considered a comment terminator and will cause
a syntax error.  An extra space may be used: {{{(op * )}}}.  However,
parenthesizing {{{op}}} is redundant, even though it is a widely used
convention.

=== Semicolons ===

It is a common mistake to use redundant semicolons in SML code.  This is
probably caused by the fact that in a SML REPL, a semicolon (and enter) is
used to signal the implementation that it should evaluate the preceding
chuck of code as a unit.  In SML source files semicolons are really needed
in only two places.  Namely, in expressions of the form

 * {{{(exp ; ... ; exp)}}}, and
 * {{{let ... in exp ; ... ; exp end}}}.



More information about the MLton-user mailing list