Rumination on calling conventions

Back in the dark ages of 1998, I took my first programming class. As was the style of the time, the class was taught in Pascal, a language Nicklaus Wirth designed explicitly to teach structured programming concepts. Think of Pascal like an advanced jet trainer:


They teach you all the cool stuff with it, before they turn you loose in the F-15's to wax some MiGs.

Anyway, Pascal had some neat concepts and quirks, one of which was the way it made a distinction between 'functions' (subroutines that returned data) and 'procedures' (subroutines that were passed data and operated on it). So, for example, you might have a function called 'double' that took an integer and returned that number times 2:


function double( k: integer ): integer;
begin
double := k*2;
end


With the above, the parameter 'k' isn't modified, so you'd call the code this way:


...
var i:integer, result:integer;
i: = 2;
result := double(i);
# at this point, 'i' is still 2, and 'result' is 4.


So, what's a procedure do, then? It's like a function, but it doesn't return anything to the caller. Instead, it just operates on is parameters. Rewriting 'double' as a procedure:


procedulre double( k: integer, var result: integer );
begin
result := k*2
end;


This changes our calling convention, as well:
var i:integer, result:integer
i:= 2;
result := 0
double(i, result);
# at this point, 'i' is still 2, and 'result' is 4.


* * *

Whew! Why did I take this particular trip down memory lane? And in Pascal, of all things? Because I see a rift, a rift in the way C programmers (specifically Win32 coders) and Java do it. Basically:


  1. C programmers like procedures

  2. Java programmers like functions



Just reading the code I've been looking over for the past few weeks, I see tons of this:


unsigned long errorCode = ERROR_SUCCESS;
list listToPopulate;
errorCode = bigApiCall( handle, listToPopulate );

if (errorCode)
...take evasive action...


the above is sort of a hybrid function/procedure, since C/C++ makes no distinction--at the lowest level, every subroutine call is a 'function', though some functions don't return anything (that is, they're void). Anyway, the big deal here is, in java, the above would be something like this:


List listToPopulate = bigApiCall( handle );


See the difference? You're returning the value from the function, not populating it via a reference parameter. Thing is, you could do the same thing in Java, at least for Object types--the "pass references by value" semantics allow you to call methods on the object passed in, changing its state. You just don't see that much in Java class libraries.

Just an interesting distinction I thought I'd highlight. I don't see one as intrinsically superior to the other. The C-style favors error codes and that's probably a good thing for most large-scale programs (yes, I'm one of those wonks who thinks exceptions and stack unwinding doesn't scale...), but the Java-style is simpler and less prone to side-effects in my experience.

Popular posts from this blog

Monday Mope

RegisterForPrintAsyncNotifications

The reality of the next car purchase