screwlisp proposes kittens

My eepitch-send, actions and the situation calculus

Here 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).

eev eepitch emacs and my common lisp 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.

My eepitch-send and eev emacs as part of kernelspace

Sandewall 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> 

The situation calculus

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.

Conclusion

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.

Fin.

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