As I mentioned on my show, while clim2 feels like there could be a
more explanatory tutorial, attempts to create one pretty much converge
to the superapp example.

Anyway, in my one I focus on separating my class/es from the McCLIM
clim2 implementation classes. I'll reproduce what I did in the post,
though canonically it's at

[email protected]:j9000/lispusers -> tfw/high/stringlist.lisp

Define this package:
```
(uiop:define-package :lispusers/tfw/high/stringlist
(:mix :clim :clim-lisp :cl)
(:export #:app-main))

(in-package :lispusers/tfw/high/stringlist)
```

Then I wanted to try the default redisplay - which redraws the entire
application but only when a new command has been run ( :command-loop )
with both a string and a list data structure, so I deffed these
similar classes:

```
(defclass textholder ()
((my-string :initform "foo" :type 'string
  :accessor my-string)))

(defclass textsholder ()
((my-strings :initform '("foo") :type 'list
  :accessor my-strings)))
```

Now, I found if clim's #'define-application-frame gets told a
superclass, it doesn't attempt to provide the clim classes, so there
needs to be an ancestral default clim application frame.

``` (define-application-frame app () ()) ```

Hence I can combine my data-carrying class definition/s with the
ancestral app clim default application. Since this definition defines
the displayed app, all the app panes and layout stuff has to be
together here.

```
(define-application-frame textap (app textsholder) ()
(:pointer-documentation t)
(:panes
 (app :application :height 128 :width 300
  :display-function 'display-app)
 (int :interactor :height 128 :width 300))
(:layouts (default (vertically () app int))))
```
Now, the superapp example uses something like this function I removed:
```
#|
(defun display-app (frame pane)
(let ((strings (my-strings frame)))
 (format pane "~@{~a~%~}~%" string)))
|#
```
Instead, since I
wanted to change between my pure clos data classes
```
(defmethod display-app ((frame textholder) (pane stream))
(let ((string (my-string frame)))
 (format pane "~@{~a~%~}~%" string)))

(defmethod display-app ((frame textsholder) (pane stream))
(let ((strings (my-strings frame)))
 (format pane "~{~a~%~}~%" strings)))
```
Now, the running and operated upon application is bound to the
special scope *application-frame*, at least from the command's
perspective. So quitting is
```
(define-textap-command (com-quit :name t) ()
(frame-exit "application-frame"))
```
But since
*application-frame* isn't an arguement, I had to use typecase here:
```
(define-textap-command (com-addtext :name t) ((string 'string))
(typecase *application-frame*
 (textsholder (push string (my-strings *application-frame*)))
 (textholder (setf (my-string *application-frame*) string))))
```
and a utility function for
running one of this:
```
(defun app-main ()
(run-frame-top-level
 (make-application-frame 'textap)))
```
See the screenshot phosted next to this.

Hope it helps someone, phosted responses and corrections welCOMed.