Subroutines are blocks of code that can be called from elsewhere in the same function.   Subroutines do not take arguments, but have access to all variables and constants available in that function.

Subroutines begin with a SUB SubName statement, end with an END SUB statement, and are called with a GOSUB SubName statement.  It is an error to attempt to GOTO labels within a subroutine from outside the subroutine.  However, it is possible to GOTO a label outside a subroutine from within.

Subroutines cannot be nested.  Each must end before another begins.

Subroutines are not recursive.  They may not call themselves directly or indirectly.   A compile-time error occurs if a subroutine tries to call itself directly, that is, from within itself.  However a subroutine can call itself indirectly by calling another subroutine that calls it. This error is not detected at compile-time or run-time.   Programs may hang up when subroutines call themselves indirectly.

But functions are recursive, so a function can call itself from within a subroutine without restrictions.  For example, SUB Blivit in function ThisFunc() may not contain GOSUB Blivit.  But function ThisFunc() may be called from within SUB Blivit, and the newly called ThisFunc() may execute SUB Blivit.  Stated differently, the prohibition against recursive execution of subroutines applies only within each call of the function that contains it.

Functions are blocks of code that can be called from anywhere in a program, receive 0 to 16 input values called arguments, carry out actions based upon the input values, and finally return control to the point in the program immediately following the call, sometimes returning a value.

Arguments can be passed to functions by value, by reference, or by address (for calling C functions).  Numeric values, string values, arrays, and composite values can be passed to functions.