The Importance of Terminology's Quality

John W Kennedy jwkenne at attglobal.net
Sun Jul 20 18:29:25 EDT 2008


Robert Maas, http://tinyurl.com/uh3t wrote:
>>>> ... the "thunks" were necessary at the machine-language level to
>>>> /implement/ ALGOL 60, but they could not be expressed /in/ ALGOL.
>>> Ah, thanks for the clarification. Is that info in the appropriate
>>> WikiPedia page? If not, maybe you would edit it in?
>> From: John W Kennedy <jwke... at attglobal.net>
>> It is explained s.v. "thunk", which is referenced from "ALGOL
>> 60". The ALGOL "pass-by-name" argument/parameter matching was
>> perhaps the most extreme example ever of a language feature that
>> was "elegant" but insane. What it meant, in effect, was that,
>> unless otherwise marked, every argument was passed as two closures,
>> one that returned a fresh evaluation of the expression given as the
>> argument, which was called every time the parameter was read, and
>> one that set the argument to a new value, which was called every
>> time the parameter was set.
> 
> Wow! All these years when I occasionally heard of a "thunk" I never
> was told, until now, what it really meant. Thanks for the info!!
> 
> Followup question #1: I assume these are lexical closures in the
> environment of the point of the call, right?

Yes. (Actually, subprogram calls are first described as working like 
macro expansions, but then the specification adds that there must be 
magic fixups so that variable names are resolved in point-of-call 
context anyway.)

At this point in the history of computing, the conceptual distinction 
between subprograms and macros was not at all clear. It was quite 
possible to have "macros" that generated an out-of-line subprogram once 
and then generated calling code the first time and every time thereafter 
(it was a way of life on systems without linkage editors or linking 
loaders), and it was also quite possible to refer to in-line macro 
expansions as "subprograms". I suspect that the triumph of FORTRAN may 
have had something to do with cleaning up the terminological mess by the 
mid-60s.

Into the 60s, indeed, there were still machines being made that had no 
instruction comparable to the mainframe BASx/BALx family, or to Intel's 
CALL. You had to do a subprogram call by first overwriting the last 
instruction of what you were calling with a branch instruction that 
would return back to you.

> Followup question #2: For simple arithmetic expressions, I can
> possibly understand how the UPDATE closure might be implemeted
> (expressed in Lisp to make the intent clear):
>   Call form:  MyFunction(X+2);
>   GET closure:  (+ closedX 2)
>   UPDATE closure:  (lambda (newval) (setf closedX (- newval 2))
> Thus from inside MyFunction where formal parameter Arg1 is bound
> to actual parameter X+2, after doing Arg1 := 7; X will have the
> value 5 so that calling Arg1 will return 7 as expected, right?
> But if the actual argument is something complicated, especially if
> it makes a nested function call, how can that possibly be
> implemented?

It was forbidden. In the formal definition of ALGOL 60, there was no 
such thing as an external subprogram (except for non-ALGOL code, which 
was treated as magic), so the whole program was supposed to be one 
compile. Therefore, a theoretical compiler could verify that any 
parameter used as an LHS was always matched with an argument that was a 
variable. (However, a "thunk" was still required to evaluate any array 
index and, possibly, to convert between REAL and INTEGER variables.) 
Many actual compilers /did/ support separate complication as a language 
extension -- I suppose they had to use run-time checking.

-- 
John W. Kennedy
  "Compact is becoming contract,
Man only earns and pays."
   -- Charles Williams.  "Bors to Elayne:  On the King's Coins"



More information about the Python-list mailing list