\section{Functions} \subsection{Function Definitions} \fragment{ \BNF{ \Rule{\MC{function}}{\zeroplus{\MC{opt}} \MC{type} \MC{identifier} \CD{(} \zeroplus{\MC{arg},} \CD{)}} \MC{func\_body} \Or{\zeroplus{\MC{func\_opt}} \MC{type} \MC{identifier} \MC{func\_body}} \Rule{\MC{arg}}{\maybe{\CD{var}} \MC{type} \MC{identifier} \maybe{$\langle$\CD{=} \MC{typed\_expr}$\rangle$}} \Rule{\MC{func\_body}}{\CD{\{} \maybe{\MC{expr}} \CD{\}}} \Or{ \MC{rvalue} } \Rule{\MC{rvalue}}{\CD{=} \MC{typed\_expr}} \Or{\oneplus{$\langle$\CD{|} \MC{typed\_expr} \CD{=} \MC{typed\_expr} $\rangle$}} \Rule{\MC{func\_opt}}{\CD{public}} \Or{\CD{private}} \Or{\CD{pure}} \Or{\CD{default}} } } The basic form of a function definition is to declare the return type, give the name, and list the arguments, e.g.: \begin{verbatim} Float plus(Int a,Float b,Int c) { putStrLn("Doing some sums"); return a+b*c; } \end{verbatim} If the return type is given as \CD{Void}, the function must not return a value. Otherwise, it is a compile time error if any code branch does not return a value or throw an exception. \subsection{Type Inference and Scope} The compiler will infer the type of variables used in the function body. For any name which occurs in a function body, name resolution works as follows: \begin{enumerate} \item Look up the name in the list of defined functions. \item Look up the name in the list of global variables. \item If the name is not found, create a local variable and infer a type. \end{enumerate} A type will not be inferred for names which occur \remph{only} as an argument to a function, because the compiler cannot guarantee that values are defined for such names. Variables are statically scoped. If a variable is explicitly declared, it goes out of scope when the block in which it is declared exits. Otherwise, variables go out of scope on exit from the function. \subsection{Argument Passing Convention} Arguments are passed by reference. On entry to the function, a new reference to each argument is created. If an argument is marked \CD{var}, the reference is passed directly (i.e. no new reference is created), allowing the value to be modified. e.g., the following function swaps two values \begin{verbatim} Void swap(var a x, var a y) { tmp = x; x = y; y = tmp; } \end{verbatim} Without the \CD{var} modifiers, this function would have no effect. \subsection{Type Constructors} Type constructors (see section \ref{usertypes}) are effectively functions which create an instance of the relevant type. They are treated like an ordinary function in every way, except in that their implementation is compiler generated. \subsection{Options} The four options which a function can have are \CD{public}, \CD{private}, \CD{pure} and \CD{default}. \CD{public} and \CD{private} define the function's visibility outside the current module or compilation unit (see section \ref{sect:modules}). \CD{pure} declares that the function does not have any side effects and is used as an optimisation hint. \CD{default} functions are ignored if a definition already exists; this is used in the definition of program types (see section \ref{sect:progtype}). \subsection{Overloading} A function can use the same name as another function, provided that they can be disambiguated by the argument types. For example, the following functions can be defined in the same program: \begin{verbatim} Int abs(Int x) { ... } Float abs(Float x) { ... } \end{verbatim} However, functions cannot be disambiguated purely on return type. \subsection{Shorthands} \subsubsection{Zero argument functions} A function which takes no arguments does not need to give an explicit argument list, e.g. \begin{verbatim} Void usage { putStrLn("Error!"); } \end{verbatim} \subsubsection{Returning Expressions} A function which returns a single expression can simply give the expression to be returned, e.g.: \begin{verbatim} Float square(Float x) = x*x; \end{verbatim} If there are no arguments, the function can be written as a form of constant, e.g.: \begin{verbatim} Float pi = 3.141592653589793; \end{verbatim} Note that \CD{pi} is still a function here; the value cannot be modified. In practice, this can be inlined and used exactly the same way as a constant. \subsubsection{Guarded definitions} A function which returns a simple expression based on a number of boolean tests can be defined by listing the tests and results, e.g.: \begin{verbatim} Int abs(Int x) | x<0 = -x | default = x; \end{verbatim} This is equivalent to the following basic form: \begin{verbatim} Int abs(Int x) { return (if (x<0) -x else x); } \end{verbatim}