Brendan,
Great shame, but as you say its a broken design.
Many thanks for the full explanation,
Aaron
----- Original Message -----
From: Brendan Eich
To: Aaron Gray
Cc: es-discuss@mozilla.org
Sent: Monday, December 01, 2008 1:06 AM
Subject: Re: Understanding reasons for Harmony
On Nov 30, 2008, at 10:49 AM, Aaron Gray wrote:
Well as announced in August the ECMAScript 4 language is being heavily
watered down. Both packages (April)
https://mail.mozilla.org/pipermail/es-discuss/2008-April/006183.html
I cannot actually see what is wrong here, AFAICS package Q's usage of x
should be an error as x is actually defined in R as external and there is no
other definition of x in scope.
Package Q contains
import R.*;
which brings (or should bring) R.x into scope under the name x in Q.
Note that "external" does not mean what "extern" in C means. It was a
proposed ES4 built-in namespace meaning "defined in this package but visible
outside of it".
Could someone explain or give a better example.
I can see how the decisions are hard to understand without close reading,
including knowing what "external" was proposed to mean (I can't find a trace of
it in the wiki -- it was cut too well), and thinking through the meaning of
parenthetical asides such as Lars's "consider that public::x is introduced in
some later file, at a later time" and "consider flagging the reference to x in
P as ambiguous".
Even more important than these fine points was the big-picture point that
packages were intended to be sugar for namespaces. Lack of a desugaring meant
ES4 was at risk of being all of late, incomplete, and inconsistent.
If there were no conflict about the meaning of x in P, then we would have not
had such a problem.
Avoiding a conflict by making the reference to x ambiguous (an error) was
considered "arcane" because the nesting and order of package fragments should
not introduce or eliminate such an error. As with namespaces (more below),
package-based name lookup must agree between compile time and runtime. They
must not be subject to complicated and hard-to-follow rules.
Plus, we had a schedule for ES4 that was being slipped with every open
problem of this order. The right thing to do per sane requirements management
is to cut, with additions such as the built-in "internal" namespace added to
palliate the loss of packages in a future-proof way.
Therefore the example Lars gave is sufficient -- you don't need a better
example. That one was sufficient to kill packages as sugar in the time-frame we
had for ES4.
and now namespaces have been jetisoned too.
https://mail.mozilla.org/pipermail/es-discuss/2008-August/006837.html
Again could someone give a good example of whats wrong with namespaces.
The fundamental problem with namespaces was the lack of a module system by
which to prioritize namespaces during name lookup.
This need for prioritization (one idea was a first-name-wins reservation
system) affected both unqualified name lookup due to the extensible global
object, and name lookup among superclasses.
Consider just the global object case, with two namespaces, both open in the
same lexical scope, where a namespace "ns" is defined at first in only one of
the namespaces (note how namespaces can qualify namespace names along with
other names):
namespace A;
namespace B;
use namespace A, namespace B;
A namespace ns;
Let's say there's a use of ns to qualify an identifier x, in the same lexical
scope (top-level content in a script tag, in a web page):
... ns::x ...
Assume x resolves in ns. The question is: what does ns mean? Let's refine the
reference to be in a function body:
function foo() {
... ns::x ...
}
and close this lexical scope (program defined as a script tag's inline
content or out-of-line src=URL content). Then in a later program evaluated in
the same global object, we add
B namespace ns;
foo();
What effect, if any, does the B::ns namespace have on the meaning of ns::x in
foo's body?
We don't want any effect, even an ambiguity error -- otherwise name integrity
is gone and information leaks if not hijacking attacks are too easy. Lexical
scope means the name lookoup judgments at compile time and runtime should
agree, and foo's scope should be static in all senses.
But how do we implement this? ES4 had only the reservation system idea
whereby:
A namespace ns;
would reserve "ns" in *all* namespaces, even ones not seen yet, for the life
of the global object being mutated by the definitions. This was considered
broken-as-designed.
An alternative would treat each top-level scope as a module, either by giving
it its own global object (as is done in AS3, IIRC), or at least a subjective
prioritization mechanism by which to make "ns" mean only A::ns when used in
foo, no matter what B::ns might be defined later. But such a solution was not
designed or proposed for ES4, and we were out of time and complexity budget.
/be
_______________________________________________
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss