SML# Document Version 3.7.1
23 Declarations of the core language and their interfaces

23.2 Function declarations : ⟨valRecDecl⟩, ⟨funDecl⟩

Syntax of function declarations has the following two forms ⟨valRecDecl⟩ and ⟨funDecl⟩.

⟨valRecDecl⟩ ::= val rec ⟨tyvarSeq⟩ ⟨valBind⟩
⟨funDecl⟩ ::= fun ⟨tyvarSeq⟩ ⟨funBind⟩
⟨funBind⟩ ::= ⟨funBind1⟩
 | ⟨funBind1⟩ and ⟨funBind⟩
⟨funBind1⟩ ::=   (op)? ⟨vid⟩ ⟨atpat11⟩ ⋯ ⟨atpat1n⟩ (: ⟨ty⟩)? = ⟨exp1⟩ (m,n≥1)
| (op)? ⟨vid⟩ ⟨atpat21⟩ ⋯ ⟨atpat2n⟩ (: ⟨ty⟩)? = ⟨exp2⟩
| ⋯
| (op)? ⟨vid⟩ ⟨atpatm1⟩ ⋯ ⟨atpatmn⟩ (: ⟨ty⟩)? = ⟨expm⟩

These declarations define mutual recursive functions. The scope of the function names being defined is the entire declaration and the declarations that follow.

val declarations of ⟨valBind⟩ in ⟨valRecDecl⟩ are restricted to those that have the following syntactic form:

⟨vid⟩ = fn expression

The identifiers (function names) ⟨vid⟩ appearing in the same ⟨funBind1⟩ must be the same, and function names appearing in different ⟨funBind1⟩s must be pair-wise distinct. As in ⟨valBind1⟩, variables contained in patterns ⟨pat⟩ in the same ⟨funBind1⟩ must be pair-wise distinct.

In evaluation of these declarations, function names (⟨vid⟩) are bound to the same (static and dynamic) values as the corresponding functions.

The type variable declaration ⟨tyvarSeq⟩ in ⟨valBind⟩ and ⟨funDecl⟩ delimit their scope. These type variables must be generalized at the top-level of each ⟨valBind1⟩ of ⟨valBind⟩ and ⟨funBind1⟩.

23.2.1 Function declaration interface

Function declaration interface is the same as val declaration interface. Each function name defined in the function declaration and its type are specified in the same syntax of val declaration specification. The following is an example of a source file and an interface file containing function declarations.

Bool.sml file: fun not true = false
  | not false = true
fun toString true = "true"
  | toString false = "false"
Bool.smi file: val not : bool -> bool
val toString : bool -> string