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. Kent Pitman was consulted about the specification, which has at least three current and one historic implementation being McCLIM, Franz, Lispworks, and Symbolics’. 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.

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 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)
#<a CLIM-USER::FOOBAR 0x7efd62d7fa40>
CLIM-USER> (things *)
(CHARLIE THE FEATHERLESS BIPED)
CLIM-USER> (slot-boundp ** 'things)
NIL
CLIM-USER> (slot-boundp *** 'thing1)
T
Great, but I imagine that
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, 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
(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.
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-types, 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 talk was spurred by Kepeken asking what starting points I would give reasonably experienced lisp beginners, where I gave the list
with additional insistence that the common lisp interface manager 2 spec 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 implemented currently by at least
and historically (though the spec and hence book is current) by
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, which are another fundamental part of CLIM.
What do you think (on the Mastodon thread)? 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.
Kent Pitman 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.
screwlisp proposes kittens