From: Surendra Singhi
Subject: defstruct -clisp vs. allegro / Or is it ansi standard vs. some old style?
Date: 
Message-ID: <cuei9n$spm$1@news.asu.edu>
Hi,

(defstruct circle x1 y1 r
	(area (* 3.14 r r))
	(perimeter (* 2 3.14 r)))

(setf circ1 (make-circle :x1 1 :y1 1 :r 4))

The above code works in allegro cl but it doesn't in clisp.
I checked in the standard but I couldn't parse the definition of the 
circle with the grammar in standard(I might be wrong here).

Can anyone please shed more light on it?

Thanks.
-- 
Surendra Singhi

www.public.asu.edu/~sksinghi/

From: drewc
Subject: Re: defstruct -clisp vs. allegro / Or is it ansi standard vs. some old style?
Date: 
Message-ID: <fRAOd.347253$Xk.151238@pd7tw3no>
Surendra Singhi wrote:
> Hi,
> 
> (defstruct circle x1 y1 r
>     (area (* 3.14 r r))
>     (perimeter (* 2 3.14 r)))
> 
> (setf circ1 (make-circle :x1 1 :y1 1 :r 4))

I don't use structs very often, but I'm pretty sure the above is not 
common lisp. There is nothing in the CLHS that says you can refer to a 
member of the structure in the structure definition.

In SBCL i get an "R is not defined" error, which is consistent with the 
above hypothesis.

Also, a CLOS class has the same limitation (which is a Good Thing[tm] 
IMO), which makes me suspect a struct would too.

I'm sure Kenny will be along shortly to tell you about Cells, but in the 
meantime, area and perimeter should probably be generic functions and 
not members of the struct. i.e.:

CL-USER> (defstruct circle x1 y1 r)
CIRCLE

CL-USER> (defmethod approx-area ((c circle))
	   (* 3.14 (circle-r c) (circle-r c)))
STYLE-WARNING: implicitly creating new generic function APPROX-AREA
#<STANDARD-METHOD APPROX-AREA (CIRCLE) {9DCA739}>

CL-USER> (make-circle :x1 1 :y1 1 :r 10)
#S(CIRCLE :X1 1 :Y1 1 :R 10)

CL-USER> (approx-area *)
314.0
CL-USER>

Somebody who actually uses structs may be along shortly to prove me 
wrong, but the above code works in all my Lisp compilers, while the 
original code didn't work in any of them :)

drewc
From: Steven M. Haflich
Subject: Re: defstruct -clisp vs. allegro / Or is it ansi standard vs. some old style?
Date: 
Message-ID: <GQDOd.3499$aW6.1779@newssvr22.news.prodigy.net>
drewc wrote:
> Surendra Singhi wrote:
> 
>> Hi,
>>
>> (defstruct circle x1 y1 r
>>     (area (* 3.14 r r))
>>     (perimeter (* 2 3.14 r)))
>>
>> (setf circ1 (make-circle :x1 1 :y1 1 :r 4))
> 
> 
> I don't use structs very often, but I'm pretty sure the above is not 
> common lisp. There is nothing in the CLHS that says you can refer to a 
> member of the structure in the structure definition.

This analysis is almost correct, except for one small point.  I think
this kind of reference worked by accident in Allegro 6.2, but was fixed
in 7.0 in order to conform to the ANS.  (By the way, the term "member of
the structure" is irrelevant C/Java terminology.  In the Lisp community
you should use "slot".  There are sometimes differences in the baggage
hese concepts drag along when they are used.)

make-circle is a constructor function, and that function accepts
keyword arguments that are names of the slots interned in the
keyword package.  But the ANS 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.

The small point is that it is not the structure slot that is being
referenced in the example above.  It is the like-named keyword argument
to the constructor function, according to the lambda-list rule that
default forms for keyword arguments can refer to the values of other
lambda-list variables earlier in the lambda list.

Allegro 6.2 and earlier did not conform to the requirement that the
keyword argument variables be hidden (i.e. be gensyms) so references to
earlier variables worked, but only by the accidental punning between the
keywod argument names and the slot names.
From: Surendra Singhi
Subject: Re: defstruct -clisp vs. allegro / Or is it ansi standard vs. some   old style?
Date: 
Message-ID: <cufatc$aee$1@news.asu.edu>
Steven M. Haflich wrote:
> drewc wrote:
> 
>> Surendra Singhi wrote:
>>
>>> Hi,
>>>
>>> (defstruct circle x1 y1 r
>>>     (area (* 3.14 r r))
>>>     (perimeter (* 2 3.14 r)))
>>>
>>> (setf circ1 (make-circle :x1 1 :y1 1 :r 4))
>>
>>
>>
>> I don't use structs very often, but I'm pretty sure the above is not 
>> common lisp. There is nothing in the CLHS that says you can refer to a 
>> member of the structure in the structure definition.
> 
> 
> This analysis is almost correct, except for one small point.  I think
> this kind of reference worked by accident in Allegro 6.2, but was fixed
> in 7.0 in order to conform to the ANS.  (By the way, the term "member of
> the structure" is irrelevant C/Java terminology.  In the Lisp community
> you should use "slot".  There are sometimes differences in the baggage
> hese concepts drag along when they are used.)
> 
> make-circle is a constructor function, and that function accepts
> keyword arguments that are names of the slots interned in the
> keyword package.  But the ANS 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.
> 
> The small point is that it is not the structure slot that is being
> referenced in the example above.  It is the like-named keyword argument
> to the constructor function, according to the lambda-list rule that
> default forms for keyword arguments can refer to the values of other
> lambda-list variables earlier in the lambda list.
> 
> Allegro 6.2 and earlier did not conform to the requirement that the
> keyword argument variables be hidden (i.e. be gensyms) so references to
> earlier variables worked, but only by the accidental punning between the
> keywod argument names and the slot names.

Thanks, this explanation helped.

-- 
Surendra Singhi

www.public.asu.edu/~sksinghi/
From: Albert Reiner
Subject: Re: defstruct -clisp vs. allegro / Or is it ansi standard vs. some old style?
Date: 
Message-ID: <vw8is501j42.fsf@berry.phys.ntnu.no>
[Surendra Singhi <·········@netscape.net>, Wed, 09 Feb 2005 19:52:38 -0700]:
> Hi,
> 
> (defstruct circle x1 y1 r
> 	(area (* 3.14 r r))
> 	(perimeter (* 2 3.14 r)))

I think you need a "boa constructor" for that to work:

CL-USER> (defstruct (circle 
                      (:constructor make-circle 
                                    (x1 y1 r &aux (area (* 6.3 r r)))))
           x1 y1 r area)
CIRCLE
CL-USER> (make-circle 0 0 1)
#S(CIRCLE :X1 0 :Y1 0 :R 1 :AREA 6.3)

Albert.