From: Peter Norvig - Sun Labs East
Subject: CLOS: How to handle :initform with :allocation :class
Date: 
Message-ID: <10157@eastapps.East.Sun.COM>
Consider the following:

(defclass c1 ()
  ((a :allocation :class :initform (complex-computation))))

(dotimes (i 1000)
  (make-instance 'c1))

Should this call complex-computation 1 time or 1000?  My intuition
is that it should only be once, but the only support I find is on
page 802 CLtL2: "The :initform form for a local slot may be used
when creating an instance ... . The :initform form for a shared slot may
be used when defining or re-defining a class."

Note that Lucid CL will call complex-computation 1000 times in the above
example.  Is this a bug, a misunderstanding on my part, or a whole in the
specification?


Peter Norvig				Tel: (508) 671-0508
Sun Microsystems Laboratories		Fax: (508) 671-0624
Two Federal Street			Net: ············@East.Sun.COM
Billerica MA 01821

From: Gregor Kiczales
Subject: Re: CLOS: How to handle :initform with :allocation :class
Date: 
Message-ID: <GREGOR.92Jan2103238@tracer-bullet.parc.xerox.com>
Peter Norvig writes:

>Consider the following:
>
>(defclass c1 ()
>  ((a :allocation :class :initform (complex-computation))))
>
>(dotimes (i 1000)
>  (make-instance 'c1))
>
>Should this call complex-computation 1 time or 1000?

The precise moment at which the initform for a class slot is evaluated
is deliberately not specified.  What was intended was that it only be
evaluated once, and that it be evaluated within a range of times from
class initialization to class finalization.  

This means that a fairly precise answer can be given to your question.
Evaluation of the DEFCLASS form is permitted to call
(COMPLEX-COMPUTATION) at most once and evaluation of the DOTIMES loop is
permitted to call (COMPLEX-COMPUTATION) no more than once.  A second
evaluation of the DOTIMES loop isn't permitted to call
(COMPLEX-COMPUTATION) at all.  That is, evaluation of the initform for a
shared slot can be done either when the class is first created (when the
class metaobject is initialized) or when the first instance of the class
is created (when the class metaobject is finalized).
From: Barry Margolin
Subject: Re: CLOS: How to handle :initform with :allocation :class
Date: 
Message-ID: <km767oINNhqt@early-bird.think.com>
In article <·····@eastapps.East.Sun.COM> ·······@east.sun.com (Peter Norvig) writes:
>Note that Lucid CL will call complex-computation 1000 times in the above
>example.  Is this a bug, a misunderstanding on my part, or a whole in the
>specification?

I just tried it in Lucid CL 4.0.1 on a Sun, and it only evaluated the
initform once, when the class was defined.

To Gregor: You said that the spec allows the initform for shared slots to
be evaluated when the class is defined (and both Lucid and Genera seem do
this) or when the first instance is created, but actually it's somewhat
inconsistent about it, although it mostly seem to force it to be evaluated
when the class is defined.  The description of SHARED-INITIALIZE says that
it uses the initforms to fill in any unbound slots; I suppose the loophole
is that shared slots might not be unbound at the time the first instance is
initialized.  The description of DEFCLASS says that shared slot initforms
are evaluated in the dynamic environment of the DEFCLASS form; unless
you're using an extension of CL that supports dynamic closures, this
implies that the initform will be evaluated at DEFCLASS time.  (To support
the use of THROW, GO, RETURN-FROM, INVOKE-RESTART, etc. in the initform,
you'd need to capture the entire dynamic environment, not just dynamic
variable bindings) in the captured initform closure).

In general, I believe that when CLtL and the draft standard say that
something is evaluated in the dynamic environment of a form, they mean that
it is executed during the execution of the form.
-- 
Barry Margolin, Thinking Machines Corp.

······@think.com
{uunet,harvard}!think!barmar