Procedures and Functions

Purpose

Organizational activities speed up when things are put into bags and managed as a single item. Procedures and Functions provide ?bags? which can contain statements organized to accomplish a particular objective. Once organized this behavior can then be requested from many different points in a program to provide a specialized capability. Procedures are like subroutines in basic and ?void? functions in C. Functions are procedures which return an answer.

Procedures

The syntax of a procedure without parameters is:

procedure <ProcedureName>;
<optional local variables>
begin
<statements>;
end;

The first word is "procedure", a keyword indicating that a procedure is being defined. Following is a space and the name of the procedure followed by a semicolon. At this point you may choose to include local variables. Local variables are temporary storage areas which remain intact only for the duration of this particular execution of the subroutine. Following any local variables is "begin" followed by statements followed by "end".

A procedure can be added to a plate in Snap2Motion with this choice:

A new procedure is provided with the following default template:

The following procedure moves a 2 axis group named Laser in a square pattern:

This procedure can now be referenced by another list of commands to produce several squares:

Now a square can be made by calling procedure MakeSquare rather than the individual statements. MakeSquare has accomplished several things. It has ?bagged? the four movement instructions so that now the behavior can be accomplished with one statement instead of four. It has also ?raised the level of abstraction?. Now instead of describing the problem in terms of movements, the problem can be described in terms of ?squares?, a higher abstraction description of a problem. Procedure names are excellent places to convey meaning about program behavior. Take the time to make descriptive and meaningful procedure names.

What if squares of different sizes are needed? Procedures are able to take parameters. The syntax of a procedure with parameters is:

Procedure <ProcedureName> ({var}<ParamName>:Type{;another...});

To include parameters follow the procedure name with a left paren- thesis. After the parenthesis comes a description of the parameter. If the first word in the description is ?var? the parameter will be ac- cessed using call-by-reference. If ?var? is not the first word the parameter will be call-by-value. The distinction between call-by- reference and call-by-value is important and will be discussed in the following section. The name of the parameter follows, a colon after the name and a type after the colon similar to a conventional variable declaration. Multiple parameters are separated with semicolons. The right parenthesis completes the description of the parameter list and a semicolon follows just as it had in the original procedure definition.

The previous example can be rewritten to produce squares of various sizes:


The parameter SideLength is provided in the calling routine with explicit numbers and produces 3 squares of different sizes. The parameter could also have been provided as an expression or function result.

Functions

Functions are similar to procedures with the additional feature of returning an answer. The syntax of a function is similar to a proce- dure however the keyword is "function" instead of "procedure", and following the declaration is a colon, type name, and semicolon instead of just the semicolon:

function <name>{(<parameters>)}:<type>;

The result of a calculation can be returned by the function and used by the caller. To return a value perform an assignment statement to the function name inside the body of the function. To use the answer include the function name anywhere you might use an expression.

An example function might square a parameter:

If while inside a function body the function name is used as a source expression, i.e. on the right side of an assignment statement, the function is treated as a temporary variable that responds with the value last assigned to it. This will not perform recursion as would normally be the case. Using the function name in this way is not recommended as it develops non-standard habits. Use a local variable instead. Although functional recursion is not supported procedural recursion is.

The function value must be assigned to a value. The compiler does not produce a warning if the return result is never assigned.

The language does not support return types of arrays, strings, or aggregate types however they can accessed and modified from a procedure or function by passing them as call-by-reference, or "var" parameters.

Call-By-Value and Call-By-Reference

Call-by-value and call-by-reference are two different parameter passing models. Which model is appropriate to use depends on the objective.

Call-by-value is the default parameter passing model. In this case, copies of the parameters are provided to the called routine which regards the parameter names as temporary variables. The routine can freely read or write to these parameter variables and cause no effect on the variables that were used in the calling routine to fill in the parameters. The only way an answer can get back to the caller when using call by value is through a function return result. This approach is generally regarded as the safest method because there is less of a connection between the activities inside the called routine and the information in the caller.

Call-by-reference is a technique where a ?pointer? to the information in the caller is given to the function. The "var" keyword indicates that the parameter is being passed as a referenced piece of information in the caller. All of the ?referencing and dereferencing? is handled automatically by the compiler. When the value of a parameter that is being assessed through call-by-reference is changed, the value of the parameter in the caller changes. It?s as if the single variable in the caller has two names, its original name and the param- eter name in the called function. Call-by-reference allows information to travel from the function back to the caller in a way besides a function return result. For example a procedure can have a var parameter and through assignment to that parameter change the value of a variable in the calling routine. Call-by-reference permits a routine to provide numerous return results and not just one. Call-by-reference also incurs less stack space than call-by-value for structures which are large. The language creates temporary stack space for call-by-value parameters regardless of their size. If strings are being passed as parameters it is required that they be passed by reference. Some language systems default to call-by-reference. Developers who are familiar with this technique may choose to use the VAR keyword to better simulate a parameter passing method they are familiar with.

The general principle for choosing between the two is this. If the value of the variable in the calling routine is expected to change by actions of the called procedure or function then use call-be-reference by indication with a "var" keyword.

If an explicit parameter or function is found for a call-by-reference parameter the compiler creates, behind the scenes, a temporary variables. The compiler then arranges for that constant or function expresssion to be placed into the temporary variable, and then uses a pointer to that temporary variable for the VAR referenced parameter. Note that this takes more time to execute than simply passing a value to the routine. For small variable such as integers, booleans, longints, and single types, it is faster to simply pass the variable by value rather than by reference.