SUBs & FUNCTIONs

Procedures give a name to a block of code, let you reuse it with different inputs, and keep variables local so that one part of a program cannot accidentally damage another.

11.1 Why procedures?

Procedures give a name to a block of code, let you reuse it with different inputs, and keep variables local so that one part of a program cannot accidentally damage another. A SUB performs an action; a FUNCTION computes and returns a value.

11.2 Program layout in QB64-PE

A FUNCTION's return type comes from its name suffix (! here) or from DEFtype; assign the result to the function name before it ends.

Calling a SUB: PrintBanner APP$ (no parentheses) or CALL PrintBanner(APP$) (parentheses required with CALL).

Calling a FUNCTION: use it in an expression — x = RectArea!(4, 2). A FUNCTION cannot be called as a statement on its own.

In QB64-PE, DECLARE SUB/DECLARE FUNCTION lines (which the QBasic IDE inserted automatically) are accepted but not required.

Use EXIT SUB / EXIT FUNCTION to return early.

' 1. Metacommands, CONSTs, TYPEs, DIM SHARED (module level)
OPTION _EXPLICIT
CONST APP$ = "Procedures Demo"

' 2. Main program
DIM w AS SINGLE, h AS SINGLE
PrintBanner APP$
w = 4: h = 2.5
PRINT "Area:"; RectArea!(w, h)
END

' 3. SUB and FUNCTION definitions come AFTER the main code
SUB PrintBanner (text AS STRING)
    PRINT STRING$(LEN(text) + 4, "*")
    PRINT "* "; text; " *"
    PRINT STRING$(LEN(text) + 4, "*")
END SUB

FUNCTION RectArea! (wd AS SINGLE, ht AS SINGLE)
    RectArea! = wd * ht                  ' assign the result to the function's name
END FUNCTION

11.3 More FUNCTION examples

Note: literals passed to parameters are converted automatically (the 3 in Clamp&(150, 0, 100) becomes a LONG copy).

PRINT Max#(3.5, 9.25)
PRINT Repeat$("ab", 3)
PRINT IsLeapYear%(2024), IsLeapYear%(1900)
PRINT Clamp&(150, 0, 100)
END

FUNCTION Max# (a AS DOUBLE, b AS DOUBLE)
    IF a > b THEN Max# = a ELSE Max# = b
END FUNCTION

FUNCTION Repeat$ (s AS STRING, n AS INTEGER)
    DIM result AS STRING, i AS INTEGER
    FOR i = 1 TO n
        result = result + s
    NEXT
    Repeat$ = result
END FUNCTION

FUNCTION IsLeapYear% (y AS INTEGER)
    IsLeapYear% = (y MOD 4 = 0 AND y MOD 100 <> 0) OR (y MOD 400 = 0)   ' -1 or 0
END FUNCTION

FUNCTION Clamp& (v AS LONG, lo AS LONG, hi AS LONG)
    IF v < lo THEN Clamp& = lo: EXIT FUNCTION
    IF v > hi THEN Clamp& = hi: EXIT FUNCTION
    Clamp& = v
END FUNCTION

11.4 DEF FN (legacy single-line functions)

DEF FN functions must be defined before use and share variables with the main program. Prefer FUNCTION.

Classic BASIC: only GOSUB and one-line DEF FN; BBC BASIC had DEF PROCname(params) / ENDPROC and DEF FNname(params) = expr with LOCAL variables. FreeBASIC: return types are declared: Function Max(a As Double, b As Double) As Double; return with Return value or Function = value. Procedures can appear before use if declared, and can be overloaded (Overload). VB.NET: Sub Greet(name As String) and Function Max(a As Double, b As Double) As Double ... Return a End Function; optional parameters (Optional n As Integer = 1), ParamArray, overloading.

DEF FNCube (x) = x * x * x
PRINT FNCube(3)          ' 27