Procedures Vs Functions

In Visual Foxpro, you can declare procedural routines or Object Oriented methods as either “PROCEDURE” or “FUNCTION”, and it has no impact on how that routine is handled by VFP, like this:

PROCEDURE ThisIsMyProcedure
  Messagebox( "You are in a Procedure." )
ENDPROC

FUNCTION ThisIsMyFunction
  Messagebox( "You are in a Function." )
ENDFUNC


Differences between calling Procedures and Calling Functions

Functions return a result, Procedures do Not

If a routine does not include a RETURN statement to return a result, it will return .T. by default.

The calling pattern determines whether a routine is a Procedure or a Function, not its “definition”

Even if your routine is defined as a PROCEDURE, you can still call it like a function, and it *is* a function. If you did not include a RETURN statement, the function will return .T. (as mentioned above). (Object Oriented methods must always be called “as functions”.)

As discussed in Parameters By Value Or Reference, the way that you call a procedural routine also determines the handling of the parameters. This can be confusing, even with the information in the previously mentioned article.

Here are your two options:
1) Use “DO … WITH” to call a routine and it will be considered a “procedure”.
Parameters will be passed “by reference” unless they are surrounded by parentheses, and there is no way to “explicitly” pass parameters “by reference”.
(Note that Set UDFParms does NOT affect routines called by “DO … WITH”)

For example:

DO MyRoutine WITH ParamByRef, (ParamByValue)
DO MyRoutine WITH @ThisDoesNotWork

or

2) Omit “DO” and “WITH”, and surround all parameters in one pair of parentheses, and your routine will be considered a “function”.
Parameters will be passed “by value” unless:
A) You place an “@” in front of the parameter, or
B) You place (additional) parentheses around the parameter

For example:

SET UDFPARMS TO VALUE
Result = MyRoutine( ParamByVal, @ParamByRef, (otherParamByVal) )
MyRoutine( ParamByVal, @ParamByRef, (otherParamByVal) )
SET UDFPARMS TO REFERENCE
Result = MyRoutine( ParamByRef, @OtherParamByRef, (ParamByVal) )
MyRoutine( ParamByRef, @OtherParamByRef, (ParamByVal) )

Contributors: wgcs