ReadyBASIC
BASIC Language Reference Manual > Command and Function Reference >

FUNCTION Command

Summary

Defines a function.

Syntax

  • FUNCTION FunctionName
        code block
    END FUNCTION
    

  • FUNCTION FunctionName()
        code block
    END FUNCTION
    

  • FUNCTION FunctionName(FunctionName1)
        code block
    END FUNCTION
    

  • FUNCTION FunctionName(ParameterName1, ..., ParameterNameN)
        code block
    END FUNCTION
    

Remarks and Examples

A function is a block of code that may perform some task, but which must always return a value. When you define a function, you must give it a name, and you must indicate the data type that will be returned (an integer value, a floating-point value, or a string). A function definition almost always defines one or more parameters (explained below), but it is also possible to define a function that takes no parameters.

Once a function is defined, you can then call or invoke the function by name as many times as you like throughout the rest of your program. (Note that procedure calls must use the CALL command, but function calls do not.) Each time you call a function, the program flow jumps to the the function definition and the commands in the function definition are executed. When the end of function is reached, the return value is determined, the control passes back to the place where the procedure was called, and the return value is substituted in place of the function call in the evaluation of the expression in which the function call was situation. (Some examples will make this clear.)

The suffix on the name of the function determines the data type that the function will return. If you do not use a suffix -- for instance, if you name your function DoubleIt -- then that function will return a floating-point value. If you use the % suffix -- for example, DoubleIt% -- the function will return an integer. The $ suffix, as in RepeatIt$, will return a string.

The return value is set by assigning a value to the "return value variable", which has the same name as the function. For example, if your function is named DoubleIt%, then by assigning a value to the variable DoubleIt% within this function, you can set the value that the DoubleIt% function will return.

You can assign values to the return value variable as many times as you like within the function. The act of assigning a value to the return value variable does not cause the function to return; the code within the function continues executing until the END FUNCTION statement is reached, at which point the value of the return value variable is used as the return value.

When a function is called, before the code within the function definition is executed, the return value variable is initialized with the default initial value for the data type. For an integer, it is initialized to 0; for a floating-point value, it is initialized to 0.0; for a string, it is initialized to the empty string (""). If you do not modify the return value variable, it is this initial value that will be returned.

Example program listing illustrating a simple function:

Main:
    A% = 5
    PRINT "A% is "; A%
    PRINT "A% doubled is "; DoubleIt%(A%)
    B% = DoubleIt%(2) + DoubleIt%(9)
    PRINT "B% is "; B%
    B% = DoubleIt%(DoubleIt%(B%))
    PRINT "B% doubled and then doubled again is "; B%
    END
    
FUNCTION DoubleIt%(X%)
    DoubleIt% = X% * 2
END FUNCTION

When this program is run, the results are as follows:

A% is 5
A% doubled is 10
B% is 22
B% doubled and then doubled again is 88

Parameters

When defining a procedure, you can specify one or more parameters by providing a comma-separated list of variable names surrounded by parentheses.

If a variable name is given without any suffix (e.g., "AccountBalance"), the variable is considered to be of the floating-point numeric type. If the variable name is given the % suffix, (e.g., "Age%"), it signifies an integer numeric type. If the variable name is given the $ suffix, (e.g., "Message$"), it is considered to be a string.

Example:

Main:
    PRINT "User name: "; GenerateUserName$("Gerda", "Malaperis", 23)
    END

FUNCTION GenerateUserName$(FirstName$, LastName$, Age%)
    LOCAL Temp$
    Temp$ = LEFT$(FirstName$, 1) & LEFT$(LastName$, 8) & STR$(Age%)
    GenerateUserName$ = ToLowerCase$(Temp$)     
END FUNCTION

FUNCTION ToLowerCase$(X$)
    LOCAL NewCh$
    
    FOR Position% = 1 TO LEN(X$)
        Ch$ = MID$(X$, Position%, 1)
        IF Ch$ >= "A" AND Ch$ <= "Z" THEN
            NewCh$ = CHR$(ASC(Ch$) + (ASC("a") - ASC("A")))
            ToLowerCase$ = ToLowerCase$ & NewCh$
        ELSE
            ToLowerCase$ = ToLowerCase$ & Ch$
        END IF  
    NEXT Position%
END FUNCTION

When this program is run, the results are as follows:

User name: gmalaperi23

Functions may be defined that take no parameters. In this case, it is optional to use the sequence () after the function name in the function definition. However, function calls must always use the sequence () to indicate that it is a function call. If you omit the parentheses, the name will be interpreted as a variable rather than a function call.

Example:

Main:
    PRINT "A random number between 1 and 10 is: "; GimmeARandomNumber%()
    
FUNCTION GimmeARandomNumber%
    GimmeARandomNumber% = INT(RND * 10) + 1
END FUNCTION

Functions use pass-by-value parameter passing

Procedures (see the PROCEDURE command) follow a principle called pass-by-reference parameter passing, by which values can be returned to the caller by modifying the values of parameter variables.

Functions are intended to return only a single value to the caller, and so in ReadyBASIC, the parameters in functions follow the pass-by-value parameter passing principle. If you modify the values of parameter values in a function, it will not cause the changes to be reflected in the variables that the caller has supplied as parameters in the function call.

This is an intentional design decision intended to prevent unintentional side-effects. If you intend to return multiple values, therefore, you should choose a procedure instead of a function.

Main:
    A% = 5
    PRINT "Before the function call, A% = "; A%
    B% = AddOne%(A%)
    PRINT "After the function call, A% = "; A%; " and B% = "; B%
    END
    
FUNCTION AddOne%(X%)
    AddOne% = X% + 1
    X% = 99999
END FUNCTION%

Result:

Before the function call, A% is 5
After the function call, A% is 5 and B% is 6

Note that A% in the main program has not been set to 99999.

Control flow

When a function is called, the instructions in the function definition will be executed until the matching END FUNCTION statement is reached.

The use of the RETURN statement to prematurely break out of a function is not currently supported.

A function can call other procedures and functions.

While a function can use GOTO and GOSUB statements, these should be limited to referring to labels that are defined within the function definition itself.

Where should functions be defined in a program listing?

If the flow of control encounters a function definition, it will be skipped over, and execution will resume with the instruction following the function definition. The only way to execute the code inside a function definition is to explicitly call that function. For example:

PRINT "A... "; GimmeARandomNumber%()
FUNCTION GimmeARandomNumber%
    GimmeARandomNumber% = INT(RND * 10) + 1
END FUNCTION
PRINT "B... "; GimmeARandomNumber%()
CALL SaySomething

Results (the random values will vary with each execution):

A... 7
B... 3

However, this intermixing of function definitions with "main program" code can be confusing. It is recommended to keep your main program code at the top of the program listing and define your procedures and functions towards the bottom of the listing. An END statement at the end of the main program code is recommended but not necessary if there are no other statements intermixed between the procedure and function definitions.

Recursive functions

ReadyBASIC supports recursion. Recursion occurs when a function includes a function call to itself. Caution must be used to avoid an infinite recursion scenario.

TODO: Example

Variable scope

ReadyBASIC allows you to define local variables inside a function using the LOCAL statement. Local variables are not visible or accessible by code outside of the function. This is a structured programming technique that allows you to simplify and modularize your program by "hiding" information from parts of the program that do not need to know about that information.

TODO: Example

Notes

A function definition can call other procedures and functions, but you cannot nest another procedure or function definition inside a function definition itself.

See also: GOSUB, LOCAL, PROCEDURE, RETURN




Copyright 2006-2012, Kevin Matz, All Rights Reserved.