From: Karol Skocik
Subject: multiple slot values in one step?
Date: 
Message-ID: <e7af11ae-888a-44eb-ae8f-06b2048004a3@y1g2000pra.googlegroups.com>
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

From: Jochen Schmidt
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <809687cf-7feb-43e9-81c9-fa95cdbff9e6@t39g2000prh.googlegroups.com>
On 17 Jan., 12:18, Karol Skocik <············@gmail.com> wrote:
> 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


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~)" 870180 1680085828711918828
16438) http://www.crispylogics.com
From: Jochen Schmidt
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <d73e65b9-3424-4ca3-8a7b-1e69cc1165f0@e1g2000pra.googlegroups.com>
On 17 Jan., 20:10, Jochen Schmidt <····@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).

--
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~)" 870180 1680085828711918828
16438)http://www.crispylogics.com
From: Rainer Joswig
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <joswig-DCA3E6.12452817012009@news-europe.giganews.com>
In article 
<····································@y1g2000pra.googlegroups.com>,
 Karol Skocik <············@gmail.com> wrote:

> 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


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

-- 
http://lispm.dyndns.org/
From: Pascal J. Bourguignon
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <87wscuunwn.fsf@galatea.local>
Karol Skocik <············@gmail.com> writes:

> 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.

(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__
From: Karol Skocik
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <67b4ae88-657c-4ca3-9a67-92b594c80eeb@x16g2000prn.googlegroups.com>
On Jan 17, 1:18 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Karol Skocik <············@gmail.com> writes:
> > 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.
>
> (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__

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.
From: Pascal Costanza
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <6te50dFaep7eU1@mid.individual.net>
Karol Skocik wrote:
> On Jan 17, 1:18 pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Karol Skocik <············@gmail.com> writes:
>>> 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.
>> (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__
> 
> 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.

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/
From: Karol Skocik
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <f1b37f28-ee6a-4956-bd23-c19abfd38d10@g3g2000pre.googlegroups.com>
On Jan 17, 2:33 pm, Pascal Costanza <····@p-cos.net> wrote:
> Karol Skocik wrote:
> > On Jan 17, 1:18 pm, ····@informatimago.com (Pascal J. Bourguignon)
> > wrote:
> >> Karol Skocik <············@gmail.com> writes:
> >>> 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.
> >> (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__
>
> > 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.
>
> Yes, but that doesn't have to be inefficient.
>
> 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!
From: Pascal J. Bourguignon
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <87skniugqf.fsf@galatea.local>
Karol Skocik <············@gmail.com> writes:

> On Jan 17, 1:18�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Karol Skocik <············@gmail.com> writes:
>> > 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.
>>
>> (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__
>
> 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.

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__
From: Madhu
Subject: Re: multiple slot values in one step?
Date: 
Message-ID: <m3iqoew1gt.fsf@moon.robolove.meer.net>
* Karol Skocik Wrote on Sat, 17 Jan 2009 03:18:32 -0800 (PST):

| 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.
|

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