Eric Raymond remembers:
I was writing some code the new-school way yesterday, prompting gpt-4.1 through aider, and for whatever reason my mind flashed back 50 years and the utter freaking enormity of it all crashed in on me like a tidal wave.
— Eric S. Raymond (@esrtweet) December 27, 2025
And now I want to make you feel that, too.
In 1975 I ran…
Yeah pretty much remember it all. The keypunch machine. Oh yes. There was no whiteout there. Punch a typo and eject the card forward. Then use the copy key to copy the characters from the old card to the new and be sure to lift your finger off the copy key in time else you’d copy the typo onto the new card. Now you have TWO bad cards in the stack that you have to remove before feeding them into the card reader tied to a PDP-11 that was connected via a dedicated serial link to the IBM-360 mainframe that would attempt to compile and execute your program as a batch stream. Usually two or three tries. Oh yes and when coding in FORTRAN-IV be sure to keep your program out of the collation field beyond column 71 on the punch card if you wanted the compiler to see it.
But it was heaven compared to my pre-college days wiring screws and rotary switches…
https://grok.com/share/c2hhcmQtNQ_8d8a54a4-6858-4f02-8b72-ae9369025e4a
My first job at Douglas (right after I separated from active duty) was in product support – when they found out I had ‘computer skills’ they decided I’d be the keeper of lists of spares needed to support a DC-10 for a year. These were things like cans of spray paint, misc fittings, crushed walnut shells to clean engines, etc…actual numbered parts were different.
And the plan was to punch cards on a keypunch they had stolen from the computing museum (and had never been serviced), punch a card for each item, then take the cards and print them on green-bar computer paper (for that full ‘computer’ experience.
Naturally getting a few dozen cards punched correctly was a challenge – mistakes, mispunches, etc. Then, printing them? The card reader would damage the cards requiring new cards be punched.
So, finally got the list printed (on multi-part paper, of course). Then, the editing. “Lets add another column!” “If we move this column over, we will have room for something else”, etc.
This was in around 1983. PC’s were just getting started….I had a Columbia (the first transportable, before even compaq)…dual floppy! 64K ram!
I finally went and bought a wide carriage dot matrix printer, and did the work at home using edlin, it was easier than using the punch cards.
I believe the proper term was “luggable”.
I remember my junior year in college being able to rent a “portable” thermal offset printing terminal with a 300 baud acoustic coupler! The case was about the size of an electric typewriter of the day. I could use it for dial-up service from the phone in my apartment. Goodbye keypunch machines! But it was expensive to rent. I only did one or two machine problems on it before I had to return it and get my deposit back…
Hmm. IIRC correctly the line oriented editor was called SOS. lol Never got the hang of Teco. I was too seduced by WYSIWYG editors by then.
Someone put together a huge macro that turned PDP-11 TECO on a VT100 monitor into an editor where you controlled the insertion point, and other common actions, with the numeric keypad.
I spent way too much time digging into that in order to add all sort of specialized and customized commands.
Yeah I remember that. It was called video TECO. I used it on an VT-52 on my first job at DEC after college. Then I was asked to stop. It was eating too much CPU on our time-shared prototype VAX-11/780 (serial #3) running in PDP-11 compatibility mode and locking out too many other users. But by then I’d discovered EDT which was also WYSIWYG. Used the keypad and didn’t tie the processor up in compatibility mode when idle.
I briefly had an AJ-modified Selectric with a built-in acoustic coupler, used to access TUCC at UNC, As I recall, I sold it for more than I paid for it.
I don’t think that link works as you intended 🙂 ..
Yeah, maybe a little too much sharing of irrelevant material. Should have reset the ‘conversation’. Oh well… lol…
But I wanted to give folks the true look and feel of a Geniac! Too bad there are no back side photos showing all the screws and wires! Wire wrapped mechanical madness using 1.5VDC!
PS: I tried to build the tic-tac-toe machine. Didn’t work. Found out *decades* later there was a wiring bug in the circuit diagram that came with the kit. Somebody posted a one-wire fix in the 90’s or the 00’s. I think that is hilarious…. Should write an emulator to see if it works… 😀
At the worlds fair in 1968, people lined up to play tic tac toe against a computer. I guess it was state of the art in San Antonio at the time.
Was that the tic-tac-toe machine from The Amateur Scientist? If so, it wasn’t the only electronic circuit they ever botched. The design of the nuclear magnetic resonance spectrometer in that Scientific American column, available in a collection work by the same title, was found to be non-workable by those who tried it. On the other had, the later instruction on how to build a helium-neon laser was spot on, and I did so when I was 11 years old.
No it was the last and most complex circuit described in the Geniac manual. It was one of the designs that used all six disks. Since the Geniac was stateless it was all done with combinatorial wired logic. There were only three outcomes: player wins, machine wins, or draw and a light to indicate machine’s move. To say it was stateless is a bit of a misnomer. It didn’t have flip-flops, but the position of each rotary switch held state for a particular move and they were turned in sequence. The best you should have been able to do was a draw. Can’t remember who moved first.
Back in the early seventies a local wag at my university promulgated an interactive tic-tac-toe program. But it didn’t play fair!
It said “Welcome to tic-tac-toe! Would you like to play first?” But if you said yes, it replied, “Too bad; I’m going first.”
It didn’t play a perfect game even so. But if you managed to get three O’s in a row, it said, “Hmm, didn’t see that. Well, I’ll just change my last move.”
It was a riot to show people.
I remember playing poker (5 card stud) against the computer during a summer program called JETS at UIUC for engineering candidates while still in high school. (Summer of ’73). It used an ASR-33 teletype running at 110 baud. Every deal or draw it would re-print the cards in your hand using ASCII art. Take bets, raises, folds and win or lose. I think it terminated if your chips went to zero. Quite clever.
Yep I remember those days.
And in 1978 I built my first COSMAC ELF.
I see complaints about “bloat” in software today.
Sure, there’s some of that. But a lot of “bloat” is making things easier for the poor humans trying to do something with that machine, without having to devote lots of time to learning how to cater to the machine’s limitations.
I can write code with manual memory allocation and grovel through the process of eliminating leaks and double frees.
Or I can write in a language that has garbage collection. Yeah I lose performance, but it’s ready to go and most of the time the performance loss isn’t measurable.
If it’s measurable, then I can think about re-writing the specific hot spots to regain that performance in the areas where I’ve measured.
I wish the software developers would stop changing the way things work – excel is a good example: I used to use ‘spin buttons’ for a lot of things. Various versions of excel would change how they work, or not work at all…. And ‘help’ is a tortious lie.
It was my FIRST use of AI. I found that ChatGPT and later Grok were excellent at answering any natural language posed question I had about usage of any Microsoft Office program.
I used to joke that if software engineers were put in charge of design and operation of the steering, throttle and brakes of your car we’d all be dead from the 2.0 version.
Now along comes Tesla with self-driving autopilot…
That doesn’t seem to work, considering the variations in versions of MS products…..
Hmm. Hasn’t been my experience. Then again where I work there is an insistence on using antique versions of MS Office for licensing reasons.
The interface designers need to be a separate group from the coders.
I’ve done it that way on some projects. The problem is getting designers who know what they’re doing.
I recommend interface designers that weren’t killed on the job and have working/complete extremities.
Or I can write in a language that has garbage collection. Yeah I lose performance, but it’s ready to go and most of the time the performance loss isn’t measurable.
Technically I suppose my very first exposure to such a language was LISP. But outside of one semester of an AI course in college (back when blocks world SHRDLU by Terry Winograd was state of the art) I never used it again. Well, not counting Emacs-Lisp hacks. My first real practical exposure was Java. Which I’m still not too uncomfortable in if you don’t mind stringing together primitives like readers and buffered readers and what and not. The write once run anywhere was very attractive at the time. But almost all practical quick and dirty coding these days is in Python. If it has to be really quick I will sit down with Grok and carefully compose a series of questions to get it to write the code. Then I’ll massage it to suit. I find Python a little more intuitive than Java.
void Word(God) extends Heaven implements Earth {}
Works great for any and all object oriented religions.
In 1974, I learned IBM 360 assembler on a machine with 32K of memory – 8K for the operating system, and 24K for the application. I couldn’t imagine how to fill that much memory.
In 1979, still working in assembler, I was writing event-driven, multithreaded code. I didn’t learn any of that in school; I had to invent those concepts myself.
Well, times have changed, haven’t they? I retired just before my job started incorporating AI generated code, and I think that was just in time. Now I can laugh and point fingers.
You are amazing.
Agreed. That’s awesome. Of course you do realize it was Microsoft invented that in 1995…
Thanks, you all made me feel young today. My first computer was also a PDP11. DEC had recristened it the DEC D116 and sold it commercially. We had the fancy Kenedy tape drives by then but we still toggled in all the diagnostic programs.
Engineering class had two computers available. An 8k Wang and a 16K. Insufficient for 30 or so students in that class. Not to mention all the other classes used the same ones. Didn’t learn programing as I didn’t know how to type at the time and there were always people in line that were quite annoyed with me.
Couldn’t afford a Commodore PET but I got the luggable Radio Shack PC with dual floppies. Used punch tape for “computer-aided learning” at junior college. Got exposed to VMS at university. I’m still at the C++ level, though I did learn to program a serial port driver in assembler. My work involves automation where the programming languages are stuck on ladder logic, function block diagrams and sequential function charts. All very structured and boring.
Thanks y’all for making me feel like a young’n. I’ve only been programming for 43 years.
Me, too. I got a late start, beginning on a VIC-20, just like Elon Musk. Of course, he was 12 and I was 32…
I too, started in a VIC-20.
On.
I learned programming in the punch card era with WATFOR and WATFIV interpreters on IBM 360s. Then we learned ALGOL and I fell in love with its elegance. As a grad student, I programmed a control system for an MS10 mass spectrometer on an Apple ][, running UCSD Pascal on a p-code machine. That compiler was about a hundred times faster and more reliable than any contemporaneous C compiler on the Mostek 6502 8bit architecture. So the little computer did great with Pascal and a soupcon of 6502 assembler code in 64k of memory. BTW, a little movie reference. In the movie The Terminator, when “Ahnold” is giving us his point of view, he’s displaying 6502 assember code.
Mmmm, ALGOL.
‘splain to us, in 500 words or less, how “call by name” worked.
In 30 glyphs or less write a sparse matrix reduction in APL demonstrating whichever technique you chose. Extra credit if it demonstrates profile reduction…
Don’t know whether APL supplies a simple way of coding a sparse matrix algorithm given that its philosphy is to operate on matrices without breaking them into loops on matrix elements.
Call by name in ALGOL was a “thing” that made ALGOL different from Pascal, Modula or even C that removed this feature that was complicated to understand and complicated to implement.
My take on it, and this has a Wikipedia article if anyone is interested, is that you could supply an algebraic expression as an input argument to a procedure or a function, and instead of evaluating that expression once, when the procedure or function was called, it reevaluated that expression from its component variables every time the call-by-name value is referenced inside the procedure of function.
To borrow a phrase from the late Douglas Adams, it was somewhat but not completely unlike an anonymous function or a “lambda” expression which is the feature programming language hipsters claim is essential. What this supposed to help with is writing a generic non-linear optimization algorithm that you can pass different functions to optimize without rewriting the algorithm code for each such function.
The point of this is that ALGOL had a sophistication that was so far ahead of its time that subsequent languages imitated ALGOL without people understanding what ALGOL offered.
Well Paul you sent me scurrying over to my Emacs Lisp initialization files. There is a case there that uses the ‘lambda’ operator to define a function on the fly to determine the existence of a file in a directory before either passing that filename to the mapcar function or a nil. I use it for parsing where to find an Emacs tags file in a somewhat convoluted project directory structure.
I think I got that example from Grok. Not something I hold in my head…
APL (or at least the later version I used), as well as its descendants, such as A+ and J, worked very well on sparse matrices.
I can’t remember the ALGOL syntax, but it is implemented in Pascal. If you pass a variable to a function or procedure “as is”, it’s pass by value, the only option available to C-style languages of that era. In Pascal, if you precede the variable name with the word “var”, its pass by reference, or pass as a modifiable variable. In that case, modifying the contents of the variable within the procedure means that the calling code’s version of the variable is also modified. In C, to get call by reference, you have to pass a pointer to the variable rather than the variable itself.
It was the insistence on having to pass pointers all the time that made C such a dangerous language to use in the early 8-bit era. Mess up with a pointer call just once and you could easily wipe out the operating system. Pascal does have pointers, and you CAN use them to pass parameters C-Style if you want, but like the attack sub’s reactor going to 105% in Hunt For Red October, not recommended.
No, call-by-name was something different from either call-by-value or call-by-reference. It was more like macros; the passed expression is re-evaluated whenever used, so you could pass, say, “i” to “x” and “a[i]” to “y”, and if you changed the value of “x” (i.e. “i”) it would change which element of “a” is referred to by “y” (i.e. “a[i]”).
It was a tricky bastard, and tough to implement correctly. If I recall correctly, you couldn’t just do it textually like macros, since the procedure you are calling might have its own definitions of “i” or “a”, and call-by-name was supposed to refer to the “i” and “a” in the caller’s environment. It let you do some “clever” things but I think a consensus emerged that it was too clever by half. But not a universal consensus; Scala still claims to have them.
Implementation, I have read, depends on “thunks.” A thunk could be thought of as passing a pointer to a short block of code implementing what call-by-name does according to your description.
It may have been expensive in time and memory to implement correctly, but it may be even tougher to use correctly given the trouble this can create if the programmer doesn’t fully understand not only what this does but also what it is useful for.
But as you indicate, it hasn’t gone away, and I guess lambdas (anonymous functions passed as parameters to other functions) may do a similar thing to a similar purpose, and now even stodgy, plodding Java has a version of this.
OK, got it. This would violate the idea of having a single pass compiler. It’s more like an interpreter implementation, which of course you can do in Pascal, if you want to write the interpreter in Pascal.
Newer Pascals do have the ability to pass function pointers to procedures, so that would be a little like call by name.
I’m now a bit vague on Pascal, though at some point we probably all used it, especially Borland Turbo Pascal, back when we transferred files with Kermit. ^_^
Anyway, I’m thinking that in Pascal, a pointer reference always referenced something due to the syntax, whereas C had no guardrails. You just declared that something was a pointer and that was that, whether it pointed to anything or not.
Correct. It made passing pointers a LOT safer, not like the C Wild Wild West.
In my experience, with a little discipline, if your program compiled (fast because it is 1 pass), it had a very good chance of working.
It’s no accident that as the world of C evolved through C++ to C#, it all started to look a lot like Pascal. For grins, a (void) function is just a procedure.
For C/C++ there was always the non-freeware ‘Purify’ that looked for uninitialized pointers and for memory leaks caused by pointer reassignment to malloc’d memory w/o first doing a free. That was pretty slick. I saved myself a lot of hassle in that area by almost never using a local variable as a pointer to a malloc’d block. Or at least always making sure for every malloc’d pointer there was a corresponding free() before a return.
I started on mainframes in high school (1970) with FORTRAN IV, and continued through my undergraduate and half of my graduate education on mainframes with punched card input. The first time I used a keyboard and screen was on a little PDP-11 my graduate research program bought. It had a wonderful text editor (MEDIT), and a FORTRAN compiler that worked amazingly well on a 32 kB machine – though as a 16 bit machine, even in double precision, my numerical methods homework integration problems would diverge over a sufficiently large domain. I fell in love with the paradigm, which became the personal computer milieu. I bought the first IBM PC sold in San Bernardino county, with a completely worthless UCSC P-System FORTRAN compiler, and a dot matrix printer, for $6,500. After failing to find a working FORTRAN environment, I fell back on learning BASIC, which turned out to be perfectly serviceable for my needs. With an 8087 co-processor added to my machine, I was able to use it to write a launch vehicle sizing and performance code that served as the foundational tool of the TRW Launch Services Organization. The last code I wrote for pay was a maneuvering reentry vehicle trajectory optimization code in Leahy Fortran, for the Air Force, back in 2005. Of late, I have settled on using Maple for all of the “work” I do, which is whatever I’m interested in involving mathematics at any level. It solves math symbolically, has its own clunky programming language, and has a fairly straightforward array of excellent graphics output. That minimizes its power, which is so vast that I’ll never fully utilize in my lifetime. It was what a few of my contemporaries and I dreamed of circa 1980, the ability to assist mathematical derivations by a) keeping track of the algebra, and b) supplying every piece of information known to humanity about that algebra as an assist. Mathematica is its main rival, or colleague, depending on ones point of view. I’ve tried AI a couple of times, with mixed success. Maple is probably the limit of my advanced development environments.
That’s “UCSD P-System”, not the non-existent UCSC.
Actually, UC Santa Cruz is not only a “thing”, they are a research university with a strong reputation. But they didn’t original the P-system computer language compilers.
Not to be confused with the Santa Cruz Operation, aka SCO. You *did* pay your licensing fee to SCO in order to use RedHat Linux. Right?
heh
Maneuvering reentry vehicle trajectory optimization is of serious interest to me. Is there a paper or an unclassified report on this? Are you able to disclose anything about it, such as whether you used Optimal Control methods, either “direct transcription” or an indirect method based on the Pontryagin Maximum Principle (PMP)?
What I “do” is high-order solution methods for non-linear systems.
If you used the PMP, how did you address the difficulty of a highly dissipative state equation? Bryson explains that if the state decays rapidly as in the reentry vehicle decelerating rapidly, the “costate” grows rapidly, requiring a large number of multi-shooting intervals for any hope of numerical convergence. Bryson had suggested alternating forward sweeps integrating the state equation with backward sweeps of the costate equation to deal with this. Any insight into this?
Unfortunately, I never wrote a report, just a user guide – deliverable under the contract, but not something I could retain. The optimization method was what I was actually interested in trying out, and the whole reason I volunteered to develop the code (not something I had done in years, and really had to knock myself out doing). It’s a very simple one, developed by Metropolis, and known as “simulated annealing.” It’s covered in Numerical Recipes, and I won’t go into details here. What I was really interested in was space launch vehicle ascent guidance optimization, but a trajectory is a trajectory, and I wanted to see how well it worked. I had already found a reference to the fact that simulated annealing had been applied to the Bryson time-to-climb problem for the F-4, and had beaten Bryson’s optimum by a couple of seconds. My testing of the algorithm was abruptly truncated by my being hired by a more attractive employer, but everything I learned about it was good. I’ve since found that others have developed convex optimization algorithms that operate in real time, and were tested on Masten suborbital rockets demonstrating astounding results of starting at random points at altitude, and autonomously reaching precise landing points that one normally wouldn’t think possible. I bow to their superiority, but have no insight into their working.