Proper behavior of slot-initforms in defstruct?

Peter Stirling peter at pjstirling.plus.com
Tue Aug 4 02:12:57 UTC 2015


My read of the spec is that either behaviour is allowable.

DEFSTRUCT[1] says:

     "If a slot is not initialized in this way, it is initialized by 
evaluating /slot-initform/ in the slot description at the time the 
constructor function is called."

Which makes no reference to the environment in which the form should be 
evaluated in.

Later on it says:

     "It is as if the /slot-initforms/ were used as /initialization 
forms/ 
<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#initialization_form> 
for the /keyword parameters/ 
<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_k.htm#keyword_parameter> 
of the constructor function"

The page describing keyword arguments in ordinary lambda lists[2] also 
makes no reference to which environment should be used for initforms.

I guess they didn't think about people using closures for initforms when 
they were drawing it up?

To side-step the issue I would invoke a closure from the initform 
instead (if that's how you want to do it).

[1] http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm
[2] http://www.lispworks.com/documentation/HyperSpec/Body/03_dad.htm

On 03/08/15 23:04, Peter Stirling wrote:
> That makes no sense, the bindings in the let are independent.
>
>
> On 03/08/15 22:42, Laughing Water wrote:
>> It looks like you need a LET* to guarantee the order of evaluation 
>> within your LET. Otherwise, it’s undefined.
>>
>> Laughing Water
>>
>>> On Aug 3, 2015, at 3:27 PM, Jean-Claude Beaudoin 
>>> <jean.claude.beaudoin at gmail.com> wrote:
>>>
>>>
>>> Please consider the following code:
>>>
>>> (defparameter init-a 1)
>>>
>>> (let ((init-a 42) (serial-no 0))
>>>    (defstruct foo (a init-a) (b (incf serial-no)))
>>>    (defun get-foo-serial-no () serial-no))
>>>
>>> (defstruct (bar (:include foo)) (c 33) d)
>>>
>>> When one loads the above and then try to call #'make-bar the result
>>> varies widely from one lisp implementation (clisp) to another.
>>>
>>> clisp: (make-bar) --> #S(BAR :A 1 :B 1 :C 33 :D NIL)
>>> ccl: (make-bar) --> <enter the debugger saying: "Unbound variable: 
>>> SERIAL-NO">
>>>
>>> lispworks, allegro and sbcl also behave more or less like ccl.
>>>
>>> What is the proper ANSI-CL behavior in this case here?
>>> Is clisp right in evaluating the slot initform in its "proper" 
>>> lexical context?
>>> Or is the correct behavior to replicate the slot initform verbatim
>>> in the sub-structure constructor regardless of its original lexical 
>>> context
>>> like the others do?
>>>
>>> I guess that this question has probably been asked before, in a 
>>> somewhat
>>> distant past, but my google skills have not been sharp enough to 
>>> find it, sorry.
>>>
>>>
>>
>
>
> ---
> This email has been checked for viruses by Avast antivirus software.
> https://www.avast.com/antivirus
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20150804/1aaf7275/attachment.html>


More information about the pro mailing list