(22 51 8 30 5 2025 4 NIL -12)
Momentary directions being distinct from hopefully articles of timeless principle! While I have a million and one things to do, the ones that occur to me to start with right now are blending
eev
being a way-of-operating in emacs, the McCLIM common lisp interface manager being a mechanism to operate and a kitten being a sort of reward for the other two. I have other ancillary tasks at the moment I will mention, but I am regarding those as kind of keeping-the-ship-afloat duties.
eev
If you are in emacs, the canonical way of learning about eev-mode is to install the package eev
and try M-x eev-beginner
. This is my own exploration a little past that. I am doing a version of literate programming using plain text markdown files, stowing multiline code inside my codeberg.org/tfw/screwlisps-knowledge.git repo. eev
’s eepitch
lets you blend emacs
elisp
lines and host language lines (for me, here, common lisp
, maybe a touch of shell
).
eepitch
useage for common lisp
This should probably should be the whole article. The key thing is that the one-line-y nature of eepitch
works incredibly well with ANSI common lisp’s * ** *** / // /// + ++ +++
repl special variables resulting in an extra-good version of point-free programming, or what I think of as basically R’s magrittr
package if you will forgive the explanation.
You just press <F8>
and the line you were on happens on the other half of your screen like-you-typed-it.
Consider this example I am using variations of all the time recently:
(eepitch-sbcl)
(elisp that starts you eepitching to sbcl) followed by
(require "asdf")
(asdf:load-system :mcclim)
(asdf:system-source-directory :swank)
(merge-pathnames #p"*.*" *)
(directory *)
(merge-pathnames #p"start-swank.lisp" **)
(load *)
this is more subtle than it appears becase, as seen walking through it:
(asdf:system-source-directory :swank)
⮕ #p"~/common-lisp/slime/"
(merge-pathnames #p"*.*" *)
⮕ #p"~/common-lisp/slime/."(directory *)
⮕(#P"~/common-lisp/slime/.git/"
#P"~/common-lisp/slime/.gitattributes"
#P"~/common-lisp/slime/.github/"
#P"~/common-lisp/slime/.gitignore"
#P"~/common-lisp/slime/.gitref"
#P"~/common-lisp/slime/CONTRIBUTING.md"
#P"~/common-lisp/slime/Makefile"
#P"~/common-lisp/slime/NEWS"
#P"~/common-lisp/slime/PROBLEMS"
#P"~/common-lisp/slime/README.md"
#P"~/common-lisp/slime/contrib/"
#P"~/common-lisp/slime/doc/"
#P"~/common-lisp/slime/lib/"
#P"~/common-lisp/slime/metering.lisp"
#P"~/common-lisp/slime/nregex.lisp"
#P"~/common-lisp/slime/packages.lisp"
#P"~/common-lisp/slime/sbcl-pprint-patch.lisp"
#P"~/common-lisp/slime/slime-autoloads.el"
#P"~/common-lisp/slime/slime-tests.el"
#P"~/common-lisp/slime/slime.el"
#P"~/common-lisp/slime/start-swank.lisp"
#P"~/common-lisp/slime/swank-loader.lisp"
#P"~/common-lisp/slime/swank.asd"
#P"~/common-lisp/slime/swank.lisp"
#P"~/common-lisp/slime/swank/"
#P"~/common-lisp/slime/xref.lisp")
Because I got this result live, I now have emacs’ autocompletion (M-/
= alt+slash) of the different paths when specifying the path I chose
(merge-pathnames #p"start-swank.lisp" **)
i.e. I typed #p"st<M-/>"
to get the #p"start-swank.lisp"
path.
This has the deep principle that the two computer programs being the running common lisp image and the emacs programming system are using each other by the same mechanism a human uses each of them. It is not that the human particularly programmed that they would get an autocompleting directory choice, nor that a feedforward neural network wastefully guessed this from its training. Simply by emacs using common lisp like-a-human, its autocomplete implicitly exposed the directory choices. Furthermore, instead of duplicating or wiring into common lisp’s return values and previous commands in a low level, manually programmed way, emacs is directly using what the standard provides (to humans). Well, I think it is deep. Fight me.
We can imagine writing this in a code block instead:
(progn
(require "asdf")
(asdf:load-system :mcclim)
(load
(merge-pathnames #p"start-swank.lisp"
(asdf:system-source-directory :swank))))
however we have to manually check that the file is #p"start-swank.lisp"
and get-it-right externally, with no local flow. The hypothetical compilation we get from writing this in one large partially inside-out fragment is meaningless in this case. The interactive step-by-step human approach is the better way for this program to work as well and this is one thing we got from eev
eepitch
.
Now, I said I am working on this this week. In particular, basically multi-line expressions that needs to be seen by a compiler need to end up tangled into my screwlisps-knowledge
git repo and then pulled in and used via interactive one-liners in the eepitch
. On the other hand, I also want articles that are line-by-line play-with-able examinations of the gets-compiled code. The way to do this is something of a research question!
As I mentioned in my simple common lisp interface manager application-frame
GUI example yesterday (as of writing) I think the flow of
indicates some powerful principle at work that I am still discovering. I am reminded of how in moulds, prions (also the cause of prion disease in animals) are used as a second unit of heredity. Since a new mould carries not just its parent’s DNA, but also its local contamination with prions as a second unit of heredity. Prions not being a pathology per se in moulds.
One particular attribute of the-way-clim-works for making interfaces is that defining application-frame
s is a MOP
ed macro and extension to the standard’s defclass
to automatically create the user interface of a program in terms of the define-application-frame
declarative form. On the other hand, the different sections (i.e. :panes
and :layouts
) are strongly interlinked which is a difficulty for line-by-line interactively constructing a particular application-frame
definition. But a pick-n-mix application-frame
declaration is also an attractive idea, to exploratorily discover new application-frame
types by breeding previous application-frame
s.
Hopefully we can make progress in this style while eventually actually giving an example of simply drawing an ellipse using McCLIM
’s implementation of the CLIM
spec. The thing is that it would be a misrepresentation of McCLIM to imply it was similarly simple-minded to something like java processing4 or javascript p5js. The common lisp interface manager does extensive intelligent work using its awareness of and access to its lisp image. The generation of interactive presentation-oriented programming from and of the common lisp object system is tightly joined to the idea of just-drawing-an-ellipse.
Kitten
, if you are just arriving, is my friend Aral’s server-side dynamic page generation tls-authentication-federation framework. Admittedly, the Kitten’s host language is javascript which is more selfish than lispy. On the other hand, my friend mnl’s (and many later users/maintainers) parenscript adopts a brutal but effective approach to creating human-esque javascript from native lisp code.
This week my goal for my kitten is to nest the cl-series and parenscript macros to declaratively grow my kitten to subsume Aral’s kitten-application-database tutorial at least. In particular I would like to turn what I began in lisp-game-jam into a naturally evolving over-server-hits automata resembling Lotka-Volterra predator/prey dynamics, lovingly rendered in kitten’s unicode emoji subset.
In the background, my explicit, core goal with the lispy gopher climate is to persist and spread knowledge of lisp’s oral cultural history, which is fundamentally necessary for computer programming in anything like an informed way. So I need to both upload and hand-transcribe more of the interviews and commentary I have been lucky to recieve on and for the lispy gopher climate. The transcriptions and interviews are important because they are primary sources, not secondary sources (like me). Hence if a primary source makes some mistake or misremembers something, that is at least a primary source misremembering something in contrast to my gossip-ish frequent confusion. It is a necessary backbone for the show: I am not going to stop sharing what I’m pretty-sure-I-remember-seeing, since I think my occasional mistakes are fairly easily sorted out and interpretable to see what I mixed up, on the other hand, losing lisp cultural knowledge by not talking is the worst case scenario for the world of computing.
See you on the Mastodon everyone! I do enjoy and enjoy reading spirited discussion and I hope to hear from you there as well (and your strongly worded advice on my proximal goals and theories this article laid out). I think it bears remembering sometimes that for better or for worse we are all here because we are members of the lisp community and contributing what we each can to that ((apply 'round (read) 100)
year quest so far). The fact that our language, besides fortran, is the one that is most a century spanning quest is something to remember in our vociferous community discussions.
Listen, if you are someone with some grey hair who has been involved in the lisp community decades past, (recent history as well), please come on the lispy gopher climate to informally present your particular memories and second-hand anecdotes from and of lisp’s history. If you are not comfortable live, you are also welcome to pre-record something we will play (and pause and chatter in response to) on the weekly show that will end up in our archive.
See you everyone!
screwlisp proposes kittens