From: Ron Garret on
In article <9mpy6nexp8c.fsf(a)runa.se>, bjorn(a)runa.se (Björn Lindberg)
wrote:

> In any case, one passage in the Hyperspec which hasn't been mentioned
> yet is the following:
>
> It is as if the slot-initforms were used as initialization forms for
> the keyword parameters of the constructor function.
>
> If it is relevant to the case at hand, it implies the interpretation
> where initforms are evaluated in the lexical envvironment of the
> *including* structure definition.

This is indeed an valid argument, but it is not a slam-dunk (and hence
it is not a refutation of the claim of ambiguity). The reason it is not
a slam-dunk is because this sentence occurs in the context of an example
meant to elucidate *when* initforms are evaluated. One could therefore
reasonably argue that the sentence is not meant to apply in general. In
particular, the sentence's reference to "the constructor function" does
*not* necessarily imply that there is a single constructor function in
play in all cases. The possibility remains that in the case of an
:included structure there are two constructor functions, one for the
including structure and one for the included structure, and hence two
lexical environments. Of course, the spec does not *require* this
behavior (if it did, there would be no ambiguity and we would not be
having this discussion). But it doesn't rule it out either.

rg
From: Ron Garret on
In article <m3aazuux1e.fsf(a)moon.robolove.meer.net>,
Madhu <enometh(a)meer.net> wrote:

> | Just for the record, here's what Dan actually said:
> |
> | "I think I can say pretty reliably
> | that during the design of CL, nobody thought about
> | this.  So the spec is not written in such a way as to
> | give unambiguous guidance about what these forms
> | ought to do."
>
> I believe he means "He" did not think about this.

I'm pretty sure he meant what he wrote. But I'm sure he's easy to
contact. Why don't you ask him?

> [broken record plays again]
> |
> |> and the behaviour in fact conforms with what I have
> |> come to expect, given the spirit expressed in other parts of the
> |> language [which I do not assume you have any familiarity or sympathy
> |> with]
> ^^ familiarity with or sympathy for
>
> | You assume incorrectly. And you do so again and again and again.
>
> Others may wish to consider that in CL, DEFSTRUCT is a defined as a
> macro.

What does that have to do with anything?

> When I do C-Shift-m Macroexpand-1 around a defstruct definition I expect
> to see the entire form for THAT defstruct definition, which will be
> evaluated in the lexical environment of that Defstruct form.

You expect more than that. You expect DEFSTRUCT to behave like DEFMACRO
rather than DEFUN with respect to the surrounding lexical environment.
You expect that that expanded definition will NOT make any reference to
an initialization function for an included structure that was defined in
some other lexical environment. But THOSE expectations have no basis in
the spec. That is simply your own personal prejudice.

A perfectly reasonable expansion of (defstruct foo x (:include baz))
would be something like:

(progn
(internal-define-struct foo :slots '(x) :include '(baz))
(defun internal-initialize-foo (f args)
(initialize-slot f 'x (extract-arg args 'x))
(defun make-foo (&rest args)
(let ((struct (internal-make-struct (internal-struct-size 'foo))))
(internal-initialize-foo struct args)
(internal-initialize-baz struct args :offset (length '(x)))
...)

where internal-initialize-baz, of course, gets defined in the expansion
of (defstruct baz ...) and therefore captures the lexical environment
surrounding THAT defstruct.

> As a CL programmer I am not accustomed to seeing opaque undebuggable
> closures when I do this.

Please note that the above expansion contains no opaque, undebuggable
closures.

> Instead I expect to see the entire form of the
> defstruct which :includes (as defined in the specification) the literal
> forms of the included defstruct definition, as the specification
> indicates

The specification may indicate this. It may even strongly imply this.
But it does not *require* this.

> So I know EXACTLY (by the principles of referential
> transparency) what is evaluated in the one lexical environment (of the
> macro) of the defstruct.

Please note that in the above example you do know exactly what is
evaluated in the lexical environment of the defstruct.

> This is the rationale for my claim that a possible ambiguity has been
> resolved, in the context of the CL language. The alternative
> interpretation does not make sense in this context.

Yes, it does. As I have shown above.

> The scheme indoctrinated will find this sort of power too much to
> handle. However there is more hope in the more people will be
> discovering the lisp way now that MIT has officially stopped
> indoctrinating its freshmen.

Maybe some day the world will be enlightened enough to reject lexical
scoping entirely and return to the halcyon days where everything was
dynamically scoped and we didn't have to argue about things like whether
or not DEFVAR does the Right Thing either. Until that happens, I'm
afraid you're stuck with the spec as it is written. And as it is
written it is ambiguous. I'm sorry you don't like it, but that's the
way it is.

rg
From: =?iso-8859-1?Q?Bj=F6rn?= Lindberg on
Ron Garret <rNOSPAMon(a)flownet.com> writes:

> In article <9mpy6nexp8c.fsf(a)runa.se>, bjorn(a)runa.se (Bj�rn Lindberg)
> wrote:
>
>> In any case, one passage in the Hyperspec which hasn't been mentioned
>> yet is the following:
>>
>> It is as if the slot-initforms were used as initialization forms for
>> the keyword parameters of the constructor function.
>>
>> If it is relevant to the case at hand, it implies the interpretation
>> where initforms are evaluated in the lexical envvironment of the
>> *including* structure definition.
>
> [...] In particular, the sentence's reference to "the constructor
> function" does *not* necessarily imply that there is a single
> constructor function in play in all cases.

But there is. Make-foo is the constructor function of the structure
foo.

> The possibility remains that in the case of an
> :included structure there are two constructor functions, one for the
> including structure and one for the included structure, and hence two
> lexical environments.

Such an implementation is not compatible with the requirement that the
slot initforms evaluate as if they were initforms to keyword arguments.

If I were to speculate, I would guess that in some ancient Lisp,
:include had a very literal meaning to insert s-expressions of one
structure definition into another. If this were the background, it would
explain why the spec does not clearly state the environment of
evaluation, despite doing so for defclass. Many apparent ambiguities in
the spec can be explained knowing the behaviour of Lisps leading up to
CL. It would be interesting to have Kent Pitman's input on the subject.


Bj�rn Lindberg
From: Ron Garret on
In article <9mpeip6xk1u.fsf(a)runa.se>, bjorn(a)runa.se (Björn Lindberg)
wrote:

> Ron Garret <rNOSPAMon(a)flownet.com> writes:
>
> > In article <9mpy6nexp8c.fsf(a)runa.se>, bjorn(a)runa.se (Björn Lindberg)
> > wrote:
> >
> >> In any case, one passage in the Hyperspec which hasn't been mentioned
> >> yet is the following:
> >>
> >> It is as if the slot-initforms were used as initialization forms for
> >> the keyword parameters of the constructor function.
> >>
> >> If it is relevant to the case at hand, it implies the interpretation
> >> where initforms are evaluated in the lexical envvironment of the
> >> *including* structure definition.
> >
> > [...] In particular, the sentence's reference to "the constructor
> > function" does *not* necessarily imply that there is a single
> > constructor function in play in all cases.
>
> But there is. Make-foo is the constructor function of the structure
> foo.

Let me be more precise: the sentence's reference to "the constructor
function" does not preclude the possibility that there are additional
constructor/initialization functions created behind the scenes that are
invoked by make-foo (assuming now that FOO :includes BAZ) and which
capture the lexical environment where BAZ is defined.

> > The possibility remains that in the case of an
> > :included structure there are two constructor functions, one for the
> > including structure and one for the included structure, and hence two
> > lexical environments.
>
> Such an implementation is not compatible with the requirement that the
> slot initforms evaluate as if they were initforms to keyword arguments.

As I just explained, this is not a requirement, it is part of an
expository sentence pertaining to an example that has nothing to do with
:included structs.

> the spec does not clearly state the environment of evaluation

That is exactly the point I am trying to make. (And it is the *only*
point I am trying to make.)

rg
From: Tim Bradshaw on
On 2009-10-13 08:02:19 +0100, Ron Garret <rNOSPAMon(a)flownet.com> said:

> No, that is not true. The very fact that a lexical environment is
> mentioned indicates that these are not just forms, that there are in
> fact (or at least should be) closures being created behind the scenes.

And indeed such closures are being created in the simple case (ie no
inclusion).

> This has nothing to do with newbie expectations. This has to do with
> the fact that your interpretation would be a BAD DESIGN because it would
> break the referential opacity of included structures.

I don't agree with Ron about much, but yes. It's not bad design in
fact: it's catastrophically awful design. Accidental name capture like
this is the kind of thing that makes the hygienic macro people whine
about CL.

I haven't read much of the rest of this thread yet, but come on people,
be serious: *If* the standard says this (and as a native speaker of
English I think it is ambiguous), it is a bug in the standard. Let's
not get held to bugs which clearly have such horrible effects.