screwlisp proposes kittens

Screwlisps-knowledge Common lisp interface manager spec Cons Tree Graphics

(We eventually just get the above visualisations working as easy as pasting or typing whatever trees as nested lists. It is available as a common lisp asdf package inside my screwlisps-knowledge system git repository) (My example is intentionally similar to Lispworks’ one here).

Using jackdaniel’s McCLIM implementation of the CLIM 2 spec. A foundational principle of lisp was that the code of lisp, s-expressions, be a sequence type used by the programming language. Of lisp’s sequences, (lists were chosen instead of #(vectors for example)). While it is (unambiguous and much cleaner to write a list like this), the list’s truest form is as nested cons pairs (like . (this . ((for . (one . nil)) . (example . nil)))). The terminating dot-nils make lists true-lists. Doug Merritt says it is basically a regret that non-true-lists are allowed, e.g. (a . b) though this useage remains popular basically when we want to use conses as pairs per se instead of as building blocks for true lists.

For these kinds of reasons, the common lisp interface manager spec actually includes visualizing these cons trees fairly directly.

Setup

I am assuming you are using sbcl, McCLIM, eev and emacs [] or understand your differences thereto.

My common lisp asdf package is going ]in my screwlisps-knowledge repo](https://codeberg.org/tfw/screwlisps-knowledge).

 (eepitch-shell)
mkdir -p ~/common-lisp/
cd ~/common-lisp
git clone https://codeberg.org/tfw/screwlisps-knowledge.git
cd
#|
 (eepitch-sbcl)
|#
(asdf:load-system :mcclim)

Source of #p"screwlisps-knowledge/cons-grapher.lisp"

Define and go into the package

(uiop:define-package :screwlisps-knowledge/cons-grapher
    (:mix :series :clim :clim-lisp :cl)
  (:export #:graph-frame
	   #:graph
	   #:define-graph-frame-command
	   #:visualize))

(in-package :screwlisps-knowledge/cons-grapher)

Define the frame

(define-application-frame graph-frame
    ()
  ((graph :initarg :graph
	  :accessor graph))
  (:pane :application
   :display-function 'display-graph
   :incremental-redisplay t)
  (:default-initargs :graph '((this (could) (be)) (your (graph) (this)))))

The display function for our application frame.

(defmethod display-graph ((f graph-frame) p)
  (updating-output (p)
    (format-graph-from-roots
     (graph f)
     #'(lambda (x s) (princ (car x) s))
     #'cdr
     :orientation :vertical
     :merge-duplicates t
     :duplicate-key #'car)))

Commands for setting and querying the user for cons trees

The default update behaviour is to update the application-frame graphics when a command happens, so we should use commands.

(define-graph-frame-command (com-set-graph :menu nil :name t)
    ((expression expression))
  (setf (graph *application-frame*) expression))

(define-graph-frame-command (com-graph :menu t :name t)
    ()
  (let ((frame *application-frame*))
    (accepting-values ()
      (let ((expressions
	      (accept '(sequence expression))))
	(print expressions *terminal-io*)
	(execute-frame-command frame `(com-set-graph ,(car expressions)))))))

A function that just pops a frame up showing a cons tree

(defun visualize
    (&rest cons-tree)
  (let ((grapher (make-application-frame 'graph-frame)))
    (when cons-tree
      (execute-frame-command grapher
			     `(com-set-graph ,cons-tree)))
    (run-frame-top-level grapher)))

Useage

(asdf:load-system :mcclim)
(in-package :clim-user)
(asdf:load-system :screwlisps-knowledge/cons-grapher)
(use-package :screwlisps-knowledge/cons-grapher)

(remember, autocomplete in common lisp emacs with slime is M-/)

Headless - visualize

(visualize '(a (b) (c)) '(d (e (c))))

Interactively writing in new cons trees

Directly making the frame

If we want access to the application frame being used, for example to open and close the same one at different times, we can directly make-application-frame it.

(make-application-frame 'graph-frame :graph '((a (b (c))) (x (y (z) (c)))))

Conclusion

A small amount of window dressing around the CLIM 2 spec’s format-graph-from-roots so we just re/write in cons trees and get graphs of them. I get a lot of mileage out of it. Three uses I have planned are

  1. Working with Kitten html components as structural types
  2. Cross referenced editor facility style tagging of these blog articles
  3. Intent-based tours of these blog articles.

I think these are better represented as cons tree graphs of atoms than structs or classes because html elements are basically structural - they are their element name appearing in their html, along with a a property list, which symbol atoms already have. All html elements more or less always can have children which are a sequence of strings and more html trees. Encoding what html happens to have been defined like is not my intent here; however, it seems coincident with these cons trees, and this is a way of easily looking with those. I note that you can paste into that application-frame’s accepting-values easily.

I note that my accepting-values clearly should instead be (accepting-values (t :own-window t) <body>) because McCLIM makes odd compromises to squeeze it onto that one frame sometimes.

Fin

See you on the thread for this article on the Mastodon.

This classic lisp tree visualization useage has been part of lisp useage for a long time. To lose it decontextualises lisp in a harmful [sic] way. Common lisp interface manager was the heir to Lisp machine dynamic-windows (pers. coms.). Cons tree graphs loosely in this style go back much, much further into lisp’s approximately hundred year history. In particular, modernly, McCLIM was started by Robert Strandh in 1996 and then joyfully offloaded, eventually to jackdaniel.

For this kind of reason, please do share this bit to newcomers to the lisp community so they are not confused into thinking using graphs in program and data structure design and exploration was invented by low quality fly-by-night in-and-out financial ventures. You have my blessing to share it whereever and however occurs to you.

OR BETTER if you have something to say, say it on the Mastodon, come on an episode of the lispy gopher climate like Vassil and Kent do.

screwlisp proposes kittens