Friday, April 25, 2025

Get Over It (ai content)

I'm tired of people complaining about all the parentheses in Lisp, so I told Gemini to vent for me. This came out pretty good.

I suppose I'm guilty of contributing to the glut of AI slop, but while the text and tone are generated, the core idea and sentiment is mine, so it isn’t pure slop.


Alright, let's drop the hand-holding. You — yes, you — the one still whimpering about the parentheses in Lisp. It's time someone told you bluntly: Get over it.

Your constant refrain about "too many parentheses" isn't some profound insight into language design; it's a confession of intellectual laziness. It screams that you encountered something different, something that didn't conform to the aesthetic you were spoon-fed, and you threw up your hands rather than engage your brain.

Are parentheses really an insurmountable cognitive barrier? Are matching pairs of symbols truly beyond your capacity to track? Let's be honest. The core issue isn't difficulty; it's unfamiliarity coupled with a stubborn refusal to adapt. You've decided what code ought to look like, and anything else is dismissed as "hard" or "ugly" without genuine effort.

Thousands upon thousands of programmers — people with brains presumably no bigger than yours — have not only managed Lisp's syntax but have thrived with it. They've built complex, powerful systems. They didn't possess some secret anti-parenthesis superpower; they simply possessed the willingness to learn and adapt. They saw the structure, the consistency, the power behind the syntax, instead of getting stuck on the superficial shape of the characters.

Your complaint isn’t about usability; it’s about preference, and a remarkably shallow one at that. It’s like refusing to read a brilliant novel because you don’t like the font. It demonstrates a lack of curiosity, an unwillingness to look past the surface.

So, here's the unvarnished truth: The parentheses aren't the problem. Your rigid thinking is. Your demand that every language cater to your pre-existing biases is.

Stop whining. Stop making excuses based on trivial syntax. Either put in the minimal mental effort required to see the structure beneath the curves, recognise the direct representation of the abstract syntax tree, and understand why it is the way it is – or don't. But don't pretend your aesthetic preference is a legitimate technical critique.

The Lisp world isn't waiting for you to overcome your parenthesis phobia. It's moving on, building things, leveraging a unique and powerful paradigm. You can either engage your intellect and join in, or you can stay on the sidelines complaining about the punctuation.

Frankly, it's time to grow up and get over the parentheses.

Thursday, April 24, 2025

Lisp Debugger Wins

I'm gathering statistics from thousands of pull requests in GitHub. I wrote a little Lisp program to do that. It's taking a long time because it has to make a lot of API calls to GitHub and the calls are rate limited.

After about half an hour, I got an unexpected error. A user who made the pull request I was looking at had deleted their account. No problem. I used the Lisp debugger to walk up the stack to a convenient frame and returned NIL from that frame, causing that particular PR to be skipped. The program continued running from where it left off. I didn't have to restart from the beginning and lose a half hour of work.

The Lisp debugger for the win!

Sunday, April 20, 2025

Well This Was Interesting

I was playing with notebooklm.google.com and for fun I entered a few of my recent blog posts. I asked it to generate a conversation. The AI generated what sounds a lot like a podcast discussing my blog. One host sounds a bit like Mike Rowe. They get a lot of the detail right, but there are a couple of glaring mistakes. (Read - EVIL - Print - Loop) I suppose I am contributing to the soup of AI slop, but I was suprised at how natural this sounds. Podcast

I also tried giving it some text files about Tic Tac Toe representations. It generated a remarkably good “Deep Dive” that really sounds as if it has an understanding of the text: Deep Dive

There are some “tells” that this is AI and not human, but I wouldn't be surprised if this could fool the average layman. In a few years, it’s going to be really hard to detect, though.

Friday, April 18, 2025

Stupid reader tricks

Here are some stupid reader tricks for Lisp. I've tested them on SBCL, and they are of questionable portability and utility.

Run Shell Commands from the Lisp Prompt

(set-macro-character #\! 
    (lambda (stream char)
      (declare (ignore stream char))
      (uiop:run-program (read-line stream) :output *standard-output*))
    t)

> !ls -als
total 4068
   4 drwxr-x--- 21 jrm  jrm     4096 Apr 18 06:42 .
   4 drwxr-xr-x  4 root root    4096 Mar 22 17:27 ..
1900 -rwx--x--x  1 jrm  jrm  1940604 Apr 17 19:10 .bash_history
   4 -rw-r--r--  1 jrm  jrm      220 Mar 19 12:16 .bash_logout
   8 -rw-r--r--  1 jrm  jrm     4961 Apr  1 11:13 .bashrc
   4 drwx------  6 jrm  jrm     4096 Mar 21 07:52 .cache
   0 lrwxrwxrwx  1 jrm  jrm       51 Mar 24 05:20 .config -> /mnt/c/Users/JosephMarshall/AppData/Roaming/.config
   0 lrwxrwxrwx  1 jrm  jrm       50 Mar 26 03:12 .emacs -> /mnt/c/Users/JosephMarshall/AppData/Roaming/.emacs
   4 drwx------  6 jrm  jrm     4096 Apr 17 12:13 .emacs.d
      ... etc ...

>

Make λ an alias for lambda

(set-macro-character #\λ (lambda (stream char) (declare (ignore stream char)) 'cl:lambda) t)

> ((λ (x) (+ x 4)) 3)
7

If you do this you might want to add a print function for the lambda symbol:

(defmethod print-object ((obj (eql 'cl:lambda)) stream) ;; doubt this is portable
  (format stream "λ"))

> '(λ (x) (+ x 4))
(λ (x) (+ x 4))

> (symbol-name (car *))
"LAMBDA"

Thursday, April 17, 2025

DES Machine

The MIT CADR Lisp Machine had a number of static RAMs that were used in the processor for various things such as state machines and register files. The core parts of the LMI Lambda Lisp Machine were similar to the CADR (similar enough that they could run the same microcode) but technology had advanced such that the static RAM chips were typically double the size of the CADR's. The LMI Lambda thus had twice as many registers as the CADR, but because there weren't any extra bits in the instruction set, you couldn't address half of them. The extra address bit from the RAM was wired to a status register. So the LMI Lambda had, in effect, two banks of registers which you could swap between by toggling the bit in the status register. This was not normally used — the microcode would set the bit to zero and leave it there.

A friend of mine was interested in security and he had written a high performance version of the encryption algorithm used by Unix to encrypt passwords. He was experimenting with dictionary attacks against passwords and one bottleneck was the performance of the password encryption algorithm.

It occurred to me that I could store the DES S-boxes in the alternate register bank of the LMI Lambda. With some special microcode, I could turn an LMI Lambda into a DES machine that could churn through a dictionary attack at a high speed. I added a special Lisp primitive that would swap the register banks and then run several hundred rounds of the DES algorithm before swapping back and returning to Lisp. Then I wrote a Lisp program that would feed a dictionary into the DES primitives when the processor was idle.

I was able to discover a few passwords this way, but I was more interested in the proof of concept that the actual results. A microcoded DES machine would work, but you'd get better performance out of dedicated hardware.

Sunday, April 13, 2025

Mea Culpa

OH NO! There's something wrong on the Internet!

It is often me. Mea culpa. Mea maxima culpa. I'm only human.

But this is a blog, not a reference manual. I use it to organize my thoughts, get things off my chest, provoke discussion, maybe entertain a few fellow hackers, and show others how much fun I'm having playing with computers. Accuracy and precision aren't the primary objectives although I try not to be egregiously incorrect.

Mostly I see people misinterpreting something I say casually. I gloss over some details that some find important but I consider boring. I make the first-order error of assuming everyone has the same backgroud as I do and will interpret what I say in the way I had in mind. Clearly this isn't the case, yet I persist in thinking this way. Oh well.

I'll try to correct errors that are brought to my attention and will elaborate things in more detail if asked, but if my blog irritates you with its broad generalizations, inattention to detail, omission of specifics, and things that are just plain wrong, why are you reading it?

Emacs and Lisp

The first editor I learned how to use was TECO on a line printer. You’d print the line of code you were on, then you’d issue commands to move the cursor around. You tried to avoid printing the line because that would be wasting paper. So you’d move the cursor around blind until you thought you got it to where you wanted, and then you’d start inserting characters. When you thought you had it, you’d print out the edited line.

Another undergrad saw me struggling with this and asked why I wasn’t using vi. I had never heard of vi and I was amazed that you could view the code on the screen and move your cursor around visually before going into insert mode and adding text. With vi I was orders of magnitude more productive than with TECO.

When I came to the ’tute in the early 80s, I found that computer accounts were only routinely issued to students taking computer science courses. I hadn’t decided on a computer science major, so I didn’t have an account. However the Student Information Processing Board would give out a Multics account to interested students, so I signed up for that. The Multics terminal was in the basement and it had a dial up connection with an acoustically coupled modem: two rubber cups that the handset would cradle in.

Everyone at the AI Lab used a home grown editor called emacs, and there was a Multics port. I abandoned vi and learned emacs. The paradigm was different, but I didn’t see one as superior to the other. When I declared computer science as my major, I got an account at the AI Lab on the Decsystem 20 machine. The editor was TECO with the editor macros (emacs) package loaded.

When I took S&ICP, we had a lab with HP9836 “Chipmunks” running MIT Scheme. The Chipmunks were PCs, not time-shared, and each acted as its own Scheme machine, complete with an emacs clone for editing the code.

At the AI Lab, there were a couple of machines running ITS, the Incompatible Timesharing System. You could run Maclisp on them, but Maclisp was such a pig, using over a megabyte of RAM, that a couple of instances of Maclisp would bring the machine to its knees. The Lab had developed the Lisp Machine, a single user computer that would run ZetaLisp (the successor to Maclisp). In addition to Lisp, the Lisp machine ran the ZWEI editor. Zwei Was Eine Initially, and Eine Is Not Emacs, but rather an emacs clone written in Zetalisp.

ZWEI was integrated with the Lisp environment. You could insert Lisp objects in the ZWEI editor and their printed representation would appear in the edited text. The printed represention was mouse sensitive and had its own context menu.

If you weren’t using a Lisp Machine, your options were Unipress Emacs and Gosling Emacs which you could run on this new OS called “Unix”

Around this time (in the late 80s) a hacker named Stallman decided to write a new OS. His first task was to write an editor and he decided on a new version of Emacs written in its own Lisp dialect.

If you wanted to use Lisp, you interacted with it via Emacs.

These days, I use GNU Emacs and I load up the sly package. Sly is a slime fork and it turns GNU Emacs into an IDE for a Lisp running in another process. The interface gives you much of what you used to get when using ZWEI on the Lisp machine. You can evaluate subexpressions, macroexpand and compile programs, gather output, and run the Lisp debugger from within GNU emacs.

Emacs and Lisp co-evolved at MIT and Emacs has always been used as a front-end to Lisp. I’ve never gone back to vi, and when I’ve had to use it I’ve found it frustrating (but this is because I have forgotten everything about how to use it).

I understand that some people find Emacs impossible to use and have a strong preference for vi. Is the experience of hacking Lisp in vi any good?