Chapter 8. Functions and Subs

8.1 General

Functions and Subs are the primary executable units of a Buoy program.

Both define reusable sequences of statements that may accept parameters. A Function computes and returns a value to its caller. A Sub performs an action and does not return a value.

Although Functions and Subs share much of their syntax and behaviour, they represent distinct language constructs and are treated separately throughout this specification.


8.2 Function Declarations

A Function declaration introduces a named routine that computes and returns a value.

A Function declaration specifies:

  • the function name
  • zero or more parameters
  • the return type
  • optional generic parameters
  • the function body

The return type forms part of the function declaration and determines the type of every invocation.


8.3 Sub Declarations

A Sub declaration introduces a named routine that performs an action.

A Sub declaration specifies:

  • the Sub name
  • zero or more parameters
  • optional generic parameters
  • the Sub body

Unlike a Function, a Sub has no return type.


8.4 Parameters

Parameters introduce named values that are supplied by the caller when a routine is invoked.

Each parameter has:

  • a name
  • a type
  • a passing mechanism
  • optional modifiers
  • an optional default value, where permitted

Parameters are local to the routine in which they are declared.


8.5 Invocation

A routine is invoked by specifying its name followed by an argument list.

Each argument is evaluated before control transfers to the invoked routine.

Arguments shall satisfy the parameter requirements established by the declaration.

If no applicable declaration exists, the invocation is ill-formed.


8.6 Return

A Function returns control and a value to its caller.

Every execution path through a Function shall produce a value compatible with the declared return type.

A Sub returns only control.

Execution of a Sub completes when:

  • execution reaches the end of the Sub body, or
  • a Return statement transfers control to the caller.

8.7 Local Variables

Variables declared within a Function or Sub are local to that routine.

Local variables are created upon entry to the routine and destroyed when execution leaves the routine.

Each invocation receives an independent set of local variables.


8.8 Overloading

Multiple Functions or Subs may share the same name provided their parameter lists satisfy the language rules for overload resolution.

Overload resolution is performed entirely at compile time.

The compiler selects the most appropriate declaration according to the argument types supplied by the invocation.

The overload resolution algorithm is described in Chapter 9.


8.9 Generic Routines

A Function or Sub may declare one or more generic type parameters.

Generic routines describe families of related routines whose behaviour depends upon the supplied type arguments.

Type arguments may be written explicitly or inferred by the compiler when permitted by the language.

Generic programming is described in Chapter 10.


8.10 Recursion

A Function or Sub may invoke itself either directly or indirectly.

Each recursive invocation creates a new execution context with its own parameters and local variables.

The language imposes no restriction upon recursive declarations beyond those required by available execution resources.


8.11 Visibility

The visibility of a Function or Sub is determined by its declaration.

A routine may be visible only within its declaring scope or may be exported for use by other compilation units, according to the applicable accessibility rules.


8.12 Forward References

A Function or Sub may invoke another routine declared elsewhere within the same program.

The compiler resolves routine references during semantic analysis.

The order of routine declarations within source files does not affect program correctness.


8.13 Routine Identity

A Function and a Sub are distinct declaration kinds.

A Function cannot be substituted for a Sub.

Likewise, a Sub cannot be used where a Function is required to produce a value.

This distinction is enforced during compilation.


8.14 Summary

Functions compute values.

Subs perform actions.

Together they provide the primary abstraction mechanism for executable behaviour in the Buoy programming language.