Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

multiple slot values in one step?

34 views
Skip to first unread message

Karol Skocik

unread,
Jan 17, 2009, 6:18:32 AM1/17/09
to
Hi,
I have following scenario - I want to get more than one slot value
of object, but pay for dispatch just once.
Is there a function in CL which allows you to dispatch once on the
object type, and then get a values of different slots?
I don't mean with-slots, since that expands (in SBCL) to symbol-
macrolets using slot-value, and every time you use the slot-name, it
expands to (slot-value ...) which pays for dispatch.

I mean something like:

(with-bound-values-from-slots ((x slot-name-x) (y slot-name-y)) object
...)

where x and y in the body of with-bound-values-from-slots are bound to
variable using multiple-value-bind for example and values of those x
and y are taken from the object in one step.

Karol

Rainer Joswig

unread,
Jan 17, 2009, 6:45:28 AM1/17/09
to
In article
<e7af11ae-888a-44eb...@y1g2000pra.googlegroups.com>,
Karol Skocik <Karol....@gmail.com> wrote:


Note that SLOT-VALUE is a function, not a generic function.

--
http://lispm.dyndns.org/

Pascal J. Bourguignon

unread,
Jan 17, 2009, 7:18:00 AM1/17/09
to
Karol Skocik <Karol....@gmail.com> writes:

(defmethod slots ((object class))
(values (slot-value object 'slot-1)
(slot-value object 'slot-2)
...
(slot-value object 'slot-n)))

(multiple-value-bind (x y ... z) (slots object)
...)

One single dispatch (but as Rainer mentionned, you can do it with zero
dispatch).

--
__Pascal Bourguignon__

Madhu

unread,
Jan 17, 2009, 7:39:46 AM1/17/09
to

* Karol Skocik Wrote on Sat, 17 Jan 2009 03:18:32 -0800 (PST):

Others have pointed out that there is nothing wrong with WITH-SLOTS and
there should be no reason to avoid it.

However if you want to avoid the SYMBOL-MACROLET in WITH-SLOTS
altogether (maybe you do not ever want to set the slot value) in the
body, you can just use

(macroexpand-1
'(with-slots ((x slot-name-x) (y slot-name-y)) object forms))

And replace the SYMBOL-MACROLET with LET in the expansion --- and use
that literally in your code.

I do have a macro which does this, but I won't post it because I think
it is abuse. [Actually I abuse it in another way: for accessing
slot-names that are in a different package without importing the symbols
or qualifying the package name explicitly]

--
Madhu

Karol Skocik

unread,
Jan 17, 2009, 8:04:33 AM1/17/09
to
On Jan 17, 1:18 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

I think I did not formed my question clearly. I was after built-in way
(directly in CL) how to avoid even slot-value. Every slot-value
function has to somehow get the layout of class first and then check
for the presence of slot specified by symbol.

What I wanted is: Get the layout first *once*, and then with that
layout check for presence of slots, finally when all slots are present
return all of them with values.


Pascal Costanza

unread,
Jan 17, 2009, 8:33:00 AM1/17/09
to

Yes, but that doesn't have to be inefficient.

See http://www.sbcl.org/manual/Slot-access.html#Slot-access for example.

Note that CLOS slots are more inefficient than structs primarily because
of the fact CLOS slots can be unbound and each and every slot access has
to check for that condition. (Some implementations allow you to declare
that you don't want this, like CMUCL.)

Also see standard-instance-access, which is part of the CLOS MOP and
which allows you to circumvent all additional checks CLOS has to perform
(and is therefore a somewhat dangerous tool that should be used wisely).


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/

Pascal J. Bourguignon

unread,
Jan 17, 2009, 9:52:56 AM1/17/09
to
Karol Skocik <Karol....@gmail.com> writes:

With CLOS, you cannot avoid SLOT-VALUE:

(defun f (o)
(change-class o 'some-other-class))

(with-slots (x y z) o
(setf x (do-something x y z))
(f o)
(setf x (do-something x y z)))


In CL implementations with threads, it's even worse:

(with-slots (x y z) o
(setf x (do-something x y z))
;; Here another thread may change the class of o.
(setf x (do-something x y z)))


If you want to avoid SLOT-VALUE, you must use another object system.

You could try first DEFSTRUCT. Here, redefining a structure class has
undefined effects, so you don't do that in conformant code.

Otherwise, just write your own object system or use a library OO
system (eg. KR, but I don't think you'll like it).

--
__Pascal Bourguignon__

Karol Skocik

unread,
Jan 17, 2009, 10:45:28 AM1/17/09
to
> Seehttp://www.sbcl.org/manual/Slot-access.html#Slot-accessfor example.

>
> Note that CLOS slots are more inefficient than structs primarily because
> of the fact CLOS slots can be unbound and each and every slot access has
> to check for that condition. (Some implementations allow you to declare
> that you don't want this, like CMUCL.)
>
> Also see standard-instance-access, which is part of the CLOS MOP and
> which allows you to circumvent all additional checks CLOS has to perform
> (and is therefore a somewhat dangerous tool that should be used wisely).
>
> Pascal
>
> --
> My website:http://p-cos.net
> Common Lisp Document Repository:http://cdr.eurolisp.org
> Closer to MOP & ContextL:http://common-lisp.net/project/closer/

Yes, standard-instance-access seems interesting. Also this page:
http://www.cliki.net/MOP%20design%20patterns

Thanks!

Jochen Schmidt

unread,
Jan 17, 2009, 2:10:28 PM1/17/09
to


You could use WITH-ACCESSORS - it uses the generated accessor
functions of your CLOS classes. In some implementations of CLOS an
accessor doesn't have to go through SLOT-VALUE-USING-CLASS; accessors
would then be faster than using SLOT-VALUE with a symbol. SLOT-VALUE
itself could also get optimized quite well for constant slot-name
parameters. Actually your problem doesn't actually is object accesses
but really creating bindings to values based on a snapshot of the
objects state at that time. There is nothing like this in standard
common lisp - but isn't that quite trivial?

(defmacro with-bound-values-from-slots (bindings object &body forms)
`(with-slots ,bindings object
(let ,(loop for (b _) in bindings collect (list b b)) ,@forms)))

ciao,
Jochen

--
Jochen Schmidt
CRISPYLOGICS
Uhlandstr. 9, 90408 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828
16438) http://www.crispylogics.com

Jochen Schmidt

unread,
Jan 17, 2009, 2:14:49 PM1/17/09
to
On 17 Jan., 20:10, Jochen Schmidt <j...@crispylogics.com> wrote:
>
> (defmacro with-bound-values-from-slots (bindings object &body forms)
>   `(with-slots ,bindings object
>      (let ,(loop for (b _) in bindings collect (list b b)) ,@forms)))

Should be

(defmacro with-bound-values-from-slots (bindings object &body forms)

`(with-slots ,bindings ,object


(let ,(loop for (b _) in bindings collect (list b b)) ,@forms)))

of course (note the comma before object).

0 new messages