Search code examples
smlsmlnjml

sml syntax having a hard time looking up documentation


I am trying to "simulate" a pass by value result function with the following code but there seems to be a syntax error. I've been looking through sml tutorials but I'm having a hard time figuring out why this doesn't work

1 val x = ref 0;
2 fun p(y': int ref)=
3 let
4   val y = !y'
5     in
6         let
7             y = 1
8             in
9                 let x := 0 
10                 in
11                 y' := y
12                 end
13         end  
14 end     
15 p(x)

Solution

  • In the let <decs> in <exp>, <decs> needs to be one or more declarations.

    In your case, on line 7 you do y = 1 - note, this is not an assigment, but a comparison. That is, in C++ it would be equivalent to doing y == 1. You cannot assign to non-ref variables. (And in general, you want to avoid ref variables as much as possible.) You could do val y = 1 in its place, in which case you create a new value by the name of y, which shadows over the old y (but does not change it; you create a new value).

    Likewise, on line 9, you do x := 0, which is not a declaration, but an expression, which assigns the value 0 to the reference value x, and then returns unit.

    In addition, you can do multiple declarations in your let statements, so you don't need the nesting you do.

    Finally, you write p(x) on the toplevel. You can only write expressions on the toplevel, if the declaration preceding ends with a semicolon; otherwise it believes it to be a part of the declaration. That is

    val a = 5
    6
    

    is interpreted to be

    val a = 5 6
    

    In short, you could rewrite it to this:

    val x = ref 0;
    
    fun p(y': int ref)=
    let
      val y = !y' (* this line might as well be deleted. *)
      val y = 1
    in
      x := 0;
      y' := y
    end;
    
    p(x)
    

    Or, the shorter version, since the SML has good type inference:

    val x = ref 0;
    
    fun p y' = (x := 0; y' := 1);
    
    p x
    

    I will say this, though; if you come from a language like C++ or similar, it may be tempting to use 'a refs a lot, but you will often find, that minimizing the use of them often leads to cleaner code in SML. (And other functional languages.)