GeorgeTirebiter
GeorgeTirebiter on Hacker News
Related, for the CHM's IBM 1620 project, we received 4 entire cabinets filled with punched cards from Indiana University -- a prof there took every useful IBM 1620 program, and immediately made a copy and put those cards into what ended up being 4 card cabinets -- those deep things, with decks on both sides of each drawer. About 10' x 5' tall x 6' deep. As part of the project, we had a card reader that was capable of reading 'column binary' -- that is, it could read the bits on the cards, not just the encodings. I wrote a program to read ALL of those card decks in column binary and then took those around 200 files and put them into a single .ZIP file.
That .ZIP file holding ALL of the known commercial / scientific computing SW for the IBM 1620 fit onto exactly .... ONE standard 1.44 MB Floppy Diskette.
Interestingly, in the Olden Days, machines often had custom instructions. The pdp-1/D had a tad instruction for 2's complement addition (it was normally 1's complement machine), and there were also new pdp-1 instructions for timesharing.
For the IBM 1401, there were all sorts of add on 'features', e.g. the Multiply / Divide Feature (sped up * and / in HW), High-Low-Equal Compare feature, Advanced Programming (added Index Register, Subroutine Linkage), Move Record feature (allows right-to-left movement until hitting a Record Mark, useful for Tape), Expanded Print Edit Feature (float $ sign, automatic * insertion, etc), various memory sizes from 1,400 characters up to 16,000 characters. The point is that manufacturer-distributed software had to deal with having features (or not); and this was handled e.g. in the assembler by having a CTL card that listed (coded) the features, e.g. "CTL 31110" says this is a 12K machine, with Automatic Multiply / Divide, the High-Low-Equal Compare, the Move Record Feature, but NOT the Expanded Print Edit Feature -- that told the Macro Generator what it needed to know to properly expand macros for a specific HW configuration. (Certain Features did not require SW mods, e.g. the notorious "Print Overlap" feature that would speed up print operations by having a hardware buffer to hold the Print Line, so the CPU did not need to stall. The feature was notorious because the sub-rack of HW required to implement it connected into probably 75% of the machine's instruction decoder & execution units; when it failed, it was incredibly painful to find the fault(s)).
And, there have been Writeable Control Stores like, forever. It was a feature on the Burroughs B1700, where different control stores could be loaded on-the-fly depending if you were executing COBOL or FORTRAN or Pascal - the 'instruction set' would be optimized for running that particular language. The pdp-11 had some version of this, and CMU's custom C.MMP had something like this.
So, the desire for certain customers to have machines specifically honed to their use cases was normal. It has only been this brief period of homogenization of single-chip(ish) CPUs (8008, 8080, Z80, 8086... amd64 etc) that introduced new instructions in tranches.
The End-Users now get their custom instructions in other ways (e.g. PCIe and GPUs)
Now-a-days, I actively avoid RVxxx Zwhatever because those guys had their chance and seemed to have learned nothing from the IBM 360: SOFTWARE is what ultimately matters, as long as you don't have ridiculously expensive chips, keep the ABI consistent!
And, ARM learned from M0 and quickly came out with the M0+ --- which SHOULD be the 8051 killer (no offense to my friend John Wharton (RIP), 8051 designer https://en.wikipedia.org/wiki/John_Harrison_Wharton): M0+ is a lower-power, more efficient redesign of M0, 2-stage pipeline, Harvard bus, and optional features (MPU, MTB, fast I/O) that M0 lacks. The RPi Pico has all of these optional features except the MTB (Micro Trace Buffer), but does have 4 breakpoints / 2 watchpoints per core, 8 memory regions, single-cycle I/O port access, 30% less power than M0, and 12% less die area, 32x32 single-cycle multiply, Thumb-2: "32‑bit Performance at 8‑bit Cost" https://documentation-service.arm.com/static/60411750ee93794...
Maybe certain Chinese RV32E variants will get uber popular (WCH CH32V003 under a dime in quantity https://wch-ic.com/products/CH32V003.html ). Maybe.
I now generate ALL of my hobby projects in CL (SBCL on windows). I tell the LLM to 'over-comment' the code, so I get to learn as I read the output. It has been glorious. I generally use the web browser on an unused port on localhost for user IO (beautiful pages), and the app just hooks to Hunchentoot to serve.
Any 'real' programming language (meaning, one that is truly general purpose: numeric stacks, Web front and back ends, system code, utilities, etc) will always have some cruft. In CL, at least you can understand why some cruft exists. And you get used to it, because it's not like e.g. C where there are some very dark corners indeed. Check out Peter's book!
CL lets you build real apps, for real. No toys. This has value.
Life(actual) = Life(rated) x ( V(rated) / V(actual) ) ** 13
NOTE that 13th (!) power. Doubling brightness only requires a small voltage increase, but it causes the lifespan to be roughly 9% due to this law.Hams have known about this for decades, where is it common to run 14V or 12V lamps on 6.3 volts for dial / panel illumination. I have a Drake 2-B receiver that uses this technique, and I have yet to replace the 2 bulbs that light up the frequency dial.
I wanted something more 'algorithmic' - and more accurate.
So me and Claude build an sbcl-based Film Recommendation system. Type in a new film name, it goes to open film database OMDB, grabs the scores, and then, using films I have already rated and with a built-in tiny Neural Net, gives me a personal recommendation. It uses the OMDB data and an algo that weights those with my personal values (in half a dozen areas: overall, acting, cinematography, etc), along with a 'comments' box to note for friends / others.
The code is very well-done CL, heavily commented. The film & ratings database is stored as S-exprs, naturally, all in one file. I don't use a database as I only have a few hundred films, but maybe later I will. And that's the point -- this is a living chunk of code that I from time to time bolt in new features, or try new things (e.g. the UI is localhost:8080)
I fretted about having a 'real' project to really dig into CL for a long time, and finally, found a meaty-enough project that ends up being really useful & quite a learning (continuing learning) experience. I start it up inside emacs/sly like this:
(ql:quickload '(:hunchentoot :dexador :yason))
(load "s:/filmrec.lisp")
(filmrec:start)
I have to set the omdb key: (setf filmrec:*omdb-api-key* "fxxxx70")
Then, every so often, I retrain the NN: (filmrec:retrain)
Good Luck, you'll find a project. And with an LLM buddy, you'll succeed.But seriously -- newer Claude (and OpenAI and Google and ???) models DO find the smoking gun, if you let them keep going until they reveal the weird chain of events that leads to a bug. I was seeing the most obscure UART driver bug, where it would work at 1,500,000 baud (!) but fail by only outputting the 1st char at 230.4k and 460.8k -- and it was due to a very narrow race that would check the buffer, if not full, insert a character, and return BUT sometimes the TX Complete interrupt would happen between the check and the insert, and something else would insert, and then - buf overflow. At 1,500,000 the other process didn't have time to do that phantom insert. ANYWAY, Claude found this and proposed a fix -- simpler: spins on IRQ-protected buffer empty checks.
I'd hate to think how long it would have taken me to find that.
And THAT's the problem -- of course a human CAN find it, with sufficient focus and time; I'm sure you've found a complicated bug pretty easily sometimes, by sheer luck or good engineering instinct.
BUT, it seems to me, as human, we are capable of creating potential execution paths that EXCEED our ability to EVER figure it out -- due to not being smart enough, not enough time on the problem, or something makes it economically unfeasible.
THIS is where LLMs shine -- let 'em bang at the code for as long as it takes.
The recent Mythos bug-finding explosion I think is proof of this conjecture. I think of it like a chessboard, where a machine really can look at all possible execution paths, and locate obscure bugs; a human programer (akin to a chess program) is doing 'alpha-beta pruning' of what's likely, and only after that list is exhausted are the really weird possibilities examined.
LLMs are our friends. And, as for "WTF did the LLM just do" when it generates code? I always include the instruction "For this code you just wrote, use Best Practices to document this code, function by function and class by class, and when necessary, line-by-line, so that a junior SW developer can completely understand how this code works, using the documentation standard we use (e.g. Doxygen)."
I have also used this technique to learn new languages, or explore ones I only know a little -- it has been a godsend for leveling me up on common lisp, for example. "Give detailed comments explaining what the code is doing, assuming the code reader is fluent in C and Python, and use analogs when possible." Stuff like that.
The MOS 6502 was introduced at the WESCON tradeshow in September 1975 and sold for $25 quantity 1. They had a transparent vase full of them, 'proving' they did volume -- but those were all chips that failed post-manufacturing testing, except for the very top layer. Still...
I think, tho, the fundamental reason is: he specs the machine. It does exactly what he says it does. No edge cases, no surprising behavior that LLVM IR or WASM might have; also, I'm sure he spec'd it to make the algorithms he implements elegant or at least more understandable.
I suspect part our views comes from the purity of Mathematics (Knuth) and the actuality of Computer Science. I'm even sympathetic to your view, because then we could verbatim copy Knuth's algos to WASM etc and run them, and we get a twofer: a deeper understanding of the algo AND a deeper understanding of the underlying V-ISA (PTX, BEAM, WASM, LLVM IR, etc).
I think the learning / understanding of the algos Knuth presents partially comes from us Playing Computer, and manually going through the code. It's that pedagogy comes first, I think.
Next time I run into Don, I'll ask him about this. 'cause you're also correct about L1...Ln caches affecting performance drastically.
(And, yes, I had wondered why Don did MMIX he didn't create a "RISC-V" before there was a RISC-V; that is, why didn't he create the Next Great RISC Machine? He said he talked with John Hennessy and Richard Sites. This was in 1990.)
Here's HN on RISC-V vs MMIX: https://news.ycombinator.com/item?id=14635361
Don's first computer was the IBM 650 https://en.wikipedia.org/wiki/IBM_650?useskin=vector see also http://ed-thelen.org/comp-hist/KnuthIBM650Appreciation.pdf so MIX was a simplified version of the 650 because, well, it's well-defined and simple -- and Don knew a popular IBM machine very well. And there's this, in Vol 1:
This series of books is affectionately dedicated to the Type 650 computer once installed at Case Institute of Technology, in remembrance of many pleasant evenings.
MMIX is for all you youngsters who think RISC is all the rage ;-) and I think he does an admirable job creating a fully-defined machine that does use more modern hardware techniques. The fact that he fully defines his underlying machine is exactly correct, because it lays the foundation for precisely expressing the algorithms, and for giving Time and Space (runtime) estimates.
I believe it's fundamentally incorrect to think of these abstract machines as 'assembly language' but rather, I think, they define a stable foundation onto which accurately described algorithms can be expressed. You're supposed to 'play computer' and follow along -- step by step -- to understand the deep details of the algorithms.
If one is trying to do some assembly line (max # of operations per second), the power requirements alone get hard to manage. And then you're managing back EMF, eddy currents, heck, air resistance!
My rule: have dedicated low-level hw provide smooth PID response, mostly on the P term; and have a higher-level control produce the setpoint. Faster response means less need to rely on I or D terms as much (just because delta-T is so relatively small).
I'm not sure adding 'features' to Python anymore makes sense - UNLESS those features help humans understand LLM code. Part of the problem is, of course, that LLMs haven't been trained on the latest-and-greatest, so they won't output any of it (even new training events won't capture the latest very much, since there is so little of it relative to what is already out there).
But again -- do new features help HUMANS understand what the LLMs produce? If not, seems to me ... new features merely add complexity for no apparent gain. (Or am I confused about this?) THANKS for any helpful opinions.
LESSON: N E V E R Use code that can "stop working" until you pay ransom. N E V E R.
At this point, it's irrelevant, because the LLMs can replace PySimpleGUI with PyQt etc so --- thanks but no thanks. I did like it because you could throw up something around a CLI and it looked at least presentable. Now, since 2025, nobody codes anymore, so ... seems to me, this PySimpleGUI 6 is just a bit of history.
I am also curious: What hardware enhancements would benefit 'lightweight, kernel-enforced isolation' ? Do we need memory tags? HW Capability Lists? ?
( I believe we've concentrated far too much in making "damn fast pdp-11s" with our hardware advances, and far less on building Reliable Systems -- even if a few percent of peak possible performance is consumed by extra HW. )
is there something 'less good' about:
let v1 = if v0 < 0 then 0 else v0
Am I the only one who stutter-parses "0 > value" vs my counterexample?Is Yoda condition somehow better?
Shouldn't we write: Let v1 = max 0 v0
<- is somewhat better, but, again, for such a common operation, a single character is just more convenient. Sure, we could have editors that turn "=" into := or <- but now we're getting too fancy especially for something pedagogical.
I also don't mind the -> for C pointers; and certainly don't mind the <= >= or even == conventions (although at least today's compilers warn when they see "if (a=b) ...".
Ultimately, humans won't be writing code anymore anyway ( ;-) ?) so maybe the issue is entirely moot.
We're 'simply' moving up the abstraction hierarchy again. Good!