[E-Lang] down with `define' (was: newbie syntax: picayune
points from a prejudiced programmer)
Mark S. Miller
markm@caplet.com
Fri, 02 Mar 2001 13:57:33 -0800
At 09:02 AM Friday 3/2/01, Marc Stiegler wrote:
>> "delegate" is a shortcut. It is yet another keyword appearing in a
>> object definition.
>
>At what point does a shortcut become a new mental model? Why do we not refer
>to snow as, "small, lightweight crystallized oxygen dihydride"? You see a
>shortcut, I see a mental model, we are looking at the same thing. The
>difference is indeed important. I actually experience the difference between
>
>delegate {object}
>
>and
>
>match[verb,args] {E call(object, verb, args)}
>
>as a physical sensation: when I write "delegate" in an object maker, the
>tension flows out of my shoulders because it is so easy, I can't get it
>wrong. But when I write "match" in an object maker, the tension flows into
>my shoulders, because I have to get the rest of the passage exactly right
>for every conceivable message coming through. When reading, I have the same
>reactions: "delegate" means I can stop inspecting this constructor and go
>read the other constructor, "match" means it is time to review the rest
>extra-carefully.
Except for MarcS's abuse of the term "constructor" (I think you meant to
type "construct"), I see what he means, and I agree. For this and because
of the inheritance issue (see upcoming email), I'm inclined to put
"delegate" back into the language in the following restrictive way:
As now,
delegate { expr }
is syntactic shorthand (modulo variable renaming to avoid conflicts) for
match [verb, args] { E call(expr, verb, args) }
Up through 0.8.9s (the latest release at the time of this email), the
documentation and implementation agreed that the delegate construct could
appear wherever the match construct could appear, since one was just a
shorthand for the other.
In the grammar up through 0.8.9s, this includes the following contexts:
1) In a vTable:
def <name> { <method>* <matcher>* }
Any of these matchers may be of the "match" kind or the "delegate" kind.
2) In the plumbing expression. Both of the following are accepted:
def <name> match <pattern> { <expr> }
and
def <name> delegate { <expr> }
3) In a switch expression:
switch (<expr>) { <matcher>* }
Since #2 just went into the pocket, both of its cases went into the pocket
with it.
#3 was a fool's attempt at generality, and was never a good idea. All the
<matcher>s in a switch should only be of the "match" type.
For #1, it was equally foolish to allow a "delegate" construct in any but
the last position, since no matchers following it could ever be meaningful.
Therefore, I propose that the production instead be:
def <name> { <method>* <matcher>* <delegator>? }
where "<matcher>" is understood to only be a "match" construct, and
"<delegator>" is, of course, the corresponding "delegate" construct.
Cheers,
--MarkM