Common Lisp images communicating like-a-human through shared emacs slime and eev

screwlisp (he/him, they/them) - IRC: screwlisp, https://gamerplus.org/@screwlisp, https://screwlisp.small-web.org/

The following image shows where the talk is in the schedule for Sat 2025-12-06. Solid lines show talks with Q&A via BigBlueButton. Dashed lines show talks with Q&A via IRC or Etherpad.

Format: 26-min talk ; Q&A: IRC https://chat.emacsconf.org/?join=emacsconf,emacsconf-dev Etherpad: https://pad.emacsconf.org/2025-commonlisp
Etherpad: https://pad.emacsconf.org/2025-commonlisp
Discuss on IRC: #emacsconf-dev
Status: Q&A finished, IRC and pad will be archived on this page

Description

Demos a typical orgmode user's regular useages, segueing into Eduardo Ochs' eev executable-logs emacs style generally emphasising language/target interoperability ANSI common lisp / C / emacs lisp / org-mode / eev homed around eev.

On the theory that an agent is intelligent to the extent it is human-relatable, an autonomous software agent is started which receives messages pushed to an emacs lisp list, but otherwise does its own thing using eev eepitch, just like the human does.

Good as a normal lisp-user emacs example underscoring the org-mode and eev focused talks feeding into using software agents that use emacs/eev exactly like the human does via my port to emacs of Sandewall's 2014 Leonardo system software-individuals release.

Naturalistic style.

Some related blog articles.

Weekly shows past.

Q&A will be on IRC and in LambdaMOO.

Q&A in LambdaMOO:

As an experiment, screwlisp will also be taking questions from LambdaMOO. Here's how to join:

  1. Use M-x telnet to connect to lambda.moo.mud.org 8888. Alternatively, you can use a web-based client like https://mudslinger.net/play/ or rmoo.el (see rmoo.el note below)
  2. connect Guest to connect as a guest. If that doesn't work, please ask in #emacsconf-org and we'll try to get you sorted out.
  3. Agree to the terms by typing YES.
  4. Teleport to where the speaker is by typing @join screwtape.

To say something, start with " and omit the ending quotation mark, like this: "Hello everyone!. To say something to a specific person, start with a backtick (`) and the person's nick, then your message, like this: `sachac I made it to LambdaMOO. Use help communication to learn more about other communication tools, such as : for emoting and whisper for sending private messages.

rmoo.el note: You may need to define process-kill-without-query if it doesn't exist on your computer. Here's a use-package declaration that might be a good starting point. If your version of use-package doesn't support :vc yet, you can check out the code from https://github.com/toddsundsted/rmoo and add it to your load-path, or use M-x telnet for now.

(use-package rmoo
    :vc "https://github.com/toddsundsted/rmoo"
    :init
    (unless (fboundp 'process-kill-without-query)
        (defun process-kill-without-query (process &optional flag)
            (set-process-query-on-exit-flag process nil)
            t))
    :config
    (rmoo-worlds-add-new-moo "LambdaMOO" "lambda.moo.mud.org" "8888"))

You can also ask questions via BigBlueButton, Etherpad, or IRC, and the host will try to make sure your question gets to the speaker. Enjoy!

About the speaker:

Flocking lisp images with Screwlisp (Lispy Gopher Climate and https://screwlisp.small-web.org/).

Transcript

[00:00:00.000] Introduction
Hey, everyone. This talk is on this tradition, intelligent agents in Emacs using my Leonardo software individuals, which I've mistyped as I just wrote here, I see. Thank you to Sacha and everyone at EmacsConf and Emacs, I guess. Sorry that I was running late. I'm screwlisp.small-web.org. I run those one or two weekly shows for a long time, the Lispy Gopher Climate. I'm active on the Mastodon at @screwlisp@gamerplus.org. I'm screwtape on lambda.moo.mud.org. And I ported, over the last kind of year, years, to some extent, I ported Eric Sandewall's system for developing intelligent software agents, which he finished working on in 2014. I got it working again around 2025. First, we're going to take a long arc. We're going to motivate... This is the idea. You can see I'm using Org Mode, which I hope provides a good example for all the Org-Mode-oriented talks this conference. But you can also see that I'm using Eduardo Ochs's eev minor mode with Org. But we can see a little bit of the difference between these two, and that will kind of evolve into my style with the agent communication in Emacs. So you can see I used eev anchors as my Emacs headings. In eev, you just evaluate Elisp expressions as links to places. An anchor will link you somewhere else in the document. So my table of contents links to my talk, I guess. Anchors come in two halves, so that's why I built that unique table of contents experience there. What else am I going to say?
[00:02:21.480] Totally normal computing
So first, let's just do some totally normal computing because intelligence is going to be difficult to describe. Let's just try and compute normally in Emacs in Org Mode and then segue more so into eev, and then maybe I would like if an agent was intelligent, I would think that an intelligent agent would do something like what I'm doing. It should be recognizably similar to what I do myself. I don't think the word intelligence is relevant if it's not related to something I'm not familiar with.
[00:02:55.680] Using Emacs as a human
Using Emacs as a human, reading headings from my article, using Common Lisp. Right, my friend jeremy_list wrote actually a big project, but part of it was base64 encoding, and I just yoinked his C code for base64 encoding, I think. This is just clearly some C-based 64 encoding. If you go to my blog, his project is actually a C++ project and you can see me doing this with C++ rather than C. But basically, you can go to my blog articles if you want more detail to read something instead. And then here's some embeddable Common Lisp, Jack Daniel's ECL ANSI Common Lisp compiler I guess. This is just what it looks like. You can see I'm using Org Mode trickily, using noweb to put the lines of the C source block in this one. We're tangling it to this file rather than evaluating it. So, you know, literate programming, tangle and weave. We're just using Org Mode like the other Org Mode people are all showing us this conference, I guess. Then we have to compile it. It's always hard to remember these invocations for me. Results file. The file is my .fas file, because the way ECL's C and C++ integration works is that it just has to be seen by compile-file in Lisp. I cached this earlier. Oh, I should actually start Lisp, actually, shouldn't I? How are we going to do this? (setq inferior-lisp-program "ecl"). We could M-x slime. Because... we better actually load this. I did a dry run before. I think we can just load this, because I already did it. But I cached it. Let's nuke the cache. Okay, I'm going to say that that probably worked. Now, as you saw, that base64 encoding was just, I guess, number to character code to other character code. So I wrote this higher-level Lisp one, but that's not really the point. Obviously, Emacs also has Base64 encoding. It's just a point that we might have C++ and C external programs that we'd like to be integrating into our Emacs agents capabilities. Here we can see a normal named Org Mode source block. that calls that function, then an Org Mode source block that calls Emacs's base64-decode-string as a way of validating it, I guess. We go to Org, so we can see... I have a named call to that function calling the Lisp function Org is just kind of like this. It's cached but I don't seem to have run it before. Then I do the Emacs decode. So if we just run this using C-c C-c, and we can kind of see what Org Mode is like a little bit here. All right, yes, so as we can see, oh hang on, let's run this as well actually. So the C embeddable Common Lisp base64 encoding gets us this. And then Emacs is decoding and gets us back, kind of validates it. I think I'm missing some things. I don't pad characters out to the correct byte lengths, that kind of thing, but it's fine.
[00:06:45.400] using this via eev as a human
And then I kind of contrast that to, I really like what my friend mdhughes.tech, game dev of the ages, calls REPL-driven development, which he says is kind of the opposite of literate coding. I think eev, at least for me, is kind of like REPL-driven development. So in eev, if you just press F8, the thing happens. And if it's a red star line, the thing is an Emacs Lisp thing, and otherwise it goes to the eepitch target. So if I do this, great, now I'm pitching to that slime REPL ECL I made. And then I pressed F8. Press F8 again. The string got coerced to a list. F8. Now it's car codified. I quite like this, because this looks like something I can do and understand doing and reason about doing. Then I form a command to send from Lisp to Emacs. Then I do it and I recover the string from the beginning. I guess I had one of these here. Oh, by the way, look at What Org Mode did with an eev source block. And then when I close the source block using C-c ', it brings me back to the Org doc, which was a cool synergy between the eev minor mode and eev source blocks in Org Mode that I noticed. And so I kind of want my agents to be like this eev usage. Clearly, Org is super powerful, but I don't even like writing calls like this, where you write the function that will happen last first, so you're kind of writing right to left, first to last. Whereas in REPL-driven development, I guess I'm writing top to bottom, and eev, I guess, executable logs are logs that are like that. So I kind of like eev's view for reasoning more than Org's Tangle. Obviously, Tangle is trying to do tricky things, but maybe they have different specializations, and eev's one is more close to my own version of intelligence, maybe.
[00:09:07.800] Software individuals using eev in Emacs like a human
Software individuals using eev in Emacs like a human. Yeah, you can always visit my blog post for more detail. Right, I made a CLOS object in Common Lisp to wrap doing this. It's not really the topic. It's in the appendix somewhere if you need it. So I've just executed that. You can look at the appendix in your own time.
[00:09:32.080] Sandewall's leonardo system
Jumping over to actually starting our hypothetical intelligent agent. I guess we're doing eev here. So if we open this, press F8 a bunch of times. Oh, and if you were cloning it yourself, I guess that's what you would do. setq eepitch-buffer-name. Oh yeah, if you went to an eepitch shell and then came back. You would have had to do that, but I didn't. I didn't, so I didn't need to. Sandewall's style is to use relative paths to tell which agent is acting inside a software individual. Remembering a software individual is potentially a bunch of agents. And we load... So one individual, all the agents in each individual share a kernel. So only one agent in one software individual is active at any given time, but the agents are separate. They just all have to share the kernel resource, which is the Remus agent. Oh, I got rid of this. And start the CLE is the thing. Oh, I did need to have an EmacsConf knowledge base. Well, let's just keep eepitching for a little bit. So I think I made... I'm going to call it emacsconf-kb. Right, that looks likely. And I think that the agent... I can check this. I could have checked that. I could have done something like (get emacsconf-kb contents). Yeah, and you can see there's a location inside it which is agent1, which I assume is an entity file that I was working with before. And then what were we going to do? Oh yeah, back to the embeddable Common Lisp image. So if I just press our button back to there...
[00:11:36.100] Start a loop for one leonardo software individual
And so my idea is that for an Emacs agent, basically, I'd like to have an Emacs Lisp list. And just when stuff gets into that list, the agent which is always running, but running slowly, will incrementally just do the stuff it finds in that list. Populating that list probably gets into stuff like your Beliefs, Desires, Intents framework and those kind of well-known and well-studied algorithms. That's not the point here. I just want to have a list in Emacs that my ECL... I'm just going to run a loop in ECL, and the ECL is going to keep sending anything it finds in that Emacs Lisp list to the software agent. The agent is also in Emacs, so it would be able to populate its own list itself if it had an idea of evaluating desires and chances to improve whatever it wants to improve and chances to avoid whatever it wants to avoid. We talked a little bit too much. Let's just start this. Sorry that I'm manually setting up my screen. Then let's put CLisp over here. Right, we could work with this, right? This loop isn't very important. It's just a Common Lisp loop. I copy my friend jmbr's style of using Lisp machine-style keyword arguments instead of symbols like cl-loop, the compatibility thing in Emacs Lisp does. I'd never initialized that. Well, let's do that. Okay, now we have the list. And just every 30, let's turn it down to every 20 seconds. Hypothetically, it's going to put whatever it finds in there, into there. And so, I think, yeah, and now... Great. So here I'm just going to fill it with stuff. And this is quite interesting, I think. It just shows I can put a whole bunch of stuff into that list. Ideally, the agent would populate it itself with a BDI algorithm or something. But if we just put some stuff in there, we'll see that it will all get sent basically using Eduardo's eepitch internal machinery, at least. And hence, it meets my requirement that it works exactly like I work. And then in eev, I just have to press M-e. Oh, it works via Emacs server, and I didn't start that, so if we server-start, hopefully... And then, ideally, things will just begin happening in this slime-repl C/Lisp agent. Oh, if this was still running. Okay, well we got at least one, but hypothetically lots of these will happen. So, show agent, I guess, happened over here. I put a whole bunch of "sleep-for"s in, because I thought that going slowly would make it seem more human. Like I saw in Eduardo's talk last year which is where I learned about eev. The system is a little fragile. Hypothetically, we have a whole bunch of agents. I guess every time it gets sent, it checks that we're in the right agent. And it's not actually just sending a string, it's sending a sequence of string actions over there. And so we see Emacs Lisp hypothetically put, I guess it put this "foo bar baz!" into an entity, message-1, which should be of type message, I guess, conceivably. I forget if I set that up earlier. It's in the appendix somewhere. And then it just called, it did a sequence of actions which was really just one action of showing that. And then I called b64-encode on message1, which I believe will have set message-1 encoded. Can I check that manually while it's happening? Disaster. Well that's what it should have been. Well, I did mention it was a little bit fragile. What if we put... Can we kind of rescue this? I don't want to try redoing this. It's slightly fragile. What it would do, we can see the actions are kind of getting there, but somehow my message didn't end up getting encoded by that sequence of actions. So this decode will have also made the decoded one be null.
[00:17:23.280] Let's do it manually
Let's just do it manually. Should have worked. b64-encode, which calls out to Emacs to get everything actually done. Oh, I got interrupted by the agent. Well, if I do it manually, it worked. Hypothetically, the queue thing should have worked. Great. Well, you can see it's kind of working. Could be more robust. The reason is that I think what I did is a bit fragile, but the intent is that FIPA, Foundation for Intelligent Physical Agents's SL standard has tools for reliability through repetition and checking outcomes and that kind of thing. So I would use those. I'm not putting too much work into being ultra-reliable right now, but it kind of worked. We saw, I guess, at least Embeddable Common Lisp believed it used emacsclient externally, asynchronously, to send these to Emacs within Emacs. I put a whole bunch of sleeps into its thing to make it look slow and human-like, kind of happened because Emacs' model is that it's kind of single-threaded. Can I just... I bet if we run this again It'll at least look like it's succeeding because I fixed the base64 encoding and so forth in the background. I wonder if it will.
[00:19:11.400] Wrapping up
In the meantime, let's wrap up this talk to some extent. Then I'm just kind of saying what I'm expecting to happen. I took out next action. Originally, I was keeping the list inside of the agent. Then I decided to keep the list inside Emacs because I have kind of first class Emacs is my IDE, so I have better access to what's going on in my IDE.
[00:19:37.608] Intelligence
Then I wanted to talk about intelligence a little bit in whatever my remaining time is. I just have these great bullet points of Nosredna yduJ and Eric Sandewall. So Nosredna yduJ, when she was on the show quite a long time ago, she... I keep describing things as expert systems and she wanted to know what I meant when I said expert systems, and I gave her a Lisp software example and she said she personally wrote that software in the 80s that I was referring to and she wanted to know how it was an expert system. What I mean when I say expert system is a system that works kind of like I do and eev's eepitch does. It's where we can really reason in a very human-relatable way about what the inputs to the program is. And also a program should be exposed to other programs in terms of like a well-structured transfer of knowledge as inputs, and it should have a well-structured transfer of knowledge kind of outputs. I don't know why this b64-encode message wasn't working. Then we kind of faked it into working. It's going to be embarrassing for me if anybody watches this. But yeah, so yduJ's thing... And then I was going to also build that into Eric Sandewall's one. So this is my vision of expert systems as kind of maybe this is an important general style loosely associated with Lisp. Same as the Lisp editor Emacs. So Eric Sandewall's description of intelligence was that his grandchildren were intelligent. So if we had software agents that were intelligent, this would be true if and maybe only if they were similar to his grandchildren who were a good reference for intelligence. And grandchildren live for a really long time. They kind of learn gradually. They don't run on GPUs for a few minutes and then get thrown out forever, something like that. And so this is the kind of vision of, I guess, the Leonardo system software individual stuff. You can see we kind of faked it into... at least the show get message one decoded bits were working. I'm not sure what was happening with the Elisp ones that worked interactively, but then they didn't work in my loopy thing. Oh yeah, and then so I mentioned thank you to Sacha at the start of this talk. And so Eric Sandewall's emphasis that you'd really like intelligent software agents, Leonardo system agents, to be like your grandchildren. And I was talking to somebody, maybe to Ramin Honary who's doing the schemacs talk this year about Sacha's writing. A lot of Sacha's writing is about her experiences of life and technology, and especially raising A* and her observations of her progeny A*'s experiences of life and technology, I would say as well as being the Emacs News and Emacs conf doer that she is. Yeah, and so I think a lot of what Sacha is seen doing and concerned with are specifically what Eric Sandewall identifies as the study of intelligence as such, as should apply to computing as well. That was my thought on Sacha, Eric Sandewall, intelligence, and yduJ. I have this note from pizzapal... I didn't realize that Microsoft had announced that 2025 was going to be the year of the software agent. I only found this out in hindsight when I saw people crowing on the Mastodon about how Microsoft had basically declared that their Year of the Agent marketing campaign was a failure where basically people didn't like the same old web services but now while you're accessing, while you're formally kind of accessing a web service, the kind of web service that used to be called serverless web services, this kind of thing, but you're just being gibbered at by Microsoft Copilot while you're trying to use regular services. And people turned out not to like this. I think that, as we can see in this agent, the agent really needs to be running on its own clock and independently of you. Like if you imagine your body is getting novel, slightly speculative instructions from your brain constantly throughout your entire waking day, quite slowly, this is what an agent should be like. And it should be... Sandewall wrote about this. Basically, computer programs aren't going to want to use human natural language with each other. There's nothing desirable about that, so you wouldn't have two hypothetical Microsoft agents, which are just regular web services with a GPT model gibbering at you while you're trying to use the web service. I think we can see... Microsoft did the wrong thing with the word agent, allowing that agent is an overloaded term like static. I'm going to stop this. I'm not going to try and fix this. Sorry, everybody. Thank you. Talk to you on the Mastodon. Hopefully, see you on the show. See you at your conference talks. My blog has writing and examples of this with multi-agents, more C and C++ stuff, Lisp things. You're welcome to come on my show to be interviewed, however formally we do that. See everybody next time.

Captioner: sachac

Questions or comments? Please e-mail emacsconf-org-private@gnu.org