eepitch-send
, actions and the situation calculusHere I am going to explain my discoveries of why eev eepitch, and my common lisp useage,e-e-v
and eepitch-send
(defined here) are so revolutionary, and why in hindsight this was wellknown by Erik Sandewall to be important and fundamental. We also look at what actions are, and the userâs (programmerâs) relationship to actions. Actions are best related to changing situations and the situation calculus.
By the way, this is the basis for my upcoming emacsconf 2025 talk/Q&A (see their call for talks).
eepitch-send
Let us recall that eev-mode helpfully eclipses other emacs useage with a small number of effective idiomatic controls. Viz actions the key one is eepitch: when your cursor is near some code you want to happen in a document you are reading or writing, you press the F8 button on your keyboard. Then, unpiloted by you, emacs pops up a buffer on one side of your emacs window - the current eepitch target buffer, types the code you pressed F8 at into it, and then sends the typed code to the buffer as well, all while leaving you and your cursor on the other part of the screen in the document you were reading or writing yourself. Eepitch pitches red-star-lines to the environment itself (emacs lisp) and other lines to whatever eepitch-buffer-name
is (âred starâ is typed in emacs eev as C-q C-o
). By way of illustration
(setq inferior-lisp-program "ecl") ; press F8
^ red star line gets pitched to emacs ; don't press F8 on this line
(slime) ; press F8
^ red star line gets pitched to emacs ; don't press F8 on this line
(setq eepitch-buffer-name "*slime-repl ECL*") ; press F8
^ red star line gets pitched to emacs (what my buffer was named) ; don't press F8 on this line
(get-decoded-time) ; press F8
^ Seen happening on the other half of this buffer ; don't press F8 on this line
/ ; press F8
^ Seen happening on the other half of this buffer. ; don't press F8 on this line
If you werenât playing along hereâs what is on the other half of my screen as I write this right now:
; SLIME 2.29.1
CL-USER> (get-decoded-time)
37
18
12
12
7
2025
5
NIL
-12
CL-USER> /
(37 18 12 12 7 2025 5 NIL -12)
CL-USER>
Note that ANSI CLâs / // /// * ** *** + ++ +++
are exceptionally powerful with this useage (lists of last multiple returned values, recent first return values, recent commands).
Eepitch makes it very clear that the user is interactively choosing and pitching intended actions to other inhabitants of their interactive programming environment (their emacs environment) in the midst of other reading/writing/browsing/whatever engagements.
eepitch-send
and eev emacs as part of kernelspaceSandewall sets about to remand this useage of actions and down into the kernel (viz the bibliography here). I guess it has been said before that emacs is actually the operating system. Then as a user I should not be sitting inside kernelspace pitching commands upwards, but in userland (i.e. in a running program) pitching commands downwards into the my kernelspace (emacs eev), which provides the low level machinery for them (uniformly, for everyone, and with syncronicity implicitly managed).
Let us create emacs-lisp eepitch-send
and common lisp swank e-e-s
for lisp images to pitch down into the emacs abyss via swank. (Common lisp and its antecedents have had functionalities that Microsoftâs âLSPâ is a copy of some of in various forms for almost a century - anyway, itâs common for a lisp image to serve a swank server and for multiple swank servers to be slime-connected to a shared emacs server as we are about to see).
I composed eepitch-send
and e-e-s
here
Iâm actually going to use ielm-mode for emacs lisp here. ielm is sort of like a slime for emacs lisp.
(ielm)
(setq eepitch-buffer-name "*ielm*")
(defun eepitch-send
(buffername line)
(setq eepitch-buffer-name buffername)
(setq line (eepitch-preprocess-line line))
(eepitch-prepare)
(eepitch-line line))
and back over to common lisp
(setq eepitch-buffer-name "*slime-repl ECL*")
(require "asdf")
(defun e-e-s (buffername expr)
"'external-eepitch-send'
buffername string (emacs buffer name string)
line string (as eepitch)
"
(require "asdf")
(uiop:launch-program
(let ((*print-pretty* nil))
(format
nil
"emacsclient --eval '(eepitch-send ~s \"~s\")'"
buffername expr))))
(server-start)
We use Barlowâs uiop
posix-compatibility and start emacsâ own server to send our pitches into it from outside in a posix way provided by emacsâ emacsclient.
So the e-e-s
in the common lisp image asyncronously asks emacs emacsclient
to call eepitch-send
a lisp expression using emacs lisp.
We can see this funny circular useage:
(setq eepitch-buffer-name "*slime-repl ECL*")
(e-e-s "*slime-repl ECL*" '(1+ 1))
On the other half of my screen, I saw:
E-E-S
CL-USER> (e-e-s "*slime-repl ECL*" '(1+ 1))
#<a UIOP/RUN-PROGRAM::PROCESS-INFO 0x7fee354058c0>
CL-USER> (1+ 1)
2
CL-USER>
In situation calculus, a situation s0 (ess-zero) connects to situation s1 via an action. An action whose precondition is metâs postcondition is a change to the value of a fluent, and leaves us in a different situation. What a situation is is not further defined.
We can see that the users (us) are not in general doing the action ourself: Our proximal contribution was indicating our choice of an action to be sent into kernelspace, as we have defined it.
Hopefully I showed that emacs eev eepitch is coincident to Sandewallâs goal to reimagine actions and environments (eepitches and the emacs environment here) as the kernelspace and not the userland because they are not endemically high level, and moving them to a low level provides a uniform meaning to actions, action being the sitcalc concept.
See everyone on the Mastodon to talk about it (and at Emacsconf 2025 to hear about it!).
By the way, I am interviewing LambdaCalculus next week on the lispy gopher climate where we will get a preview of his HOPE and PhreakNIC presentations.
I think the arc of lisp history this article is part of, closely tied to righteous dissatisfaction with how unixlike userland and kernelspace got divvied up for high tech (such as lisp community) useages, is even more important now than when Sandewall wrote
we propose to change the overall software architecture (operating systems, programming languages, etc etc) in order to eliminate the considerable redundancy of concepts and constructs that contemporary software exhibits
in 2005.
ASIDE: By the way, Sandewall explicitly sees these changes as moving towards Interlisp D Machines. Though of course we can experience Interlisp Medley directly both natively and in a javascript virtual machine right now, canât we.
screwlisp proposes kittens