Difference between FUNCTION and PROCEDURE statements

Syntactically there is no difference between FUNCTION and PROCEDURE statements in VFP. In other languages, that have both statements, a function can return a value and a procedure cannot. In VFP the difference comes in the way a procedure/function is called. By default VFP passes parameters by value in call to the functions, by reference to the procedures ( DO ...) and only former allows for a return value.

The SET UDFPARMS command can change how parameters are passed to a user-defined function (UDF) but there is no good reason to use it. The parameters can be passed by reference in the function call by preceding them with @

character and by value in the procedure call by enclosing them in parenthesis.

The objects are always passed by reference. The arrays can only be passed by reference. When array is passed by value only the first item of the array is passed.

The sample code demonstrates some of the points discussed above.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

* function
FUNCTION foo
LPARAMETERS x, y
RETURN x + y
* or procedure
PROCEDURE foo
LPARAMETERS x, y
RETURN x + y

* The default SET UDFPARMS TO VALUE setting is assumed

* Call as a function and receive return value 
*   parameters are passed by value 
z = foo(x,y)
*   parameters are passed by reference
z = foo(@x,@y)
*   mixed parameters - by value and by reference
z = foo(x, @y)

* Call as a program. Return value, if any, is ignored
*   parameters are passed by reference
DO foo WITH x, y
*   parameter are passed by value
DO foo WITH (x), (y)
*   mixed parameters - by value and by reference
DO foo WITH (x), y

Comments

Good article. However the VFP F1 Online help for PROCEDURE Command says "By default, parameters are passed to procedures by value."

Hi Darren,

The help is incorrect. The PROCEDURE/FUNCTION statement does not determine how parameters are passed.

Maybe a little off the above thread but can one tell from within a VFP function/Procedure whether the calling syntax was as a function ie = Function/Proc() or by DO Function/Proc. It could be useful to ascertain and change the routines internal behaviour

A function/Procedure behavior should not depend on how it's called but on what parameters are passed.