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.