[MLton-user] SML newbie mistakes

Tom 7 twm at andrew.cmu.edu
Thu Aug 10 08:15:42 PDT 2006


We teach undergraduate courses in SML and see students struggle with this 
syntax error all the time:

fun length nil = 0
   | length h :: t = 1 + length t

(Same goes for non-infix constructors).

Running afoul of the value restriction is another common problem, 
especially before they even learn the imperative constructs in the 
language.

I've seen students be confused about equality types when writing code like 
this:

fun null l  =  l = nil


We also constantly see students using stale bindings while developing 
their programs interactively, but this is only a problem with interactive 
REPLs like SML/NJ.

Also, why does the isEven example use words instead of ints?

  Tom

> 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}}}.
>
> _______________________________________________
> MLton-user mailing list
> MLton-user at mlton.org
> http://mlton.org/mailman/listinfo/mlton-user
>
>


[ NEW! : http://tom7.org/       ]
[ OLD! : http://fonts.tom7.com/ ]



More information about the MLton-user mailing list