Having said that, so many foundational libraries were implemented in Fortran (BLAS, LINPACK/EISPACK, LAPACK, MINPACK, FISHPACK, FFTPACK, etc.) - thanks for that.
Having said that, so many foundational libraries were implemented in Fortran (BLAS, LINPACK/EISPACK, LAPACK, MINPACK, FISHPACK, FFTPACK, etc.) - thanks for that.
It is easy to laugh but C programmers have demonstrated that they can't handle variable-sized buffers on the stack, malloc(), free() and all that.
Early versions of FORTRAN [2] didn't even have a stack, like you couldn't write recursive functions, the program would take parameters for array sizes when it boots and the memory layout would all be figured out at the beginning. When I was developing a display controller for persistence of vision displays for the AVR-8 it drove me nuts how the C compiler kept moving the stack pointer around all the time for no real reason when an assembly program could move data to and from statically allocated structures. [3]
FORTRAN and COBOL came out around the time Syntactic Structures did so of course there was not an established theory for how to parse grammars, no parser generators, etc. No Dragon Book, but the heroic techniques used to develop compilers in that age are legendary if not quite lost.
I wrote some FORTRAN programs in high school on a VAX, in a comparative programming languages class in college, converted a lot of FORTRAN algorithms into statically allocated Java in grad school in 1990 and in my postdoc I wrote a generator that wrote JNI bindings for LAPACK.
[1] ... e.g. the typical struct is < 4096 bytes
[2] before the FORTRAN 90 standard though you could set the /RECURSIVE flag on DEC FORTRAN
[3] we were done such a disservice by all those "it's so elegant to compute Fibonacci in a better programming language than BASIC" articles in Creative Computing because recursion is one of those things, like C's memory management, that most programmers can't really handle.
I dimly remember the reason for it not being recursive by default was it didn’t put local variables on the stack, and I guess /RECURSIVE (which I don’t remember) controlled that. Probably there was some SYSGEN parameter which limited stack size. There were people who would declare giant arrays as locals rather than putting them in named COMMON, so the user-friendly compiler default was to put them in a fixed PSECT because those same people would never be using recursion.
This kind of code then easily breaks by overflowing the stack if the compiler allocates them there.
But this then doesn't work that well if the procedure is called recursively, or concurrently from multiple threads.
Making this even worse, in a recent Fortran standard (2008?) this was reversed such that procedures must be explicitly marked with NON_RECURSIVE in order to allow the compiler to allocate variables statically. Undoubtedly the right decision given the increasing prevalence of threads as well as recursive algorithms, but a gotcha for compiling old dusty deck code.
Apparently, programmers would 'unpunch' a hole in a card by taping some paper back in the hole to save repunching a new card! And sometimes these 'chads' would fall out, making for some interesting debugging.