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

git@codeberg.org: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.