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
Note that SLOT-VALUE is a function, not a generic function.
(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__
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
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.
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/
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__
Yes, standard-instance-access seems interesting. Also this page:
http://www.cliki.net/MOP%20design%20patterns
Thanks!
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
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).