Pointers in Standard ML

Standard ML (SML) doesn’t have a direct equivalent to pointers, but we can use references to demonstrate a similar concept. References in SML allow us to create mutable variables, which can be used to simulate some aspects of pointer behavior.

(* We'll show how references work in contrast to values with
   2 functions: zeroval and zeroref. zeroval has an
   int parameter, so arguments will be passed to it by
   value. zeroval will get a copy of ival distinct
   from the one in the calling function. *)
fun zeroval (ival : int) =
    let
        val _ = ival := 0
    in
        ()
    end

(* zeroref in contrast has an int ref parameter, meaning
   that it takes a reference to an int. The ! operator in the
   function body then dereferences the reference to get its current value.
   Assigning a value to a reference changes the
   value at the referenced location. *)
fun zeroref (iref : int ref) =
    iref := 0

(* Main function to demonstrate the usage *)
fun main () =
    let
        val i = ref 1
        val _ = print ("initial: " ^ Int.toString(!i) ^ "\n")
        
        val _ = zeroval (!i)
        val _ = print ("zeroval: " ^ Int.toString(!i) ^ "\n")
        
        (* We pass the reference i directly to zeroref *)
        val _ = zeroref i
        val _ = print ("zeroref: " ^ Int.toString(!i) ^ "\n")
        
        (* In SML, we can't print the memory address of a reference *)
        val _ = print "SML doesn't provide direct access to memory addresses\n"
    in
        ()
    end

(* Run the main function *)
val _ = main()

To run this program, save it to a file (e.g., references.sml) and use an SML interpreter or compiler. For example, with Standard ML of New Jersey (SML/NJ):

$ sml references.sml
initial: 1
zeroval: 1
zeroref: 0
SML doesn't provide direct access to memory addresses

In this SML version:

  1. We use ref to create mutable references, which are similar to pointers in some ways.
  2. The ! operator is used to dereference a reference (get its value).
  3. The := operator is used to assign a new value to a reference.
  4. zeroval doesn’t change the value of i in main, but zeroref does because it has a reference to the mutable variable.
  5. SML doesn’t provide direct access to memory addresses, so we can’t print the “pointer” (reference) itself.

This example demonstrates how SML’s references can be used to achieve behavior similar to pointers in other languages, allowing you to pass mutable state between functions.