From: Förster vom Silberwald
Subject: accessing slots in Common Lisp
Date: 
Message-ID: <1128768024.758875.55610@g44g2000cwa.googlegroups.com>
Hi:

A small question. In Bigloo (Scheme) I often use the following (bad?)
programming structure in my programs. I have  a class lets say:

==
(class PostModels
      (post-models::pair-nil  (default (list)))
      (aod-hum::pair-nil (default (list)))
      (w-hum::pair-nil (default (list)))
      (post-hum::pair-nil (default (list)))
      (L-thres::pair (default (list '(0.5 0.5 0.5 0.5))))
      (new-type-5-hum::pair (default (list))))))
==

After upon processing my program the class becomes filled up with slot
vales. Afterwards it often happens that I would like accessing slots
(e.g. making the mean from the values). The function which makes the
mean is always the same. In the Bigloo there is no default option for
accessing names. For example:

==
(define (make-mean::double postmodels::PostModels slot-name::object)
  (...))
==

And then I would like to call it as follows (because aod-hum and
new-type-5-hum share the same structure, e.g. a vector with values):

==
(make-mean PostModels 'aod-hum)

or

(make-mean PostModels 'new-type-5-hum)
==

I would have to write a macro (so it was told and given examples to me
on the Bigloo list some months ago), otherwise I would have to "hard
code" the slot-name into my (make-mean) function.

Would it be possible in CommonLisp to access slots simply by their
name?

The aforementioned shortcomming (if there are any) often hit me when
using Bigloo; I am not the best programmer and writing macros is as
climbing a hill with the bycicle for an improper trained person (okay,
in real life I am a very good bycicle/hill climber even after 5 hours
on a mountainbike).

Thanks,
Schneewittchen

From: Russell McManus
Subject: Re: accessing slots in Common Lisp
Date: 
Message-ID: <87hdbs2pk9.fsf@cl-user.org>
"F�rster vom Silberwald" <··········@hotmail.com> writes:

> Would it be possible in CommonLisp to access slots simply by their
> name?

WITH-SLOTS is pretty cool for this kind of stuff:

(defclass point ()
  ((x :initarg :x) (y :initarg :y)))

(defmethod slope ((point1 point) (point2 point))
  (with-slots ((x1 x) (y1 y)) point1
    (with-slots ((x2 x) (y2 y)) point2
      (/ (- y2 y1) (- x2 x1)))))

(slope 
 (make-instance 'point :x 1.2 :y 2.0)
 (make-instance 'point :x 3.1 :y 4.7))

 -> 1.4210527

-russ
From: Pascal Costanza
Subject: Re: accessing slots in Common Lisp
Date: 
Message-ID: <3qpo19Fg9njvU1@individual.net>
F�rster vom Silberwald wrote:

> Would it be possible in CommonLisp to access slots simply by their
> name?

slot-value is your friend.

? (defclass person ()
     ((name :initarg :name)
      (address :initarg :address)))
#<STANDARD-CLASS PERSON>
? (defparameter *pascal*
     (make-instance 'person :name "Pascal" :address "Brussels"))
*PASCAL*
? (slot-value *pascal* 'name)
"Pascal"
? (loop for slot in '(name address)
         do (print (slot-value *pascal* slot)))

"Pascal"
"Brussels"
NIL
? (loop for slot in (class-slots (class-of *pascal*))
         do (print (slot-value *pascal* (slot-definition-name slot))))

"Pascal"
"Brussels"
NIL



Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Rainer Joswig
Subject: Re: accessing slots in Common Lisp
Date: 
Message-ID: <BF6D79F5.1A0AB%joswig@lisp.de>
Am 08.10.2005 12:40 Uhr schrieb "F�rster vom Silberwald" unter
<··········@hotmail.com> in
·······················@g44g2000cwa.googlegroups.com:

> Hi:
> 
> A small question. In Bigloo (Scheme) I often use the following (bad?)
> programming structure in my programs. I have  a class lets say:
> 
> ==
> (class PostModels
>       (post-models::pair-nil  (default (list)))
>       (aod-hum::pair-nil (default (list)))
>       (w-hum::pair-nil (default (list)))
>       (post-hum::pair-nil (default (list)))
>       (L-thres::pair (default (list '(0.5 0.5 0.5 0.5))))
>       (new-type-5-hum::pair (default (list))))))
> ==
> 
> After upon processing my program the class becomes filled up with slot
> vales. Afterwards it often happens that I would like accessing slots
> (e.g. making the mean from the values). The function which makes the
> mean is always the same. In the Bigloo there is no default option for
> accessing names. For example:
> 
> ==
> (define (make-mean::double postmodels::PostModels slot-name::object)
>   (...))
> ==
> 
> And then I would like to call it as follows (because aod-hum and
> new-type-5-hum share the same structure, e.g. a vector with values):
> 
> ==
> (make-mean PostModels 'aod-hum)
> 
> or
> 
> (make-mean PostModels 'new-type-5-hum)
> ==
> 
> I would have to write a macro (so it was told and given examples to me
> on the Bigloo list some months ago), otherwise I would have to "hard
> code" the slot-name into my (make-mean) function.
> 
> Would it be possible in CommonLisp to access slots simply by their
> name?

Common Lisp has a function called SLOT-VALUE:

"The function slot-value returns the value of the slot named slot-name in
the object. If there is no slot named slot-name, slot-missing is called. If
the slot is unbound, slot-unbound is called."

CL-USER 15 > (defclass foo () ((a :initform 'a-value) (b :initform
'b-value)))
#<STANDARD-CLASS FOO 10089463>

CL-USER 16 > (make-instance 'foo)
#<FOO 100D12F3>

CL-USER 17 > (slot-value * 'b)
B-VALUE

> 
> The aforementioned shortcomming (if there are any) often hit me when
> using Bigloo; I am not the best programmer and writing macros is as
> climbing a hill with the bycicle for an improper trained person (okay,
> in real life I am a very good bycicle/hill climber even after 5 hours
> on a mountainbike).
> 
> Thanks,
> Schneewittchen
> 
From: Marco Antoniotti
Subject: Re: accessing slots in Common Lisp
Date: 
Message-ID: <PPu2f.25$pa3.12423@typhoon.nyu.edu>
F�rster vom Silberwald wrote:
> Hi:
> 
> A small question. In Bigloo (Scheme) I often use the following (bad?)
> programming structure in my programs. I have  a class lets say:
> 
> ==
> (class PostModels
>       (post-models::pair-nil  (default (list)))
>       (aod-hum::pair-nil (default (list)))
>       (w-hum::pair-nil (default (list)))
>       (post-hum::pair-nil (default (list)))
>       (L-thres::pair (default (list '(0.5 0.5 0.5 0.5))))
>       (new-type-5-hum::pair (default (list))))))
> ==

(defclass post-models ()
    ((post-models :type pair-nil
                  :initarg :post-models
                  :accessor post-models)
     (aod-hum :type pair-nil
              :initarg :aod-hum
              :accessor aod-hum)
     (w-hum :type pair-nil
            :initarg :w-hum
            :accessor w-hum)
     (post-hum :type pair-nil
               :initarg :post-hum
               :accessor post-hum)
     (l-thres :type pair
              :initform (list (make-list 4 :initial-element 0.5))
              :accessor l-thres)
     (new-type-5-hum :type pair
                     :initarg :new-type-5-hum
                     :accessor new-type-5-hum)
     )
    (:default-initargs :post-nodels ()
                       :aod-hum ()
                       :w-hum ()
                       :post-hum ()
                       :new-type-5-hum ())
   )

More verbose but also more informative *and* *standard*!

> After upon processing my program the class becomes filled up with slot
> vales. Afterwards it often happens that I would like accessing slots
> (e.g. making the mean from the values). The function which makes the
> mean is always the same. In the Bigloo there is no default option for
> accessing names. For example:
> 
> ==
> (define (make-mean::double postmodels::PostModels slot-name::object)
>   (...))
> ==

What is the semantics of your function?  Are you assuming to have access 
to all instances of the PostModels class in the variable 
postmodels::PostModels?


> And then I would like to call it as follows (because aod-hum and
> new-type-5-hum share the same structure, e.g. a vector with values):
> 
> ==
> (make-mean PostModels 'aod-hum)
> 
> or
> 
> (make-mean PostModels 'new-type-5-hum)
> ==
> 
> I would have to write a macro (so it was told and given examples to me
> on the Bigloo list some months ago), otherwise I would have to "hard
> code" the slot-name into my (make-mean) function.
> 
> Would it be possible in CommonLisp to access slots simply by their
> name?

Accessors in CL have method nature.  Therefore a way to access slots by 
name is needed.  CL has SLOT-VALUE (a function) for these purposes and 
WITH-SLOTS (also WITH-ACCESSORS) for doing this sort of things.

Assuming you have a list of all the POST-MODELS instances, in CL you can 
get the mean in several ways, using both the slot "name" or its accessor.

(defmethod make-mean ((post-models list) (slot-specifier symbol))
   (/ (reduce '+ post-models
              :key (lambda (pm) (slot-value pm slot-specifier)))
      (list-length post-models)))

(defmethod make-mean ((post-models list) (slot-specifier function))
   (/ (reduce '+ post-models
              :key slot-specifier)
      (list-length post-models)))

Now, suppose you also have

(defmethod aod-hum :before ((pm post-models))
    (format t "Accessing slot AOD-HUM in ~S, current value ~S."
            pm
            (slot-value pm 'aod-hum)))

Can you see why you actually need both forms?

Finally.  What are you waiting for to take the leap? :)


Cheers
--
Marco