Tuesday, April 21, 2009

Functions and Procedures in VFP 101

When working in Visual FoxPro, functions are procedures are almost the same thing. Look at the following code:

FUNCTION DoSomething
LPARAMETERS Param1, Param2
? "Param 1= " + Param1
? "Param 2= " + Param2

PROCEDURE DoSomethingElse
LPARAMETERS Param1, Param2
? "Param 1= " + Param1
? "Param 2= " + Param2

The function and procedure are actually identical. The difference to determine whether you have a function or procedure is not how they are defined, but how they are called. You can even call them the same way.

DO DoSomething WITH "Hello", "Procedure"

DoSomething("Hello", "Procedure")

You'll notice that DoSomething was defined as a procedure, but we can call it as either a procedure or a function. We can do the same thing with DoSomethingElse.

The difference is how the parameters are passed. When called as a procedure, the parameters are passed by reference. When called as a function, the parameters are passed by value. You can change how they?re passed in a function with SET UDFPARMS TO REFERENCE but you can?t change how parameters are passed when calling the routine as a procedure.

So, which should you use? I think you should always call the routine as a function because the routine cannot accidently change the value of the parameter. This is the kind of nasty side effect that can be difficult to track down.

Labels:


Comments:
Hi Craig,
>> but you can't change how parameters are passed when calling the routine as a procedure.<<

Of course you can: Normally a procedure gets the parameters "By Reference", the "By Value" is done with enclosing the parameters with parantheses.

The same thing is with Functions: Their parameters are normally "By Value", and preceeding them with a "@" you get "By Reference".
There's absolutely no need for the global and dangerous SET UDFPARMS setting.

Even though the keywords "Procedure" and "Function" are resolved to the same token by the compiler, I made me a habit to use them both accordingly, denoting the way I intended to call that subroutine. Therefore a later programmer knows just by looking at the definition, that a subroutine is meant to get called as PROC or FUNC ;)
 
>> which should you use <<

Easy way out: If you need only one returnvalue: go with a function. If you need more than one result returned, use a Procedure.

It's not that uncommon, that you need more than one result (for example almost all Windows API functions use the "@" for switching one or more parameters to ReadWrite mode)

The more OOP-ish way would be to return a parameter-object from your function, which would hold all the result values in one place. But this is surely a lot more code to write and therefore not programmer-friendly ;)
 
Yes, you're right wOOdy. What I was trying to say was that you can't switch the parameters as a whole, but you have to pass each one individually in a different way to change them.
 
Hi Craig,

I have always felt that a function "RETURNS" something and a procedure does something, but returns nothing.

-Mark
 
Mark,

That's one way to look at it. But, IMO, it's dangerous to pass parameters by reference.
 
Post a Comment



Links to this post:

Create a Link



<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]