VERSIONS: All ? - written for Paradox 5
SUBJECT: Custom methods vs procedures
BY: Mark Pauker
From the "If you hold onto something long enough it will eventually become new again" file, I am including a description of what a procedure
is, and the difference between methods and procedures that I wrote (and delivered) for the 1992 Borland conference (which occurred immediately preceding the release of PdoxWin 1.0).
I wrote this because when we were first exposed to PdoxWin (in 1990), Jim Kocis, Alan Zenreich, and I spent a lot of time and effort trying to
figure out how Borland determined the difference between methods and procedures. In particular, I spent a lot of brain power trying to figure out
the "grand scheme," only to conclude after literally months of contemplation that there really wasn't one. This applies both to the classification of
method vs. proc, and to the categorization of which "type" to list it under.
Here is an excerpt from the paper:
< Quote >
A Procedure is a routine which operates independently of any object. A good example of a procedure is BEEP(), which causes the computer
to make a beep, but doesn't act on any Paradox object. Procedures cannot be called using dot notation.
Like methods, procedures also come in different flavors: Custom and RTL. A custom procedure is one which is created by the developer, and
an RTL procedure is defined by the system.
The Difference Between Methods and Procedures
It turns out that the rule which governs what is a method and what is a procedure is actually more of a guideline than a rule. In this section
we will describe the exceptions to the rule, but before doing so, a word of caution is in order: Don't get too caught up in why Borland has
classified a routine as a method or a procedure. RTL methods and procedures are accessible in basically the same manner and from within all
objects, making their classification somewhat superfluous. Custom routines are defined by the developer, so you will decide whether they are
methods or procedures; and that decision will be based on scoping constraints (as described later in this paper) rather than on any esoteric
definition of "What is a method?".
The first exception to the rule that methods act on objects and procedures don't, is evidenced in the procedure CLOSE() which closes the
current form. While this routine acts on the form object, that object is not specified as a parameter. Routines which by nature operate on an object
that is not named in the call are considered to be procedures.
Another type of procedure which might also have been considered a method is one which operates in an identical manner on various classes
of objects. A good example of this is STRING(), which casts a value to the string class. STRING will carry out the exact same function on a variable
of the anyType, currency, date, longInt, smallInt, or number class (among others). For efficiency sake, rather than defining 10 or 15 different
STRING methods (one for each class), Borland decided to condense it into a single procedure which can take arguments of various classes.
The last type of procedure which might otherwise have been considered a method is a routine that was "ported" over from DOS Paradox for
the sake of familiarity with PAL. A good example of this is STRVAL(), which is functionally identical to STRING(), but which was included in
ObjectPAL simply to ease the transition from DOS Paradox. Any routine that was brought over from DOS Paradox for "compatibility" is
considered a procedure because it was a procedure in the DOS version.
< /Quote >
I wasn't crazy about writing the above section because the classifications seemed so haphazard, and appeared to lack consistency. For
example, this code is functionally equivalent to the procedure version of close():
var
fm form
endVar
fm.attach()
fm.close()
Given this, how can we think of close() as a procedure?
The issue that you raised about smallInt brings up the same inconsistency problem. To get a bit more insight into this, let's consider the time()
procedure. Clearly, when time() is called with no arguments, it is a procedure which returns the system time. The problem is that if you call time()
with an argument (passing it a string), shouldn't it be considered a method? Since you can pass it an anyType, shouldn't it be considered a part of
the anyType class? Likewise, consider the fill() procedure, which repeats a string a certain number of times. Since it operates on a string, why isn't
it a method?
In my opinion, time should be defined as a method of type "anyType." It should also be a procedure (when called without an argument) of
either the time type or the system type. I think that Borland classified it under the time type because they thought most people would look for it
there. Also, I think they classified it as a procedure because in a way, the fact that it works on all types sort of makes it type independent. (I know,
I don't really buy it either.)
Now let's look at the smallInt procedure. The classification of smallInt() and time() should be somewhat similar in that they both cast values
into different types. The main difference between them is that smallInt can't be used without an argument. Given what I said with regard to
time(), IMO, smallInt should be a method of the anyType type.
So if Borland classifies smallInt as a procedure, why does it work like a method? My guess is that it was implemented as method, but
documented as a procedure. (Given all the confusion about what's what, that doesn't seem too unreasonable.) The next question is how should it
be called? My recommendation is to call it without using dot notation. This is consistent with other languages' conventions regarding casting data
from one type to another, and also protects you from the possibility of Borland's removing this undocumented use in future versions.
Given that I disagree with much of Borland's classification of what is a procedure, why did I write about it (and why did I post it again here)?
The reason is that people (myself included) sometimes need a consistent definition of something before they are able to move on. Thus I thought
I'd present my best shot at a consistent (albeit filled with exceptions) definition WRT how Borland categorizes things.
IMO, the key point you should take from this is contained within the body of my original paper: "Don't get too caught up in why Borland has
classified a routine as a method or a procedure. RTL methods and procedures are accessible in basically the same manner and from within all
objects, making their classification somewhat superfluous."
Hope this helps clear things up a bit.