CBFalconer wrote:
"Prof A Olowofoyeku (The African Chief)" wrote:
On 5 Oct 2004 at 0:08, Scott Moore wrote:
Here are IP Pascal's rules for overloads. I just finished implementing it. Yes, it is quite strict. To me, thats less problems going forward.
[....]
overload procedure myproc(i: integer);
Any particular reason for creating YAOS (yet another overload syntax)? I would have thought it reasonable to emulate an already existing and well established syntax (Delphi's).
Any reason for creating overloaded functions in the first place? It gobbles up another reserved word, and thus violates standards, and cuts off a vital (to me) error detection mechanism. You can always simply write "myproci" and "myproc" if you wish.
Another good question. I felt exactly that way about overloads a year ago. What happened is I listened to several fans of overloads, and read a book from an author who was advocating overloads for Pascal. I became a fan of overloads for procedures and functions, and also of templates, which I plan to implement as well.
The reason is that Pascal is very type strict. At least the standard version, as well as IP Pascal. Certainly lots of implementations "increase functionality" by loosening the type checking of Pascal. Overloads APPEAR to do that, without REALLY doing that. For example, you can implement C++ style "default parameters" by using overloads ability to match parameter counts. You can make a procedure that "apparently" takes several different types in the same parameter position.
None of the strict typing of Pascal is actually being violated. It just appears so. And under the rules of IP Pascal, the rules for overloads are quite strict as well.
So now back to the why, and what changed my mind about overloads and templates. Because these features give Pascal many of the attributes of "more advanced" languages like C++, with out breaking down the type safety of Pascal, I believe they will do a lot to help the perception of Pascal as an overly strict language without degrading or throwing out the type safety aspect of Pascal. The procedure or function chosen from the overload group is verified to the same type standard as normal pascal, and the criteria for the selection is also clear. Under IP rules, each parameter must be compatible under ISO 7185 rules to be selected as an overload candidate.
In fact, I think overloads and templates will help Pascal more than other languages. A non-type safe language such as C++ has many ways to subvert type checking and accomplish parameter mismatches. Pascal does not, so this "trick" allows Pascal to do what other languages can do, with out breaking what I consider Pascals main attribute, type safety.
In fact, the reason I implemented overload for IP Pascal at this time is a good example in of itself. The Windows API has many calls of the type:
WINAPI int someapifunc(stuff *x, stuff *y);
In C, that is of course how you pass a VAR parameter, you point to it, essentially do it yourself VAR parameters. But in the Windows API, the user may pass NULL for one of the pointers, which means "the parameter does not exist". This trick does not exist for Pascal, unless you pass everything to Windows via a pointer, which brings other kinds of problems to Pascal, like the need to be able to convert everything to and from a pointer (effectively breaking typing rules).
The way I have handled this in the past is to implement multiple functions:
function someapifunc(var x, y: stuff): integer;
function someapifunc_n(var x: stuff): integer;
function someapifunc_nn: integer;
With overloads this becomes:
function someapifunc(var x, y: stuff): integer;
overload function someapifunc(var x: stuff): integer;
overload function someapifunc: integer;
No longer any need to coin various names for WINAPI functions and document them. And the result, IMHO is cleaner. Instead of the C call:
someapifunc(&q, NULL);
I have:
someapifunc(q);
And a simple rule: if the parameter does not exist, leave it out !
Typically I have seen this kind of interfacing in other Pascals by allowing for an operator such as &x, that takes the address of any variable, then allowing the user to stuff any address into a pointer parameter. This "solves" the problem, but imports a huge type safety problem from C into Pascal, namely the ability to arbitrarily manipulate addresses.
Another example, again from Windows (also appears in Linux !):
someapifunc(int code, void *x);
Here the "void *" actually does have a type, it just has several actual types. The "code" selects which type is actually going to be indexed by x. This is certainly not one of the better practices of C (it should have been broken into multiple functions). However, with overloads, Pascal can call it easily, and in a type safe manner, by listing each of the forms of the call in an overload group.
Similar to overloads, I believe templates will help Pascal quite a bit:
procedure wrtstr(var f: file; s: template);
var i: integer;
begin
for i := 1 to max(s) do write(f, s[i])
end;
With a template, one or more parameters can be left "abstract" until the actual call is parsed. What goes on is that the compiler parses the procedure without fully evaluating the template parameter, essentially "stockpiling" the body of the procedure in an encoded form. When the actual call occurs, the compiler can reevaluate the entire procedure in terms of what it now knows about the type of the argument.
This, like overloads, does not affect the type safety of Pascal. When the actual call occurs, the procedure that is generated to match the template is completely evaluated to standard Pascal rules. It is only "type soft" while the template is still abstract. On invocation, all the type rules come into play.
The number of traditional Pascal typing difficulties templates solve is stunning. Remember the common complaint about having to have several different procedures or functions to get around fixed length strings ? That problem no longer applies. A collection of string functions can be written for fixed length strings that adapt to any string type.
How about the ability to write a set of general purpose list manipulators ? In standard Pascal you have to rewrite a set of insert, delete, sort, etc routines to fit each type of dynamic list. With templates, you can write a series of routines that only rely on the common features of a list, such as each entry having a ".next" field, and a ".data" field.
In fact, templates subsume a lot of the functionality that people get from using source macros with Pascal, but without any of the drawbacks. Unlike macros, templates CAN be evaluated before they are invoked. In fact, a smart compiler can perform type checking even on template parameters. In the string example, s is clearly an array, and its usage can be checked, if (for example) it is later misused as a record.
Sorry for the long winded discussion. However, to wrap up, I believe overloads and templates are more important to Pascal than other languages, because these techniques increase both the apparent and real power of Pascal WITHOUT short circuiting the type safety of Pascal. They allow you to "have your cake and eat it too".