From: Tian
Subject: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <5bf95303.0207080335.30c69278@posting.google.com>
I am a beginner of common lisp and I have met a problem about CLOS.

In a class with a certain amount of instance, eg.:

(defclass books () (author :accessor author
                           :initarg author
                           :initform
                    year   :accessor year
                           :initarg
                           :initform))

(make-instance 'books :author "peter"
                       :year 2002)

(make-instance 'books :author "John"
                       :year 2001)

Given one of the slot value eg. "peter", how can I get the value of
other slots in a same instance?

Could anyone kindly show me a method or give an simple example?

From: Fred Gilham
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <u7hejaryul.fsf@snapdragon.csl.sri.com>
··········@hotmail.com (Tian) writes:
> (defclass books () (author :accessor author
>                            :initarg author
>                            :initform
>                     year   :accessor year
>                            :initarg
>                            :initform))
> 
> (make-instance 'books :author "peter"
>                        :year 2002)
> 
> (make-instance 'books :author "John"
>                        :year 2001)
> 
> Given one of the slot value eg. "peter", how can I get the value of
> other slots in a same instance?
> 
> Could anyone kindly show me a method or give an simple example?


Perhaps you want something like the following?

(defvar *books* nil)

(defclass books ()
  ((author :accessor author
           :initarg :author)

   (year   :accessor year
           :initarg :year)))


(push (make-instance 'books :author "peter" :year 2000) *books*)

(push (make-instance 'books :author "John" :year 2001) *books*)

(dolist (book *books*)
  (with-slots (author year) book
    (when (string= author "peter")
       (format t "~&Book by ~A written in ~A~%" author year))))



I strongly suggest you use some reference to get the syntax of
defclass right.  This will make your life much easier.

-- 
Fred Gilham                                   ······@csl.sri.com
I think it's pretty obvious that the worship of that false idol known
as the State has, in the 20th Century, had some very bad effects. The
historians I'm familiar with have settled on the number of dead as 177
million, although I've seen estimates of up to 200 million.
                                                          -Bob Wallace
From: Christopher C. Stacy
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <u1yaeuvbs.fsf@grant.org>
>>>>> On 8 Jul 2002 04:35:02 -0700, Tian  ("Tian") writes:

 Tian> I am a beginner of common lisp and I have met a problem about CLOS.
 Tian> In a class with a certain amount of instance, eg.:

 Tian> (defclass books () (author :accessor author
 Tian>                            :initarg author
 Tian>                            :initform
 Tian>                     year   :accessor year
 Tian>                            :initarg
 Tian>                            :initform))

 Tian> (make-instance 'books :author "peter"
 Tian>                        :year 2002)

 Tian> (make-instance 'books :author "John"
 Tian>                        :year 2001)

 Tian> Given one of the slot value eg. "peter", how can I
 Tian> get the value of other slots in a same instance?

 Tian> Could anyone kindly show me a method or give an simple example?

To get any of the slot-values of an instance, you can call either 
the defined reader or accessor function on the instance.

(setq i (make-instance 'books :author "peter" :year 2002))

(author i)
=> "peter"

But there is no way to get the YEAR from I given the above string, "peter".
To get the YEAR, you would simply call the YEAR accessor:

(year i)
=> 2002

Note that MAKE-INSTANCE returns the resulting instance that is created.
It is a single instance, and it is not automatically stored anywhere
In my example, I used SETQ to store the instance in a variable so
that I could refer to it later.  (Otherwise, it would have been lost.)

In your example above, you have defined a class called BOOKS.
However, each instance of BOOKS only describes a single book,
not a collection of books.  This makes me wonder why you 
didn't call your class "BOOK", instead.

A CLOS instance is not a database and does not provide any kind of
search capability or inverse associative mapping.  

An instance is a merely a data object which can respond to functions
appropriate for its class.  When you use the :ACCESSOR or :READER slot options, 
you are simply defining a function whose purpose is to access the slot's data.  
You can use DEFMETHOD to define arbitrary functions for your class of data.
From: Sekkat Samir
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <MPG.1793d046b581cedb989681@mail.atsolute.de>
In article <····························@posting.google.com>, 
··········@hotmail.com says...
> I am a beginner of common lisp and I have met a problem about CLOS.
> 
> In a class with a certain amount of instance, eg.:
> 
> (defclass books () (author :accessor author
>                            :initarg author
>                            :initform
>                     year   :accessor year
>                            :initarg
>                            :initform))
> 
> (make-instance 'books :author "peter"
>                        :year 2002)
> 
> (make-instance 'books :author "John"
>                        :year 2001)
> 
> Given one of the slot value eg. "peter", how can I get the value of
> other slots in a same instance?
> 
> Could anyone kindly show me a method or give an simple example?
> 

AFAIK CLOS do not keep book of all created instances of a specific 
class.

So you have to define a own constructor that puts the pair name/instance 
in a hash table.

If you want to make a generic solution put this logic in an after method 
of initialize-instance

(defmethod initialize-instance :after ((ins my-base-class) &rest 
initargs)
   (...))

This code will then be executed each time an instance of my-base-class 
is executed.

Bye
Samir
From: Kenny Tilton
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <3D29F906.579803BE@nyc.rr.com>
Sekkat Samir wrote:
> AFAIK CLOS do not keep book of all created instances of a specific
> class.

Welll, it must because make-instances-obsolete has to call
update-instance-for-redefined-class on each instance.


-- 

 kenny tilton
 clinisys, inc
 ---------------------------------------------------------------
""Well, I've wrestled with reality for thirty-five years, Doctor, 
  and I'm happy to state I finally won out over it.""
                                                  Elwood P. Dowd
From: Rob Warnock
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <agcudu$7475a$1@fido.engr.sgi.com>
Kenny Tilton  <·······@nyc.rr.com> wrote:
+---------------
| Sekkat Samir wrote:
| > AFAIK CLOS do not keep book of all created instances of a specific
| > class.
| 
| Welll, it must because make-instances-obsolete has to call
| update-instance-for-redefined-class on each instance.
+---------------

Actually, I don't think it does. CLOS (quite deliberately!) allows
lazy updating of instances when a class changes, so that a given
instance doesn't have to be updated until the next time it's accessed,
whereupon *it* could check to see if its parent class had changed and
then (and only then) perform the update. But that doesn't require a
collection of instances, only back-pointers from instances to classes
(which are required anyway).


-Rob

-----
Rob Warnock, 30-3-510		<····@sgi.com>
SGI Network Engineering		<http://www.rpw3.org/>
1600 Amphitheatre Pkwy.		Phone: 650-933-1673
Mountain View, CA  94043	PP-ASEL-IA

[Note: ·········@sgi.com and ········@sgi.com aren't for humans ]  
From: Barry Margolin
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <v2nW8.24$4P.3285@paloalto-snr1.gtei.net>
In article <·················@nyc.rr.com>,
Kenny Tilton  <·······@nyc.rr.com> wrote:
>Sekkat Samir wrote:
>> AFAIK CLOS do not keep book of all created instances of a specific
>> class.
>
>Welll, it must because make-instances-obsolete has to call
>update-instance-for-redefined-class on each instance.

It can defer calling U-I-F-R-C on an instance to the first time that a slot
of the instance is read or written.  MAKE-INSTANCES-OBSOLETE often works by
simply setting a flag in the old class object; when an instance is accessed
and it still refers to that class, it gets updated.  Instances that are
never referenced don't need to be updated at all, so it's not necessary to
enumerate them.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Christopher C. Stacy
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <uk7o5j4jp.fsf@grant.org>
>>>>> On Mon, 08 Jul 2002 20:34:11 GMT, Kenny Tilton ("Kenny") writes:
 Kenny> Sekkat Samir wrote:
 >> AFAIK CLOS do not keep book of all created instances of a specific class.

 Kenny> Welll, it must because make-instances-obsolete has to call
 Kenny> update-instance-for-redefined-class on each instance.

One possible strategy is to scan all live objects in memory 
that are instances...

But anyway, ANSI CL does not include an interface that let's you access
a list of all the instances, so as far as the language definition is
concerned, CLOS doesn't have a book that you're allowed to see.

The OP seemed to be confused into thinking that CLOS was a 
database or maybe a logic system or something.
From: Kalle Olavi Niemitalo
Subject: Re: Need Help !!. (common-lisp CLOS)
Date: 
Message-ID: <87k7o65lik.fsf@Astalo.y2000.kon.iki.fi>
··········@hotmail.com (Tian) writes:

> (defclass books () (author :accessor author
>                            :initarg author
>                            :initform
>                     year   :accessor year
>                            :initarg
>                            :initform))

This gives me an error.  I guess you mean:

  (defclass books ()
    ((author :accessor author
             :initarg :author)
     (year :accessor year
           :initarg :year)))

> Given one of the slot value eg. "peter", how can I get the value of
> other slots in a same instance?

You need to collect the instances in some data structure where
you can look them up.  If you just create them and don't save
them anywhere, you cannot access them.

You could use a list, for example:

  (defvar *books* '()
    "List of all known books.")
  ;; Or sets of books?  The class was BOOKS, not BOOK.
  
  ;; Add some books in the list.
  (push (make-instance 'books :author "peter" :year 2002) *books*)
  (push (make-instance 'books :author "John" :year 2001) *books*)
  
  ;; Describe the first book by Peter.
  (describe (find "peter" *books* :key #'author :test #'string-equal))
  
  ;; Get a list of all books by Peter.
  (loop for book in *books*
        when (string-equal (author book) "peter")
          collect book)
  
  ;; Another way.
  (mapcan #'(lambda (book)
              (when (string-equal (author book) "peter")
                (list book)))
          *books*)

Or a hash table:

  (defvar *books-by-author* (make-hash-table :test 'equalp)
    "Mapping from authors (strings) to lists of books.
The test function EQUALP makes author names case-insensitive.")
  
  ;; Add all books from the *BOOKS* list to the hash table.
  (dolist (book *books*)
    (push book (gethash (author book) *books-by-author*)))
  
  ;; Describe all books by John.
  (mapc #'describe (gethash "John" *books-by-author*))