--- layout: ../Site.layout.js --- # Basic Principle of the Common Lisp Interface Manager 2 spec Decades of programming-language-and-interface-interface experience and research prior to *ANSI common lisp* (1994) were consolidated into [the Common Lisp Interface Manager 2 spec](http://bauhh.dyndns.org:8000/clim-spec/index.html). [Kent Pitman](https://netsettlement.blogspot.com/) was consulted about the specification, which has at least three current and one historic implementation being [McCLIM](https://mcclim.common-lisp.dev/), [Franz](https://franz.com/support/documentation/contents.html#clim-ug), [Lispworks](https://www.lispworks.com/documentation/lw80/clim/clim.htm), and [Symbolics'](http://lispm.de/docs/Publications/UI/1994%20Symbolics%20CLIM%202.0.pdf). This is a specification a cross section of industry players implement (Strandh, jd et al.'s McCLIM is libre) rather than an additional standard that basically provides rich interface "`stream`"s rather than the standardized character streams. It is wrong to think that for decades, the lisp community had only been using simple character streams: This was simply the standardizable commonality. Let us get minimally into what the CLIM II spec is like. ## A Common Lisp Object System Object Let us write a just barely nontrivial and conceivably useful couple lisp classes. (Starting in the `clim-user` package though, and getting `mcclim` via [quicklisp.org](https://quicklisp.org) since we want our class objects in it later). ``` (ql:quickload :mcclim) (in-package :clim-user) (defclass foo () ((thing1 :initarg :thing1)) (:default-initargs :thing1 '(charlie the)) (:documentation "(apply 'make-instance 'foo (:thing1 '(charlie the))) provides thing1.")) (defclass bar () ((thing2 :initarg :thing2)) (:default-initargs :thing2 '(featherless biped)) (:documentation "(apply 'make-instance 'bar (:thing2 '(featherless biped))) provides thing2.")) (defclass foobar (foo bar) ((things :reader things)) (:documentation "(make-instance 'foobar) provides a reader THINGS that appends thing1 and thing2 available only when THINGS is used.")) (defmethod things :before ((obj foobar)) (with-slots (thing1 thing2) obj (setf (slot-value obj 'things) (append thing1 thing2)))) (defmethod things :after ((obj foobar)) (with-slots (thing1 thing2) obj (slot-makunbound obj 'things))) ``` Let us see that in action briefly: ``` CLIM-USER> (make-instance 'foobar) # CLIM-USER> (things *) (CHARLIE THE FEATHERLESS BIPED) CLIM-USER> (slot-boundp ** 'things) NIL CLIM-USER> (slot-boundp *** 'thing1) T ``` Great, but I imagine that # We want a richer lisp interface and this is where the common lisp interface manager comes in. The spec uses lisp's metaobject protocol to make a certain CLOS object class, `standard-application-frame` naturally GUI with minimal intervention by the `clim-user`. Minimal, not none. ``` (define-application-frame foobar-frame (foobar standard-application-frame) () (:pane :application :display-function (lambda (frame pane) ;;(in-package :clim-user) (present (things frame) 'expression) (terpri) (present (things frame) '(sequence string)) (terpri) (surrounding-output-with-border () (formatting-table (t ) (surrounding-output-with-border () (formatting-row () (dolist (thing (things frame)) (surrounding-output-with-border () (present thing 'string))))))))) (:documentation "foobar-frame presents its things several different ways")) (find-application-frame 'foobar-frame) ``` When I asked [Strandh](http://metamodular.com/), he said the really key thing about the common lisp interface manager was that presentations are a very fundamental idea in computer science. Naievely, we might think of data like `(things frame)`, but a `presentation` combines a data, the `presentation-type` used for that data in this particular case, and the particular `view` of that data as that `presentation-type`. Conceivably I could # Add a presentation type ``` (define-presentation-type foobar ()) (define-presentation-method present (obj (type foobar) stream view &key &allow-other-keys) (present (things obj) 'expression)) (define-application-frame foobar-frame (foobar standard-application-frame) () (:pane :application :display-function 'presents-itself) (:documentation "foobar-frame presents its things several different ways")) (defun presents-itself (frame pane) (present (things frame) 'expression) (terpri) (surrounding-output-with-border () (present frame 'foobar))) (find-application-frame 'foobar-frame) ``` note that *redeclaring* `define-application-frame` experimentally is normal: it plays nicely with `reinitialize-instance` for example. In this case it is a bit obtuse that we have said that the `application-frame` itself *is the data* and presented it as its parent's `presentation-type` which is a bit weird. # Conclusions I left everything as plain and default as possible while minimally showing the common lisp interface manager 2 spec's `presentation` concept where data is attached to a `presentation-type` for that data and a `view` of that data under that `presentation-type`, where Strandh emphasized to me that presentations are an especially fundamental concept. All those empty `()`s peppered in the macros are places for configuring and styling the presentations: I guess a stylist would use those and the other options macros extensively instead of leaving them as whatever their defaults were. We saw that common lisp object system classes could be defined and worked on as normal, then the class could have a child with `standard-application-frame`, and this child basically is naturally a general user interface, and its contents presented in a variety of `presentation-type`s, some of which were naturally sensitive as ways of providing interactions with its data. In my opinion, lots of GUI tools are about making a way of interfacing rather than managing an interface. Common Lisp Interface Manager is instead about interfacing with common lisp objects, rather than inventing a way of interfacing with common lisp objects which is a different, natural and better normal useage based on my personal experiences. We start with the correct assumption that we are interested in presentations of common lisp objects. This article that has been written while further procrastinating recording my [emacsconf](https://emacsconf.org) talk was spurred by [Kepeken](https://mastodon.gamedev.place/@kepeken) [asking what starting points I would give reasonably experienced lisp beginners](https://gamerplus.org/@screwlisp/115556468426286494), where I gave the list - [*The art of the metaobject protocol*](https://ldbeth.sdf.org/The_Art_of_the_Metaobject_Protocol.pdf) by Kiczalez, [mothman](https://ottawa.moths.ca/) and Bobrow (*about* implementing ANSI common lisp's object system) - McCarthy's [*Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I*](https://www-formal.stanford.edu/jmc/recursive.pdf) 1960 for a clear and specific original definition of lisp and its goals (what would *you* say lisp is meant to be good at?) - Norvig and Pitman's [Tutorial on Good Lisp Style](https://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf) - Since modern ANSI CL implementations purport to conform to the 1994 standard, you have more than 30 years of great books which are actively current, unlike programming languages that keep regressing to 0 years old with a standard update every year or so (if they even have a standard). with additional insistence that the [*common lisp interface manager 2 spec*](http://bauhh.dyndns.org:8000/clim-spec/index.html) **must** be included because it includes decades of interface design experiment, experience, application and research not included in the ANSI CL standard but with a specification done under mentorship of [Pitman](https://www.nhplace.com/kent/) implemented currently by at least - [McCLIM](https://codeberg.org/McCLIM/McCLIM) - [Franz](https://franz.com/support/documentation/contents.html#clim-ug) - [Lispworks](https://www.lispworks.com/documentation/lw80/clim/clim-ch17-1.htm#CLIM) and historically (though the spec and hence book is current) by - [Symbolics](http://lispm.de/docs/Publications/UI/1994%20Symbolics%20CLIM%202.0.pdf) since beginners might wrongly assume the lisp community only ever used the minimal character streams in the standard as such, rather than as the basis for advanced, rich streams basically since the 60s. PS. I guess this article did not touch [commands](https://www.lispworks.com/documentation/lw80/clim/clim-ch11-9.htm#CLIM), which are another fundamental part of CLIM. # Fin. What [do you think (on the Mastodon thread)](https://gamerplus.org/@screwlisp/115557494483653266)? In particular I want to know if you agree that the common lisp interface manager and presentations are both a different and good approach to interfacing. # Important [Kent Pitman](https://nhplace.com/kent/publications.html) is planning to be on the Sunday-morning-in-Europe peertube live 4 hours from me writing this (9am CET) https://toobnix.org/w/gXLXQqxf5MYg1NDF2Ua6oA and is looking forward to giving an example with (historic!) visuals. So you might like to set your alarms. There will of course be the archive.