Search code examples
syntaxsmlsmlnj

print statement causing error?


The syntax in this language is confusing.

fun bar a =
  print (Int.toString a);
    0

compiles. No idea why emacs indents the 0 though.

fun bar a =
  print (Int.toString a)
    0

Throws an error.

Error: operator is not a function [tycon mismatch]
  operator: unit
  in expression:
    (print (Int.toString a)) 0


fun foo a =
  if a < 0
  then
      0
  else
      0

compiles.

fun foo a =
  if a < 0
  then
      print (Int.toString a);
      0
  else
      0

throws an error.

syntax error: replacing  SEMICOLON with  EQUALOP

Wat?

I can't make any sense of this.


Solution

  • It seems you have trouble understanding where semicolons can be used in SML. There are two main places where they're allowed:

    1. Inside a parenthesized group: (a; b). That means that a; b is not valid. You need to wrap it inside parentheses.

    2. In between in and end in a let block. However, you don't parentheses here:

    let
      val foo = ...
    in
      a;
      b;
      c
    end
    

    So, your last example should be:

    fun foo a =
      if a < 0
      then (print (Int.toString a); 0)
      else 0
    

    They can also be used to separate top-level expressions or declarations inside a file or at the REPL, but they're optional for that purpose. It's why your first example compiled.