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
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.