←back to thread

232 points todsacerdoti | 3 comments | | HN request time: 0.415s | source
Show context
kragen ◴[] No.44506606[source]
It's interesting to think of "calling" as "summoning" functions. We could also reasonably say "instantiating", "evaluating", "computing", "running", "performing" (as in COBOL), or simply "doing".

In Mauchly's "Preparation of Problems for EDVAC-Type Machines", quoted in part in the blog post, he writes:

> The total number of operations for which instructions must be provided will usually be exceedingly large, so that the instruction sequence would be far in excess of the internal memory capacity. However, such an instruction sequence is never a random sequence, and can usually be synthesized from subsequences which frequently recur.

> By providing the necessary subsequences, which may be utilized as often as desired, together with a master sequence directing the use of these subsequences, compact and easily set up instructions for very complex problems can be achieved.

The verbs he uses here for subroutine calls are "utilize" and "direct". Later in the paper he uses the term "subroutine" rather than "subsequence", and does say "called for" but not in reference to the subroutine invocation operation in the machine:

> For these, magnetic tapes containing the series of orders required for the operation can be prepared once and be made available for use when called for in a particular problem. In order that such subroutines, as they can well be called, be truly general, the machine must be endowed with the ability to modify instructions, such as placing specific quantities into general subroutines. Thus is created a new set of operations which might be said to form a calculus of instructions.

Of course nowadays we do not pass arguments to subroutines by modifying their code, but index registers had not yet been invented, so every memory address referenced had to be contained in the instructions that referenced it. (This was considered one of the great benefits of keeping the program in the data memory!)

A little lower down he says "initiate subroutines" and "transferring control to a subroutine", and talks about linking in subroutines from a "library", as quoted in the post.

He never calls subroutines "functions"; I'm not sure where that usage comes from, but certainly by BASIC and LISP there were "functions" that were at least implemented by subroutines. He does talk about mathematical functions being computed by subroutines, including things like matrix multiplication:

> If the subroutine is merely to calculate a function for a single argument, (...)

replies(1): >>44508336 #
weinzierl ◴[] No.44508336[source]
"He never calls subroutines "functions"; I'm not sure where that usage comes from, but certainly by BASIC and LISP there were "functions" that were at least implemented by subroutines."

I think the early BASIC's used the subroutine nomenclature for GOSUB, where there was no parameter passing or anything, just a jump that automatically remembered the place to return.

Functions in BASIC, as I remember it, were something quite different. I think they were merely named abbreviations for arithmetic expressions and simple one line artithmetic expressions only. They were more similar to very primitive and heavily restricted macros than to subroutines or functions.

replies(1): >>44508625 #
kragen ◴[] No.44508625[source]
Right, that's what Algol-58 functions were, too. I think FORTRAN also has a construct like this, but I forget.
replies(1): >>44511846 #
bregma ◴[] No.44511846[source]
FORTRAN had both functions and subroutines. A function returned a value and was invoked in an expression (eg. S=SIN(A)). A subroutine was invoked by calling it (eg. CALL FOPEN(FNAME, PERMS)).
replies(1): >>44512135 #
kragen ◴[] No.44512135[source]
I should probably just Google this, but how did you define the functions?
replies(1): >>44513935 #
bregma ◴[] No.44513935[source]

    C     -------- START OF FUNCTION -------    
          INTEGER FUNCTION INCREMENT(I)
          INCREMENT=I+1
          RETURN
          END
    C     -------- END OF FUNCTION -------
replies(1): >>44514178 #
1. kps ◴[] No.44514178[source]
FORTRAN also had single-expression function definitions, e.g.

    ARGF(X, Y, Z) = (D/E) * Z+ X** F+ Y/G
Naturally this is syntactically identical to an array element assignment, which is one of the many things that made compiling FORTRAN so much fun.
replies(2): >>44515399 #>>44515493 #
2. kragen ◴[] No.44515399[source]
Yeah, that's also almost exactly the same as the Algol-58 syntax for defining such functions. And BASIC, except you had to say

    DEF FNF(X, Y, Z) = (D/E) * Z+ X** F+ Y/G
and the function name had to start with FN.
3. pklausler ◴[] No.44515493[source]
s/had/has/

In the flang-new compiler, which builds a parse tree for the whole source file before processing any declarations, it was necessary to parse such things as statement functions initially so that further specification statements could follow them. Later, if it turns out that the function name is an array or regular function returning a pointer, the parse tree gets patched up in place and the statement becomes the first executable statement.