From: Tamas K Papp on
On Wed, 13 Jan 2010 14:10:55 -0800, Thomas A. Russ wrote:

> Tamas K Papp <tkpapp(a)gmail.com> writes:
>
>> On Tue, 12 Jan 2010 09:29:25 -0800, Antony wrote:
> ...
>> > In the slot-unbound method am I allowed to set the value of the slot.
>> > It wasn't clear to me from the CLHS whether the obj is allowed to be
>> > modified.
>> > My thought was that I can use this to optimize computation of
>> > expensive slot values.
>>
>> It is a good idea. I use this macro for "lazy" calculation of
>> expensively computed slots:
>
> And we have used the SLOT-MISSING method to implement "dynamic slots" on
> classes. If a slot is missing, then it becomes a dynamic slot that is
> stored in an alist or hash-table with its value. That allows regular
> slots to be fast, and the much less common dynamic slots to be
> implemented on an as-needed basis. This was also done as a technique to
> save space for seldom used slots.

Can you please provide a link to this code? I would like to look at it.

Tamas
From: Madhu on

* Tamas K Papp <7r80e7Fl9vU1(a)mid.individual.net> :
Wrote on 14 Jan 2010 07:46:16 GMT:

| On Wed, 13 Jan 2010 14:10:55 -0800, Thomas A. Russ wrote:
|
|>> > In the slot-unbound method am I allowed to set the value of the
|>> > slot. It wasn't clear to me from the CLHS whether the obj is
|>> > allowed to be modified. My thought was that I can use this to
|>> > optimize computation of expensive slot values.
|>>
|>> It is a good idea. I use this macro for "lazy" calculation of
|>> expensively computed slots:
|>
|> And we have used the SLOT-MISSING method to implement "dynamic slots"
|> on classes. If a slot is missing, then it becomes a dynamic slot
|> that is stored in an alist or hash-table with its value. That allows
|> regular slots to be fast, and the much less common dynamic slots to
|> be implemented on an as-needed basis. This was also done as a
|> technique to save space for seldom used slots.
|
| Can you please provide a link to this code? I would like to look at it.

Here is something identical which Costanza posted a few years ago.

<http://groups.google.com/group/comp.lang.lisp/msg/5cf39dec5945cda5>

From: Pascal Costanza <pc(a)p-cos.net>
Newsgroups: comp.lang.lisp
Subject: Re: The limits of lisps synatactic gymnastics? (i sure hope not)
Date: Fri, 30 Sep 2005 21:30:52 +0200
Message-ID: <3q5i3dFdb9cfU1(a)individual.net>

--
Madhu
From: Thomas A. Russ on
Madhu <enometh(a)meer.net> writes:

> * Tamas K Papp <7r80e7Fl9vU1(a)mid.individual.net> :
> Wrote on 14 Jan 2010 07:46:16 GMT:
> |>
> |> And we have used the SLOT-MISSING method to implement "dynamic slots"
> |> on classes. If a slot is missing, then it becomes a dynamic slot
> |> that is stored in an alist or hash-table with its value. That allows
> |> regular slots to be fast, and the much less common dynamic slots to
> |> be implemented on an as-needed basis. This was also done as a
> |> technique to save space for seldom used slots.
> |
> | Can you please provide a link to this code? I would like to look at it.
>
> Here is something identical which Costanza posted a few years ago.
>
> <http://groups.google.com/group/comp.lang.lisp/msg/5cf39dec5945cda5>
>
> From: Pascal Costanza <pc(a)p-cos.net>
> Newsgroups: comp.lang.lisp
> Subject: Re: The limits of lisps synatactic gymnastics? (i sure hope not)
> Date: Fri, 30 Sep 2005 21:30:52 +0200
> Message-ID: <3q5i3dFdb9cfU1(a)individual.net>

Thanks for posting that reference.

Our dynamic slots code is embedded in a large system and not separated
into a (small) library. Pascal's code is nice and more complete than
what we had.

Also, it would be a simple exercise to produce variants using ALIST or
property lists for the storage as well. For small numbers of slots,
those might be better choices.

--
Thomas A. Russ, USC/Information Sciences Institute











From: Nicolas Neuss on
tar(a)sevak.isi.edu (Thomas A. Russ) writes:

> Thanks for posting that reference.
>
> Our dynamic slots code is embedded in a large system and not separated
> into a (small) library. Pascal's code is nice and more complete than
> what we had.
>
> Also, it would be a simple exercise to produce variants using ALIST or
> property lists for the storage as well. For small numbers of slots,
> those might be better choices.

I have the following in Femlisp:

(defclass property-mixin ()
((properties :accessor properties :initform () :initarg :properties
:type list :documentation
"A property list which is used to store unstructured information about
this object."))
(:documentation "A mixin which adds a slot of properties to the class."))

(defun get-property (object property)
"Gets @arg{property} for @arg{object}. Returns NIL also if
@arg{property} is not available."
(getf (slot-value object 'properties) property))

(defun (setf get-property) (value object property)
"Sets the property @arg{property} of @arg{problem} to @arg{value}."
(setf (getf (slot-value object 'properties) property) value))

;;; new interface using CLOS
(defmethod shared-initialize :after ((object property-mixin) slot-names
&rest initargs &key &allow-other-keys)
(declare (ignore slot-names))
(let* ((class (class-of object))
(ordinary-slot-initargs (mappend #'fl.amop:slot-definition-initargs
(fl.amop:compute-slots class))))
(loop for (key value) on initargs by #'cddr
unless (member key ordinary-slot-initargs) do
(setf (slot-value object (intern (symbol-name key) *package*))
value))))

(defmethod slot-missing (class (object property-mixin) slot-name
(operation (eql 'slot-value)) &optional new-value)
(declare (ignore class new-value))
(getf (slot-value object 'properties) slot-name))

(defmethod slot-missing (class (object property-mixin) slot-name
(operation (eql 'setf)) &optional new-value)
(declare (ignore class))
(setf (getf (slot-value object 'properties) slot-name) new-value))

(defmethod slot-missing (class (object property-mixin) slot-name
(operation (eql 'slot-boundp)) &optional new-value)
(declare (ignore class slot-name new-value))
t)

(defmethod slot-missing (class (object property-mixin) slot-name
(operation (eql 'slot-makunbound)) &optional new-value)
(declare (ignore class new-value))
(error "Property slot '~A' cannot be unbound" slot-name))
From: Nicolas Neuss on
Nicolas Neuss <lastname(a)math.uni-karlsruhe.de> writes:

> mixin introducing a property slot:
> (defclass property-mixin () ... )
>
> ;;; Interface 1
> (defun get-property (object property) ... )
> (defun (setf get-property) (value object property) ...)
>
> ;;; Interface 2 accessing properties as slots
> (defmethod shared-initialize :after ((object property-mixin) slot-names
> &rest initargs &key &allow-other-keys) ...)
> (defmethod slot-missing (class (object property-mixin) slot-name
> (operation (eql 'slot-value)) &optional new-value) ...)
> ...

Since noone did take this up, I only want to remark that I am still not
convinced that the idea of generating new slots/properties dynamically
is a good idea in general. Part of the purpose of a class is a
definiion of a clear interface which is mostly lost by this technique.
I think it depends much on your programming style if you can really
profit from that feature.

Nicolas