Multiple Return Values in Standard ML

Standard ML (SML) has support for multiple return values through tuples. This feature is used often in idiomatic SML, for example to return both result and error values from a function.

(* The '* int * int' in this function signature shows that
   the function returns a tuple of 2 ints. *)
fun vals () = (3, 7)

fun main () =
  let
    (* Here we use pattern matching to destructure the tuple
       returned by vals(), similar to multiple assignment. *)
    val (a, b) = vals()
    val _ = print (Int.toString a ^ "\n")
    val _ = print (Int.toString b ^ "\n")

    (* If you only want a subset of the returned values,
       use the wildcard pattern '_'. *)
    val (_, c) = vals()
    val _ = print (Int.toString c ^ "\n")
  in
    ()
  end

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

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

$ sml multiple_return_values.sml
3
7
7

In Standard ML, functions always return a single value, but that value can be a tuple, which effectively allows for multiple return values. Pattern matching is used to destructure these tuples, providing a similar convenience to multiple assignment in other languages.

SML doesn’t have a direct equivalent to the blank identifier _ used in assignment, but it does use _ as a wildcard pattern in pattern matching, which serves a similar purpose when destructuring tuples or other data structures.

While SML doesn’t have built-in printing functions for every type like some other languages, it’s common to convert values to strings (e.g., using Int.toString) before printing.

Accepting a variable number of arguments is not as straightforward in SML as it is in some other languages, but similar functionality can be achieved using lists or other data structures.