Procedures & arguments
Define small callable contracts and be explicit about mutation, defaults and return values.
Return a value through the function name#
A Sub performs an action. A Function assigns its result to its own name. A synchronous Function may also be called as a statement when the caller intentionally discards its result; it still executes once. Use parentheses before reading members on an object returned by a Function, for example Store().Item(key). An Async Function still needs Await. Exit Function stops execution; it does not supply a result expression. In this example, the empty-input result is assigned before the early exit.
A complete function#
Public Function Greeting(ByVal name As String) As String
Dim clean As String
clean = Trim$(name)
If Len(clean) = 0 Then
Greeting = "Enter a name."
Exit Function
End If
Greeting = "Hello, " & clean
End FunctionFor input “ Ada ” the result is “Hello, Ada”. Empty or whitespace-only input returns “Enter a name.” The function has no dependency on a Form, so it can be tested independently.
Make argument direction intentional#
A parameter is ByRef unless you write ByVal. Use ByVal when a routine should read a value without changing the caller’s variable. Use ByRef deliberately when changing the caller is part of the contract. Event cancellation parameters are a typical example: keep the exact type and direction shown in Form events.
Optional and named arguments#
Optional parameters follow required ones. A typed Optional parameter needs a constant default; an Optional Variant can omit the default and be inspected with IsMissing. A caller may skip a middle position, but cannot leave a trailing comma. Named arguments use parameter:=value; after the first named argument, all remaining arguments must be named.
Public Function Welcome(ByVal name As String, Optional ByVal prefix As String = "Hello") As String
Welcome = prefix & ", " & name
End Function
Public Sub TryWelcome()
Debug.Print Welcome("Ada")
Debug.Print Welcome(prefix:="Welcome", name:="Ada")
End SubParamArray has its own rules#
Declare the last parameter as ParamArray values() As Variant, without ByVal or ByRef. It starts at zero even under Option Base 1; with no arguments, UBound is -1. A ParamArray procedure takes positional arguments and cannot also have Optional parameters. Do not assume changing an element is harmless: an element supplied as a variable can mutate that caller variable.
Keep the public surface small#
Put reusable functions in a standard module. Keep helpers Private unless other documents need them. A function’s name, argument direction and return type become obligations to callers; change them deliberately and rerun the callers’ tests.
20f4bfed6b · Build manifestSources & maintenance
Original web explanation, reviewed against these repository sources. API tables and example files follow the implementation.
docs/manual/21-language-reference.mddocs/manual/11-language-toolkit.mdsite/examples/LanguageWorkbench/Main.bas