From: Chris Riesbeck
Subject: DEFSTRUCT init forms
Date: 
Message-ID: <2lksov$q18@anaxagoras.ils.nwu.edu>
Is the following init-form for the slot B legal? I couldn't find
anything relevant in the FAQ file.

	(DEFSTRUCT FOO (A 0) (B (1+ A)))

Many Common Lisp's handle it, but CLISP doesn't. 

It's compatible with the MAKE-SHIP constructor on page 474, CLtL 2.

Anything in the ANSI standard?

From: ······@ma2s2.mathematik.uni-karlsruhe.de
Subject: Re: DEFSTRUCT init forms
Date: 
Message-ID: <2lnetp$2rv@nz12.rz.uni-karlsruhe.de>
Chris Riesbeck <········@ils.nwu.edu> asks:

> Is the following init-form for the slot B legal? I couldn't find
> anything relevant in the FAQ file.
>
>	(DEFSTRUCT FOO (A 0) (B (1+ A)))
>
> Many Common Lisp's handle it, but CLISP doesn't. 

CLtL2 specifies on p. 472/473:
  "DEFSTRUCT must treat slot default-init forms ... as occuring within
   the enclosing lexical environment, not within the global environment."

And dpANS says (second to last paragraph of page 8-3):
  "The slot default init forms are evaluated in the lexical environment in
   which the DEFSTRUCT form itself appears and in the dynamic environment
   in which the call to the constructor function appears."

So the second occurrence of A refers to an entity outside the DEFSTRUCT form.
CLISP is right.

If you want the default value for B to depend on the slot A, you have to use
the :CONSTRUCTOR option.


                    Bruno Haible
                    ······@ma2s2.mathematik.uni-karlsruhe.de
From: Barry Margolin
Subject: Re: DEFSTRUCT init forms
Date: 
Message-ID: <2lnt59INNq3r@early-bird.think.com>
In article <··········@anaxagoras.ils.nwu.edu> ········@ils.nwu.edu (Chris Riesbeck) writes:
>Is the following init-form for the slot B legal? I couldn't find
>anything relevant in the FAQ file.
>
>	(DEFSTRUCT FOO (A 0) (B (1+ A)))
>
>Many Common Lisp's handle it, but CLISP doesn't. 
>
>It's compatible with the MAKE-SHIP constructor on page 474, CLtL 2.

That equivalence is just supposed to be illustrative, not definitive.  The
text says, "roughly as if its definition were".

>Anything in the ANSI standard?

The dpANS makes it clear that preceding slots should *not* be accessible
this way.  It says:

    The symbols which name the slots must not be used by the implementation
    as the names for the lambda variables in the constructor function,
    since one or more of those symbols might have been proclaimed SPECIAL
    or might be defined as the name of a constant variable.  The slot
    default init forms are evaluated in the lexical environment in which
    the DEFSTRUCT form itself appears and in the dynamic environment in
    which the call to the constructor function appears.

Thus, a more precise equivalence on page 474 would be:

(defun make-<structure> (&key ((:<slotname1> #:G001) <init1>)
		              ((:<slotname2> #:G002) <init2>) ...)
  ...)

where the #:Gnnn are gensyms.

Since CLtL and CLtL2 are less clear about this, it would be a good idea to
avoid writing code that depends on either interpretation.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Chris Riesbeck
Subject: Re: DEFSTRUCT init forms
Date: 
Message-ID: <2lq2mg$elc@anaxagoras.ils.nwu.edu>
In article <············@early-bird.think.com>, ······@think.com (Barry Margolin) writes:
> The dpANS makes it clear that preceding slots should *not* be accessible
> this way.  It says:
> 
>     The symbols which name the slots must not be used by the implementation
>     as the names for the lambda variables in the constructor function,
>     ...
> 
> Since CLtL and CLtL2 are less clear about this, it would be a good idea to
> avoid writing code that depends on either interpretation.

That's nice and clear and the rationale (omitted above) makes a lot of
sense. 

Experimenting with the Lisp's I could find here, MCL v 2.0.1 (Mac),
Lucid v 3 (Sun), Lucid v 4 (RS/6000) and Franz Allegro v ? (IBM PC)
all appear to get this wrong, in that the following happens in each:

	> (defstruct foo (a 0) (b (1+ a)))
        FOO
        > (make-foo)
        #S(FOO :A 0 :B 1)
	
Perhaps this qualifies as a Common Lisp Pitfall.

Thanks
From: Lawrence G. Mayka
Subject: Re: DEFSTRUCT init forms
Date: 
Message-ID: <LGM.94Mar12144545@polaris.flw.att.com>
In article <··········@anaxagoras.ils.nwu.edu> ········@ils.nwu.edu (Chris Riesbeck) writes:

   In article <············@early-bird.think.com>, ······@think.com (Barry Margolin) writes:
   > The dpANS makes it clear that preceding slots should *not* be accessible
   > this way.  It says:
   > 
   >     The symbols which name the slots must not be used by the implementation
   >     as the names for the lambda variables in the constructor function,
   >     ...
   > 
   > Since CLtL and CLtL2 are less clear about this, it would be a good idea to
   > avoid writing code that depends on either interpretation.

   That's nice and clear and the rationale (omitted above) makes a lot of
   sense. 

   Experimenting with the Lisp's I could find here, MCL v 2.0.1 (Mac),
   Lucid v 3 (Sun), Lucid v 4 (RS/6000) and Franz Allegro v ? (IBM PC)
   all appear to get this wrong, in that the following happens in each:

	   > (defstruct foo (a 0) (b (1+ a)))
	   FOO
	   > (make-foo)
	   #S(FOO :A 0 :B 1)

   Perhaps this qualifies as a Common Lisp Pitfall.

Genera, LispWorks, CLISP, CMU CL, and Delphi CL all do this correctly,
but in some cases that may be due to bug reports I've filed on this
topic over the years.
--
        Lawrence G. Mayka
        AT&T Bell Laboratories
        ···@iexist.att.com

Standard disclaimer.