Subject: [clisp-list] CLOS: class-wide slots defined at compile-time?

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Feb 19 05:12:15 2003

Hi,

I'm seeking help with CLOS. I want to define a slot that all instances of a class will share. This sounds like typical :allocation :class. But read on.

One of these special slots is supposed to contain a function (closure) that I want compiled at file-compilation time. Another will be set at run-time. Another will contain the lambda expression to compile at run-time and ought to be defined at file-compilation time as well.

I thought about the following macro to declare the code:
(define-analyse-line ((analyse durchsatz))
  (incf (gethash key (analyse-top-table analyse)))
  (princ #\; (analyse-outstream analyse)))

which would macroexpand to:

(let ((*columns-used* '()))
 (setf (analyse-line-function (find-class 'durchsatz))
  (lambda (analyse .line. .start-positions. .stop-positions.)
    (macrolet ((log-line-universal-time () ;TODO? flet
		 (or (analyse-universal-time analyse) #))
	       (log-line-sql-time ()
		 (format nil #)))
      body...))
  (setf (analyse-used-columns #) *columns-used*)))

and here's something which cannot work
(defmacro define-analyse-line ((var class) &body body)
  (let* ((*precompile* nil)
	  (*columns-used* '()))
    (setf (analyse-line-function (find-class ',class))
       (lambda (,var .line. .start-positions. .stop-positions.)
	   ,@body))
    (setf (analyse-line-lambda (find-class ',class)) ',body)
    (setf (analyse-used-columns (find-class ',class)) *columns-used*)))

The reason it cannot work is that analyse-line-lambda and -line-function are not typically slots of (find-class 'analyse), but rather shared slots of each instance.

Need I got MOP here or is that overshoot? Am I misguided?

Maybe all I need is a wrapper around defclass and some initform instead?
This could become weird as well, since the closure body may reference slots to be defined in this same DEFCLASS form (e.g. analyse-top-table above).

Thanks for your help,
	Jörg Höhle.

---

From: Sam Steingold <[email-masked]>
Date: Wed Feb 19 10:12:02 2003

> * In message <[email-masked]>
> * On the subject of "[clisp-list] CLOS: class-wide slots defined at compile-time?"
> * Sent on Wed, 19 Feb 2003 14:09:06 +0100
> * Honorable "Hoehle, Joerg-Cyril" <[email-masked]> writes:
>
> I'm seeking help with CLOS. I want to define a slot that all instances
> of a class will share. This sounds like typical :allocation
> :class.

IIUC, you need what MOP calls a "class prototype".
I.e.,
(defclass foo ()
  (bar :allocation :class))

(setf (slot-value (class-prototype (find-class 'foo)) 'bar)
      (lambda () ...))

right?

(defun shared-slot (class slot)
  (let ((slot-location (gethash slot (clos::class-slot-location-table class))))
    (cond ((null slot-location) (error "no such slot"))
          ((atom slot-location) (error "slot is local"))
          (t (svref (clos::class-shared-slots (car slot-location))
                    (cdr slot-location))))))

(defun (setf shared-slot) (value class slot)
  (let ((slot-location (gethash slot (clos::class-slot-location-table class))))
    (cond ((null slot-location) (error "no such slot"))
          ((atom slot-location) (error "slot is local"))
          (t (setf (svref (clos::class-shared-slots (car slot-location))
                          (cdr slot-location))
                   value)))))

(setf (shared-slot (find-class 'foo) 'bar) (lambda () ...))

Does this solve your problem?

Should we export CLOS:SHARED-SLOT, CLOS:SHARED-SLOT-BOUNDP and
CLOS:SHARED-SLOT-MAKUNBOUND?
An alternative would be to add a class prototype (which would waste an
instance for each class...)

I don't thing we may extend SLOT-VALUE and friends like this:
(SLOT-VALUE symbol slot) == (SHARED-SLOT (find-class symbol) slot)

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
Life is a sexually transmitted disease with 100% mortality.