Namespaces as Sugar (was: complexity tax)

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Namespaces as Sugar (was: complexity tax)

Mark S. Miller-2
On Sun, May 25, 2008 at 1:16 PM, Mark S. Miller <[hidden email]> wrote:

> On Tue, May 20, 2008 at 7:02 AM, Mark S. Miller <[hidden email]> wrote:
>> 2008/5/19 Brendan Eich <[hidden email]>:
>>> On May 19, 2008, at 6:54 PM, Mark Miller wrote:
>>>
>>>> If I could
>>>> have a language with some of the syntactic conveniences of ES4 but
>>>> without ES4's semantics, I'd be quite happy.
>>>
>>> What semantics in particular, can you pick on something specific that's not
>>> in your classes as sugar proposal (rather than have me guess)?


> b) At the property-name level, in order to be able to add additional
> properties to existing objects without breaking existing code that is
> already using those names for other reasons.

> So, although I don't find any of these use-cases compelling, I'd agree
> that #b is at least a real problem, and is the most plausible of the
> arguments for some additional support in a future JavaScript. My next
> message, if I get to it, will be "Namespaces as Sugar". If you agree
> with me that #b is better avoided than solved, feel free to skip it.


                             Namespaces as Sugar


JavaScript already allows non-identifier strings to be used as
property names. However, such non-identifiers cannot be used with the
'.'  syntax, and must be quoted in the object literal syntax, so they
are generally avoided.

ES4 grammar contains the productions

NameExpression ::=
    Identifier
|   NamespaceExpression "::" PropertyIdentifier

NamespaceExpression ::=
    NameExpression
|   StringLiteral

// Used in object literals
FieldName ::=
    NameExpression
|   ...

// Used to access a property
PropertyOperator ::=
    "." NameExpression
|   ...


Good enough. Rather than invent new semantic concepts of Name and
Namespace objects, we could just have these expand into non-identifier
strings consisting of components (typically identifiers) separated by
some kind of path separator string. The most logical choices for path
separator would probably be either "::" or ".". For clarity in this
note, in order to keep the levels distinct, I will use the path
separator "/". Note that my actual preference would be "::".

So, for example, the program

    const meta = "meta";
    const obj = {meta::foo: 3};
    const n = obj.meta::foo;
    obj.meta::foo = 4;

is syntactic sugar for

    const meta = "meta";
    var tmp = {}; tmp[meta+"/foo"] = 3; const obj = tmp;
    const n = obj[meta + "/foo"];
    obj[meta + "/foo"] = 4;

This use of NamespaceExpressions will be familiar from XML. The value
of the NamespaceExpression can be a longer string, allowing us to
refer to long fully qualified names using short locally defined names.

    const nest = "com/fudco/reflect/bar/nest";
    const obj = {nest::foo: 3};

As with XML namespaces, this proposal does not allow namespaces to be
what ES4 calls "open". In other words, namespace-qualified names would
always be explicitly qualified.

The proposal above is *only* for a syntactic convenience. It would not
expand the semantics of the language at all.

--
    Cheers,
    --MarkM
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 26, 2008, at 10:02 AM, Mark S. Miller wrote:

> we could just have these expand into non-identifier
> strings consisting of components (typically identifiers) separated by
> some kind of path separator string. The most logical choices for path
> separator would probably be either "::" or ".".

This is not backward compatible, since code today is free to use such  
substrings in property names, and I will be you a donut real code  
does use arbitrary printable ASCII strings. BTW, this name-mangling  
idea already came up over a year ago:

http://wiki.ecmascript.org/doku.php?
id=meetings:minutes_apr_18_2007#es_3.1_discussion

Then there is the missing open namespaces idea. Without the ability  
to implicitly qualify identifiers by namespaces, users (as in XML  
with namespaces) have to compose identifiers from different  
namespaces using explicit qualifiers on every reference. This is  
verbose, tedious, and error-prone, and experience from XML suggests  
strongly that it's not sufficiently usable compared to alternatives  
that have a single namespace, or that support unqualified imports:

http://osteele.com/archives/2004/07/a-fresh-canvas
http://osteele.com/archives/2004/08/unqualified-imports-for-xml
http://osteele.com/archives/2004/08/unqualified-imports-for-xml

A single namespace does not scale, we know this from today's  
situation on the web where, by convention, libraries share a top-
level namespace and put their local names in a single object per  
library (MochiKit, dojo, etc.). This leaves unqualified import as the  
remaining alternative for usability.

In short, reinventing namespaces via name mangling loses backward  
compatibility, and without what Steele calls unqualified import, it  
lacks the usability programmers expect from most other languages with  
namespaces. Users have to cope in exactly this way today using JS1  
(lack of . notation and quote requirements are not the main issue).  
Why not give them both better syntax and better semantics?

/be
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Mark S. Miller-2
On Mon, May 26, 2008 at 10:22 AM, Brendan Eich <[hidden email]> wrote:
> Why not give them both better syntax and better semantics?

A wonderful idea! I eagerly await such a proposal.

--
    Cheers,
    --MarkM
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 26, 2008, at 10:34 AM, Mark S. Miller wrote:

> On Mon, May 26, 2008 at 10:22 AM, Brendan Eich  
> <[hidden email]> wrote:
>> Why not give them both better syntax and better semantics?
>
> A wonderful idea! I eagerly await such a proposal.

Was that mere snarkiness?

The ES4 proposal has unqualified import. It has backward  
compatibility in the sense that it does not change the interpretation  
of obj["ns::prop"] or obj["ns/prop"]. If it has other problems (it  
surely does -- we're working on specifying it fully, and implementing  
it in the RI -- both of which help find problems), then please point  
them out. Or make an alternative proposal. All I am suggesting is  
that any solution (a) not reinterpret existing property names, and  
(b) support unqualified import in osteele's sense of the phrase.

/be

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Mark S. Miller-2
On Mon, May 26, 2008 at 11:29 AM, Brendan Eich <[hidden email]> wrote:
> On May 26, 2008, at 10:34 AM, Mark S. Miller wrote:
>> On Mon, May 26, 2008 at 10:22 AM, Brendan Eich <[hidden email]>
>> wrote:
>>> Why not give them both better syntax and better semantics?
>> A wonderful idea! I eagerly await such a proposal.
> Was that mere snarkiness?

It was a snarky answer to what I perceived to be a snarky question. Of
course we want "better". The whole argument is about which direction
is better. Your question assumes your conclusion.

If I misunderstood your question, and if it actually wasn't snarky,
then I apologize and withdraw the snarkiness of my answer.



> The ES4 proposal has unqualified import. It has backward compatibility in
> the sense that it does not change the interpretation of obj["ns::prop"] or
> obj["ns/prop"].

Depends what you mean by "change the interpretation". IIUC, ES4 would
change the interpretation of the second of these to
obj[public::"ns/prop"] (or it would if string literals were allowed to
the right of a colon). Namespaces-as-Sugar doesn't expand the set of
mentionable property names, but it allows some to be said in a
syntactically more convenient fashion. This doesn't change the meaning
of obj["ns/prop"]. It just allows the syntax obj.ns::prop to mean the
same thing.


> If it has other problems (it surely does -- we're working on
> specifying it fully, and implementing it in the RI -- both of which help
> find problems), then please point them out.

Section 4.7 "Name Resolution" of the draft spec document goes on for
nine pages. Do you consider this a problem?


> Or make an alternative proposal.
> All I am suggesting is that any solution (a) not reinterpret existing
> property names, and (b) support unqualified import in osteele's sense of the
> phrase.


Earlier I said

> So, although I don't find any of these use-cases compelling, I'd agree
> that #b is at least a real problem, and is the most plausible of the
> arguments for some additional support in a future JavaScript. My next
> message, if I get to it, will be "Namespaces as Sugar". If you agree
> with me that #b is better avoided than solved, feel free to skip it.

so I hope I've been clear that my favorite alternate proposal is to
avoid adding any namespace mechanism to EcmaScript at all. This would
clearly satisfy your (a) request above. Depending on what
"reinterpret" means, I argue that Namespaces-as-Sugar also satisfies
(a). It just provides some conveniences for saying what can already be
said more awkwardly.

As for your (b), I fail to see why it's good. Remember, we are talking
about property names here, not module linkage! What's the compelling
need for a single object to simultaneously have properties defined in
different namespaces? How would those properties come to be added to
that object? I just don't get it. Am I missing something?

--
    Cheers,
    --MarkM
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 26, 2008, at 12:05 PM, Mark S. Miller wrote:

On Mon, May 26, 2008 at 11:29 AM, Brendan Eich <[hidden email]> wrote:
On May 26, 2008, at 10:34 AM, Mark S. Miller wrote:
On Mon, May 26, 2008 at 10:22 AM, Brendan Eich <[hidden email]>
wrote:
Why not give them both better syntax and better semantics?
A wonderful idea! I eagerly await such a proposal.
Was that mere snarkiness?

It was a snarky answer to what I perceived to be a snarky question. Of
course we want "better". The whole argument is about which direction
is better. Your question assumes your conclusion.

Not quite. My point was not snarky, and it did not assume a conclusion -- it questioned your premise: "Rather than invent new semantic concepts ...". You propose new syntax that desugars to existing semantics. I am asking: is there a non-trivial benefit in extending semantics too? Why not extend semantics too?

The answer turns, I think, on usability of namespaces, in particular on whether "unqualified import" is important.

It may be hard to argue about usability except by pointing to other languages. Hence my references to XML namespaces, which pretty clearly suffer from lack of unqualified import.

It may be that you and I differ again in preferring ES3.1 vs. ES4 premises, and one of the ES4 premises you reject is "unqualified import is important for usability" (assuming premises justifying adding namespaces in the first place).

In that case, it would still help if you had an argument based on ES4 premises that led to a simpler ES4. But it would be sillly to repeat ES3 premises as disqualifying a part of ES4, since they're different evolutions of ES3 with different design goals based on different premises.


If I misunderstood your question, and if it actually wasn't snarky,
then I apologize and withdraw the snarkiness of my answer.

Thanks.


The ES4 proposal has unqualified import. It has backward compatibility in
the sense that it does not change the interpretation of obj["ns::prop"] or
obj["ns/prop"].

Depends what you mean by "change the interpretation". IIUC, ES4 would
change the interpretation of the second of these to
obj[public::"ns/prop"] (or it would if string literals were allowed to
the right of a colon).

It would be something like obj.public::["ns/prop"], but the point is that this ES4 spelling makes no change from ES3 terms (obj["ns/prop"]), where every property specified by ES3 or created by an ES3 programmer is in the public (compatibility) namespace. It's equivalent syntax, it parses to the same post-definition-phase AST node.


Namespaces-as-Sugar doesn't expand the set of
mentionable property names, but it allows some to be said in a
syntactically more convenient fashion. This doesn't change the meaning
of obj["ns/prop"]. It just allows the syntax obj.ns::prop to mean the
same thing.

Oh, I see. Two issues apart from usability:

1. Is it compatible with all relevant Ecma standards? It is not with ECMA-357, E4X. Breaking compatibility with another Ecma standard, one implemented in at least three common implementations (SpiderMonkey, Rhino, ActionScript 3 in Flash 9 and higher), may be a cost worth paying. I'm not convinced, and Ecma/ISO folks may frown on such an overt incompatibility.

2. Is it compatible or safe (integrity-wise) if you allow unqualified import? Once you allow the identifier expression prop to denote obj.ns::prop in some ns-importing context where obj is on the scope chain, it seems to me you've allowed arbitrary ES3 code to inject identifiers into ES4 namespaces. Consider the case where obj is the global object.

In ES4, a namespace (a first class object) can be hidden, internal to a compilation unit (file or script source). It is therefore not possible in ES4/ES3 mixed embeddings for ES3 to inject names into any old namespace, just by prefixing "ns/" to the property identifier. This is an important integrity property.


If it has other problems (it surely does -- we're working on
specifying it fully, and implementing it in the RI -- both of which help
find problems), then please point them out.

Section 4.7 "Name Resolution" of the draft spec document goes on for
nine pages. Do you consider this a problem?

I already replied in an earlier thread: "I agree with you that namespaces add more complexity than classes alone".

But for the record, no: high (or merely moderate) draft-spec page counts do not constitute a problem by themselves. In particular, a finished language spec may need many pages to specify something subtle, which has the beneficial effect of *reducing* programmer burden, including cognitive load or "complexity." Someone has to pay for a solution to a problem such as namespacing. There's no free lunch. Currently ES puts almost all the burden on the programmer.

Also, the spec draft pages currently dedicated to name lookup seem to me ripe for reduction in size. Maybe not to one page, but we'll see. It's too early, besides being inconclusive, to bean-count spec pages and score accordingly.


As for your (b), I fail to see why it's good. Remember, we are talking
about property names here, not module linkage!

Who said anything about modules? Oliver Steele's "import" usage should not mislead. We're talking about how to use namespaces without requiring every reference to a namespace-qualified name to be explicitly prefixed by a qualifier. Namespaces cut across compilation unit, class, and object boundaries in ES4 as proposed.


What's the compelling
need for a single object to simultaneously have properties defined in
different namespaces? How would those properties come to be added to
that object? I just don't get it. Am I missing something?

There are many use-cases. Consider the ES4 spec and Reference Implementation, which segregate helper and informative methods from normative ones in the public namespace in the built-in classes. The Flex framework written in AS3 uses namespaces extensively. C++ programmers use a different but related kind of namespace all the time.

Waldemar's original proposal had namespaces as a cross-cutting versioning tool:


is worth a read if you haven't looked at his entire original proposal (he mailed a tarball out recently).

Perhaps more important than any of this, the existing practice among JS (Ajax) libraries uses namespaces, but allows unqualified import in various ways to populate more properties of the importing scope object with shorthands. With this optional importing comes greater risk of name collision. But it sure looks a lot like ES4's 'use namespace MochiKit' or 'use namespace dojo'. It looks like unqualified import.

/be

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Mark S. Miller-2
On Mon, May 26, 2008 at 2:45 PM, Brendan Eich <[hidden email]> wrote:
> In that case, it would still help if you had an argument based on ES4
> premises that led to a simpler ES4. But it would be sillly to repeat ES3
> premises as disqualifying a part of ES4, since they're different evolutions
> of ES3 with different design goals based on different premises.


I find this sudden discussion of premises bizarre. In any case, if
you'll recall how we got here:



On Mon, May 19, 2008 at 4:32 PM, Douglas Crockford
<[hidden email]> wrote:
> These essential features will be added without
> resorting to new syntax.

> On Mon, May 19, 2008 at 4:46 PM, Brendan Eich <[hidden email]> wrote:
>> New syntax is what's needed to make these usable.

On Mon, May 19, 2008 at 6:54 PM, Mark Miller <[hidden email]> wrote:
> I agree that it would be nice to have better syntactic conveniences
> for some of these features. I also agree that the ES4 syntax has some
> decent conveniences. Given the inescapable legacy compatibility
> constraints, it's amazing how well they turned out; kudos! If I could
> have a language with some of the syntactic conveniences of ES4 but
> without ES4's semantics, I'd be quite happy.

2008/5/19 Brendan Eich <[hidden email]>:
> What semantics in particular, can you pick on something specific that's not
> in your classes as sugar proposal (rather than have me guess)? BTW, since
> you missed the cuts in the spreadsheet, you may have missed the optional
> type checker being cut too: 'use strict' is good-taste mode, a la Perl and
> in accord with discussions we've had at the last two TC39 meetings.
> Thanks for the kind words, although since neither 3.1 nor 4 is done yet,
> specific constructive criticism is even better.


That is a reasonable request which I appreciate. I am attempting to do
so, rather than argue from supposed ES4 premises.



On Mon, May 19, 2008 at 6:54 PM, Mark Miller <[hidden email]> wrote:
> From prior discussions, I don't believe it's possible to
> find something in the middle that we can all agree on -- though I
> would still like to!


If the various camps define incompatible positions as premises, then
we may as well give up all hope of agreeing on very much. But a wise
person once said something like

  In mathematics, we justify theorems by derivation from axioms.
  But as mathematicians, we judge axioms based on what theorems
  they produce.

(I think it may have been Karl Popper, but I have been unable to find
anything by searching. Any pointers would be appreciated.)

Rather than proceeding from premises, let's continue to argue about
goals, tradeoffs and taste. Despite everything, I remain hopeful that
we may find ourselves agreeing on more than the current state of the
argument would suggest. From your reasonable request, and from your
citing the history of cuts to date, I hoped you felt likewise. I hope
you still do.

--
    Cheers,
    --MarkM
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 26, 2008, at 6:53 PM, Mark S. Miller wrote:

> On Mon, May 26, 2008 at 2:45 PM, Brendan Eich <[hidden email]>  
> wrote:
>> In that case, it would still help if you had an argument based on ES4
>> premises that led to a simpler ES4. But it would be sillly to  
>> repeat ES3
>> premises as disqualifying a part of ES4, since they're different  
>> evolutions
>> of ES3 with different design goals based on different premises.
>
> I find this sudden discussion of premises bizarre.

Bizarre or not, it's apparently necessary, since you accused me of  
assuming a conclusion, when I was questioning a premise.  
Demonstrating my counter-claim required some statement of that premise.

I then thought to allow as how it's not shared by ES3.1, but I really  
don't know. ES3.1 has no notion of namespace. This spun-out thread  
"Namespaces as Sugar" might be a proposal aimed at 3.1 that's mean to  
show no need for ES4's namespace semantics, but it does not address  
the "unqualified import" use-case, which requires new semantics in  
ES4 not in ES3 or ES3.1. We need to agree or disagree that this use-
case matters enough to justify the extra semantics.

I hope it's clear now why I'm breaking down premises, beyond  
demurring from your assertion that I assumed a conclusion. I'm still  
waiting to hear you reject as unnecessary the unqualified import  
facility, which is found in many languages -- and not just in their  
module systems.


> In any case, if
> you'll recall how we got here:

I recall well, but thanks for diagramming most (but not all!) of the  
thread.


> On Mon, May 19, 2008 at 4:32 PM, Douglas Crockford
> <[hidden email]> wrote:
>> These essential features will be added without
>> resorting to new syntax.

Context is missing here. Why? "These" is a pronoun referring not to  
namespaces, but to other features missing from ES3. Here's the  
context you omitted:

Brendan Eich wrote:

> On Mar 26, 2008, at 10:01 AM, Ric Johnson wrote:
>
>
>> Let us take action instead of throwing opinions around:
>> Brendan: What new features that can not be implemented via code
>> constructs now?
>>
>
> This is reductionism, therefore between silly and wrong, but I will  
> list
> a few things:
>
> * you can't make read-only properties in ES3;
>
> *you can't make don't-delete properties of plain old objects (only  
> vars
> in closures);
>
> * you can't make objects that cannot be extended;
>
> * you can't make don't-enum properties in plain old objects;
>

Doug then replied:

> It looks like these omissions will be corrected in ES3.1 by the
> Object.defineProperties function. These essential features will be  
> added without
> resorting to new syntax.


which links up to the first line you quoted in the thread ("These  
essential features ....").

Where in any of this were namespaces and unqualified import  
discussed? Nowhere.

The issues that I argued deserve syntax to be usable may have  
semantics in ES3.1 now, so you can argue (and you have, indeed,  
argued) for desugaring classes or their fixed properties, e.g. (To  
which I counter-argued that desugaring requires a source to source  
compiler like GWT, which not everyone should have to use to get the  
sugar. But that is another thread that died off.)

But nowhere above in my list to which Doug replied are namespaces to  
be found. So new semantics as well as syntax may be needed, depending  
on what use-cases we think are important. And I'm arguing that  
unqualified-import is important.


> If the various camps define incompatible positions as premises, then
> we may as well give up all hope of agreeing on very much.

A premise can be a conclusion from a prior major premise, plus a  
minor premise (or other style of reasoning than syllogistic). I think  
you're mixing up axiom and premise here. Aha!


> But a wise person once said something like
>
>   In mathematics, we justify theorems by derivation from axioms.
>   But as mathematicians, we judge axioms based on what theorems
>   they produce.
>
> (I think it may have been Karl Popper, but I have been unable to find
> anything by searching. Any pointers would be appreciated.)

Hey, I like Popper too -- but our struggle is not a stand-off between  
contradictory axioms, rather it's a search for the axioms (self-
evident propositions) that are the root premises from which we've  
both reasoned to other premises, and then to conclusions in the form  
of pragmas like "use namespace N".

You switched from "premise" to "axiom" by hauling a Popper quote in,  
but premise != axiom, so we are still not engaging at the level of  
axioms. ES3.1 and ES4 contain conclusions from derived premises that  
are themselves conclusions of prior premises, etc., going back in a  
chain of reasoning to axioms.

That's why I keep raising usability as an issue. Without "unqualified  
import" (Oliver Steele's phrase) or "use namespace N" in ES4 terms,  
experience with other languages leads to the conclusion that  
namespaces that must be explicitly qualified on every use are not  
usable. That's a premise for the further reasoning that has resulted  
in ES4 namespaces, the name lookup algorithm, etc.


> Rather than proceeding from premises, let's continue to argue about
> goals, tradeoffs and taste.

Sorry, those are shifting sands. Let's try to get back toward some  
shared premises, if not toward Mathematical axioms, without dying of  
boredom from all the fine-grained logic chopping. After all, we are  
starting from ES3, and we have lots of experience with programming  
languages in the literature to guide us.

We can appeal to good taste too, but I claim it's much more important  
to pay attention to experience. Let's leave Popper alone and get very  
concrete here. Have you used XML namespaces in compound documents  
with lots of names drawn from two or more vocabularies? It hurts!

/be

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Maciej Stachowiak
In reply to this post by Brendan Eich-2

On May 26, 2008, at 2:45 PM, Brendan Eich wrote:
There are many use-cases. Consider the ES4 spec and Reference Implementation, which segregate helper and informative methods from normative ones in the public namespace in the built-in classes. The Flex framework written in AS3 uses namespaces extensively. C++ programmers use a different but related kind of namespace all the time.

C++ does not have namespacing of class members, or anything resembling it as far as I can tell. Namespaces in C++ are only a top-level construct, as in many other languages. Many good frameworks have been written in languages that only support top-level namespaces, not namespacing of properties or data members or whatever is the local equivalent.

Waldemar's original proposal had namespaces as a cross-cutting versioning tool:


is worth a read if you haven't looked at his entire original proposal (he mailed a tarball out recently).

Perhaps more important than any of this, the existing practice among JS (Ajax) libraries uses namespaces, but allows unqualified import in various ways to populate more properties of the importing scope object with shorthands. With this optional importing comes greater risk of name collision. But it sure looks a lot like ES4's 'use namespace MochiKit' or 'use namespace dojo'. It looks like unqualified import.

But this is just unqualified import of a top-level namespace, not of property namespaces, right? I'm not sure property namespacing is as critical to programming in the large as top-level namespacing.

 - Maciej


_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 26, 2008, at 11:30 PM, Maciej Stachowiak wrote:

> On May 26, 2008, at 2:45 PM, Brendan Eich wrote:
>> There are many use-cases. Consider the ES4 spec and Reference  
>> Implementation, which segregate helper and informative methods  
>> from normative ones in the public namespace in the built-in  
>> classes. The Flex framework written in AS3 uses namespaces  
>> extensively. C++ programmers use a different but related kind of  
>> namespace all the time.
>
> C++ does not have namespacing of class members, or anything  
> resembling it as far as I can tell. Namespaces in C++ are only a  
> top-level construct, as in many other languages. Many good  
> frameworks have been written in languages that only support top-
> level namespaces, not namespacing of properties or data members or  
> whatever is the local equivalent.

All true -- hence "different but related" -- the ability to cut  
across definitions with a single namespace in ES4 is a big one. But  
the point for this thread is the usability of unqualified import,  
which C++ supports and Mark's desugaring sketch does not, even at top  
level only.


>> Perhaps more important than any of this, the existing practice  
>> among JS (Ajax) libraries uses namespaces, but allows unqualified  
>> import in various ways to populate more properties of the  
>> importing scope object with shorthands. With this optional  
>> importing comes greater risk of name collision. But it sure looks  
>> a lot like ES4's 'use namespace MochiKit' or 'use namespace dojo'.  
>> It looks like unqualified import.
>
> But this is just unqualified import of a top-level namespace, not  
> of property namespaces, right?

Right.


> I'm not sure property namespacing is as critical to programming in  
> the large as top-level namespacing.

The top-level in ES is an object containing properties, so there's  
not much difference. Class objects, ad-hoc object, and the global  
object all benefit from cross-cutting namespaces in ES4, and in  
precursors such as AS3. Whether this is worth the cost is for another  
thread. Again my point is the importance of unqualified import for  
usability.

/be
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Maciej Stachowiak

On May 26, 2008, at 11:39 PM, Brendan Eich wrote:

> On May 26, 2008, at 11:30 PM, Maciej Stachowiak wrote:
>
>> On May 26, 2008, at 2:45 PM, Brendan Eich wrote:
>>> There are many use-cases. Consider the ES4 spec and Reference  
>>> Implementation, which segregate helper and informative methods  
>>> from normative ones in the public namespace in the built-in  
>>> classes. The Flex framework written in AS3 uses namespaces  
>>> extensively. C++ programmers use a different but related kind of  
>>> namespace all the time.
>>
>> C++ does not have namespacing of class members, or anything  
>> resembling it as far as I can tell. Namespaces in C++ are only a  
>> top-level construct, as in many other languages. Many good  
>> frameworks have been written in languages that only support top-
>> level namespaces, not namespacing of properties or data members or  
>> whatever is the local equivalent.
>
> All true -- hence "different but related" -- the ability to cut  
> across definitions with a single namespace in ES4 is a big one. But  
> the point for this thread is the usability of unqualified import,  
> which C++ supports and Mark's desugaring sketch does not, even at  
> top level only.

Actually, in this instance you were answering Mark's question: "What's  
the compelling need for a single object to simultaneously have  
properties defined in different namespaces?" Nothing to do with  
unqualified import per se (which I agree is important for top-level  
namespaces at least).

One can certainly question the need for any namespacing of object  
properties, let alone unqualified import of namespaces for such  
purposes.

>
>>> Perhaps more important than any of this, the existing practice  
>>> among JS (Ajax) libraries uses namespaces, but allows unqualified  
>>> import in various ways to populate more properties of the  
>>> importing scope object with shorthands. With this optional  
>>> importing comes greater risk of name collision. But it sure looks  
>>> a lot like ES4's 'use namespace MochiKit' or 'use namespace dojo'.  
>>> It looks like unqualified import.
>>
>> But this is just unqualified import of a top-level namespace, not  
>> of property namespaces, right?
>
> Right.
>
>
>> I'm not sure property namespacing is as critical to programming in  
>> the large as top-level namespacing.
>
> The top-level in ES is an object containing properties, so there's  
> not much difference. Class objects, ad-hoc object, and the global  
> object all benefit from cross-cutting namespaces in ES4, and in  
> precursors such as AS3. Whether this is worth the cost is for  
> another thread. Again my point is the importance of unqualified  
> import for usability.

Object property lookup need not be the same as scope chain lookup and  
it is ok by me if some global properties can only be accessed  
unqualified via the scope chain and not by direct global property  
access. The fact that the global namespace is also an object is cute  
but does not mean namespaces need to generalize beyond the global  
scope. For example, global unqualified namespace import could desugar  
(logically) into the injection of scope chain items instead of into a  
general property lookup mechanism.

Regards,
Maciej

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
On May 27, 2008, at 12:00 AM, Maciej Stachowiak wrote:

Actually, in this instance you were answering Mark's question: "What's  
the compelling need for a single object to simultaneously have  
properties defined in different namespaces?"

I wrote "There are many use-cases" and talked about two: name collision avoidance, unqualified import. In the course of this, I cited C++. C++ doesn't have "objects as scopes" or "properties", but if it did, then the top-level could be a single object with properties in several namespaces. And C++ does support "properties" (globals) with the same unqualified identifier but different namespaces -- and C++ does support unqualified import.

So C++ namespaces are not the same as ES4 namespaces -- I never said they were (more the reverse)! The points, plural, that I was making (yes, I was going beyond Mark's question -- I'm not a deposed witness being interrogated here, so excuse me for talking about more than what was asked) apply to both C++ and ES4.


One can certainly question the need for any namespacing of object  
properties, let alone unqualified import of namespaces for such  
purposes.

I hope so. I'd rather have someone question unqualified import than implicitly dismiss it, which is what seems to be happening.


The top-level in ES is an object containing properties, so there's  
not much difference. Class objects, ad-hoc object, and the global  
object all benefit from cross-cutting namespaces in ES4, and in  
precursors such as AS3. Whether this is worth the cost is for  
another thread. Again my point is the importance of unqualified  
import for usability.

Object property lookup need not be the same as scope chain lookup and  
it is ok by me if some global properties can only be accessed  
unqualified via the scope chain and not by direct global property  
access. The fact that the global namespace is also an object is cute  

Fundamental to JS, impossible to change in ES3-compatible areas, and -- here we may disagree -- unwise to turn away from for future additions to ES3.


but does not mean namespaces need to generalize beyond the global  
scope. For example, global unqualified namespace import could desugar  
(logically) into the injection of scope chain items instead of into a  
general property lookup mechanism.

That's an interesting idea, although we use namespace qualification along the prototype chain all over the place in ES4, and for what seem like good reasons.

ES (any version) has objects as scopes, as well as prototypes. It's hard to keep the gander -- objects below the top level, or on the prototype chain -- from wanting the same sauce that the goose -- the global object -- is trying to hog all to itself.

Objects and their properties move around over time, both along the scope and prototype chains. Real web apps I've studied from a low-level actually take advantage of the ability to "pun" objects along both chains (including the global object).

Also, JS hackers often prototype in global code and then push things down into closures or sub-objects.

Then there is the namespaces-for-versioning idea, which wants to cut across classes as well as global objects.

I'm not going to belabor the general argument for uniformity that favors namespaces as qualifiers usable in all objects that can reach the given namespace by reference (if it's opaque) or use it by name (if transparent), because it is a generalization. We have many and specific use-cases in ES4 (intrinsic, iterator, helper, informative come to mind) for sub-global namespacing. We've generalized, instead of making ad-hoc or particular and restrictive solutions.

Is the cost too high? I think that depends on how the name lookup algorithm works on real-world code. AS3 developers have data to share. Let's get into that.

/be


_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
In reply to this post by Brendan Eich-2
On May 26, 2008, at 10:19 PM, Brendan Eich wrote:

> I then thought to allow as how it's not shared by ES3.1, but I really
> don't know. ES3.1 has no notion of namespace. This spun-out thread
> "Namespaces as Sugar" might be a proposal aimed at 3.1 that's meant to
> show no need for ES4's namespace semantics, but it does not address
> the "unqualified import" use-case, which requires new semantics in
> ES4 not in ES3 or ES3.1. We need to agree or disagree that this use-
> case matters enough to justify the extra semantics.

I'm still not sure why namespaces keep coming up for ES3.1. This  
started in April 2007, with an idea to treat obj["ns::prop"] as the  
same as obj.ns::prop in ES4 -- this makes obj.ns::prop not just a  
syntactic shorthand, and it reinterprets ES1-3 property names  
incompatibly. See the minutes I cited earlier in this thread.

There was a strong "no new syntax" principle in effect for 3.1 at the  
time. Soon enough this idea evolved to allow that some new syntax  
might be a good thing, so maybe obj.ns::prop and some kind of first-
class namespace (denoted ns in the example) could be added. Users  
targeting all browsers would have to use obj["ns::prop"], but when  
ES3-only browsers dropped from servers' user-agent radar, scripts on  
those servers could start using obj.ns::prop.

Now it seems you are exploring desugaring part, but not all, of ES4  
namespaces to ES3 semantics, with a little sugar and some convention  
(or other) for property naming, but no first-class namespace object,  
so no internal namespaces -- rather, injection attacks -- and no  
unqualified import.

Exploring is fine, don't let me discourage you. I don't mean to  
complain. But I hope there's no mission creep going on for ES3.1 that  
would try to add primitives (the fewest possible) for every new  
facility in ES4 not in ES3.1. That is a good way to delay 3.1 and 4,  
and multiple design by committee (if not square it, per Metcalfe's Law).

Keep 3.1 small. That's my motto, and Doug's too I'm sure. Sound right?

/be
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Mark S. Miller-2
On Tue, May 27, 2008 at 12:48 AM, Brendan Eich <[hidden email]> wrote:
> Exploring is fine, don't let me discourage you. I don't mean to complain.
> But I hope there's no mission creep going on for ES3.1 that would try to add
> primitives (the fewest possible) for every new facility in ES4 not in ES3.1.
> That is a good way to delay 3.1 and 4, and multiple design by committee (if
> not square it, per Metcalfe's Law).
>
> Keep 3.1 small. That's my motto, and Doug's too I'm sure. Sound right?


Yes, agreed. Namespaces-as-Sugar (hereafter NAS) is too big for ES3.1.
Perhaps it's too small for ES4. Again, it is simply my attempt to
explain what I meant by "A language with some of ES4's syntactic
conveniences but without ES4's semantics." I would be less happy with
NAS added to a language than with nothing added -- the problem it
addresses is a problem more in theory than in practice. The real
problem in practice is module linkage. Dojo and YUI show that this is
already adequately solved with patterns and libraries, with no new
language mechanism needed.

As I stated, I expect the current truce between the camps -- resulting
in two successor languages -- is probably the best we can do. It's
certainly a lot better than the previous stalemate. But I'm still
curious and hopeful whether a "language with some of ES4's syntactic
conveniences but without ES4's semantics" might be an intermediate
point we could get all around agreement on. Probably not, but it is
worth asking.

--
    Cheers,
    --MarkM
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Maciej Stachowiak
In reply to this post by Brendan Eich-2

On May 27, 2008, at 12:33 AM, Brendan Eich wrote:
On May 27, 2008, at 12:00 AM, Maciej Stachowiak wrote:

Actually, in this instance you were answering Mark's question: "What's  
the compelling need for a single object to simultaneously have  
properties defined in different namespaces?"

I wrote "There are many use-cases" and talked about two: name collision avoidance, unqualified import. In the course of this, I cited C++. C++ doesn't have "objects as scopes" or "properties", but if it did, then the top-level could be a single object with properties in several namespaces. And C++ does support "properties" (globals) with the same unqualified identifier but different namespaces -- and C++ does support unqualified import.

So C++ namespaces are not the same as ES4 namespaces -- I never said they were (more the reverse)! The points, plural, that I was making (yes, I was going beyond Mark's question -- I'm not a deposed witness being interrogated here, so excuse me for talking about more than what was asked) apply to both C++ and ES4.

I don't see how any of this argues for namespacing of properties on non-global objects, or why that case in particular requires unqualified import. 


One can certainly question the need for any namespacing of object  
properties, let alone unqualified import of namespaces for such  
purposes.

I hope so. I'd rather have someone question unqualified import than implicitly dismiss it, which is what seems to be happening.

I don't see how your statement is responsive. Namespacing of non-object properties is poorly justified, in my opinion. Unqualified import of top-level names is well-justified. I don't see why you keep mixing the two together.



The top-level in ES is an object containing properties, so there's  
not much difference. Class objects, ad-hoc object, and the global  
object all benefit from cross-cutting namespaces in ES4, and in  
precursors such as AS3. Whether this is worth the cost is for  
another thread. Again my point is the importance of unqualified  
import for usability.

Object property lookup need not be the same as scope chain lookup and  
it is ok by me if some global properties can only be accessed  
unqualified via the scope chain and not by direct global property  
access. The fact that the global namespace is also an object is cute  

Fundamental to JS, impossible to change in ES3-compatible areas, and -- here we may disagree -- unwise to turn away from for future additions to ES3.

I don't disagree, the global object is reified so unlike activations it cannot be treated as just a convenient spec fiction and nor can it safely be removed.


but does not mean namespaces need to generalize beyond the global  
scope. For example, global unqualified namespace import could desugar  
(logically) into the injection of scope chain items instead of into a  
general property lookup mechanism.

That's an interesting idea, although we use namespace qualification along the prototype chain all over the place in ES4, and for what seem like good reasons.

Other languages with successful namespacing features don't have such a mechanism, so I am dubious of the goodness of these ideas. I am concerned that the namespace lookup algorithm for object property access is too complicated. It makes object property lookup depend on the set of open namespaces, which means obj.property may compile to entirely different code depending on the context, and it seems likely it will slow down property lookup when multiple namespaces are open but static type info is missing. If the only real justification is that it's a nice generalization, then I do not think it is worth the performance hit.


ES (any version) has objects as scopes, as well as prototypes. It's hard to keep the gander -- objects below the top level, or on the prototype chain -- from wanting the same sauce that the goose -- the global object -- is trying to hog all to itself.

Is it really? Is there any other language where namespacing of the global namespace has led to namespacing at the sub-object level? C++, Java and Python all get by fine without namespacing of individual object properties.

The reason namespacing at top level is essential to programming in the large is that the global namespace is a shared resource and must be partitioned in controlled ways to avoid collision in a large system. But I do not see how this argument applies to classes or objects.

Objects and their properties move around over time, both along the scope and prototype chains. Real web apps I've studied from a low-level actually take advantage of the ability to "pun" objects along both chains (including the global object).

Nontheless, the global namespace is unique. There's no way to replace the global object.


Also, JS hackers often prototype in global code and then push things down into closures or sub-objects.

Then there is the namespaces-for-versioning idea, which wants to cut across classes as well as global objects.

I'm not going to belabor the general argument for uniformity that favors namespaces as qualifiers usable in all objects that can reach the given namespace by reference (if it's opaque) or use it by name (if transparent), because it is a generalization. We have many and specific use-cases in ES4 (intrinsic, iterator, helper, informative come to mind) for sub-global namespacing. We've generalized, instead of making ad-hoc or particular and restrictive solutions.

The fact that the generalization seems to be unique to ES4 makes me dubious of its actual usefulness. If it has a performance cost, then the generalization seems like a dubious choice.

Is the cost too high? I think that depends on how the name lookup algorithm works on real-world code. AS3 developers have data to share. Let's get into that.

I'd love to hear the data. AS3 developers, can unqualified lookup of object properties on untyped references in the presence of property namespaces be as fast as when there aren't namespaces at all? If so, how? The most obvious way to do property lookup when there is no static type info is a hashtable lookup on each prototype chain entry, but I do not see an obvious way that a single hashtable lookup can look in multiple namespaces. I suspect the answer to this in AS3 is that if you want performance, you have to use type declarations.

Regards,
Maciej




_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Erik Arvidsson
In reply to this post by Mark S. Miller-2
On Tue, May 27, 2008 at 07:32, Mark S. Miller <[hidden email]> wrote:
> Yes, agreed. Namespaces-as-Sugar (hereafter NAS) is too big for ES3.1.
> Perhaps it's too small for ES4. Again, it is simply my attempt to
> explain what I meant by "A language with some of ES4's syntactic
> conveniences but without ES4's semantics." I would be less happy with
> NAS added to a language than with nothing added -- the problem it
> addresses is a problem more in theory than in practice. The real
> problem in practice is module linkage. Dojo and YUI show that this is
> already adequately solved with patterns and libraries, with no new
> language mechanism needed.

This is the second time I hear you say that the namespace pattern used
by dojo and YUI is already adequate.  Let me debunk that myth.  Dojo
flattened their namespaces from things like dojo.foo.bar.baz to
dojo.baz since the ES3 namespace pattern is too vefrbose and painful
to use.  YUI people also complain that writing YAHOO.foo is painful
(all caps is hard to type).

Unqualified import of global objects is a must for programming at large.

I agree with Maciej here, if we can simplify the name lookup
significantly be removing unqualified import of property names then I
think we should do that.  That being said, having namespaced
properties seems useful and I'd rather have that if it can be made to
perform well as well as be made simpler to understand.

--
erik
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Brendan Eich-2
In reply to this post by Maciej Stachowiak
On May 27, 2008, at 8:45 AM, Maciej Stachowiak wrote:

I don't see how any of this argues for namespacing of properties on non-global objects, or why that case in particular requires unqualified import.

The topic was any single object, so if these are good for the global object, they may (not must) be good for other objects. That's the general (uniformity) argument, made further below (I'm hoping for a response).


One can certainly question the need for any namespacing of object  
properties, let alone unqualified import of namespaces for such  
purposes.

I hope so. I'd rather have someone question unqualified import than implicitly dismiss it, which is what seems to be happening.

I don't see how your statement is responsive.

Hey, I was agreeing with you (Mr. Assistant District Attorney Sir :-P). Questioning is fine.

What was "responsive" about your non-sequitur "One can certainly question the need ..." anyway? No one objects to asking clear questions that are not of the "when did you stop beating your wife" kind.

What's at issue is whether and why unqualified import matters in any object, even the global object only, since the NAS proposal did not allow unqualified import even at global level, and the use-case for unqualified import was dismissed as not compelling.


Namespacing of non-object properties is poorly justified, in my opinion. Unqualified import of top-level names is well-justified. I don't see why you keep mixing the two together.

Sure you do, below where I gave particulars that led to the generalized namespace scheme in ES4.


but does not mean namespaces need to generalize beyond the global  
scope. For example, global unqualified namespace import could desugar  
(logically) into the injection of scope chain items instead of into a  
general property lookup mechanism.

That's an interesting idea, although we use namespace qualification along the prototype chain all over the place in ES4, and for what seem like good reasons.

Other languages with successful namespacing features don't have such a mechanism, so I am dubious of the goodness of these ideas. I am concerned that the namespace lookup algorithm for object property access is too complicated.

Agreed, this is the big issue. I share your concern, but the conservative approach (esp. with reference to C++) of throwing out non-global open namespaces looks like an overreaction, and it may not save much complexity.


It makes object property lookup depend on the set of open namespaces, which means obj.property may compile to entirely different code depending on the context,

Lexical context, no dynamic open-namespaces scope.


and it seems likely it will slow down property lookup when multiple namespaces are open but static type info is missing.

It certainly could, although we think not in implementations under way. Opening multiple namespaces without is not free in a dynamic language.

Is the name lookup algorithm much simpler if namespaces are top-level only? Since obj.prop could end up with obj referring to the (or I should write "a") global object, I don't see it. Unless you're proposing outlawing such object references using the namespaces open at top-level when obj is the global object.


If the only real justification is that it's a nice generalization, then I do not think it is worth the performance hit.

The nice generalization followed from particular use-cases, it did not precede them. I cited those cases (briefly). How about being responsive to them?


ES (any version) has objects as scopes, as well as prototypes. It's hard to keep the gander -- objects below the top level, or on the prototype chain -- from wanting the same sauce that the goose -- the global object -- is trying to hog all to itself.

Is it really? Is there any other language where namespacing of the global namespace has led to namespacing at the sub-object level? C++, Java and Python all get by fine without namespacing of individual object properties.

C++ and Java are not the right paradigms for JS/ES. Python is better, but Python *does* allow import in local scope.


The reason namespacing at top level is essential to programming in the large is that the global namespace is a shared resource and must be partitioned in controlled ways to avoid collision in a large system. But I do not see how this argument applies to classes or objects.

See Mark's big post, which discusses (in item (b)) extending objects, including standard ones.

Saying the global object is a shared resource that must be partitioned, etc., but no others reachable from it, particularly class objects, are shared resources, is begging the question: what makes any object a shared resource? That the global is the only necessarily shared object does not reduce the benefit, or make the cost prohibitive, of sharing other objects reachable from it.

Prototype (the Ajax library) may have erred in extending standard object prototypes. But if it had namespaces as proposed in ES4, and control over enumerability, then why not? Then there are non-prototype standard objects that can be (and are, in JS1/ES3 code today) shared and extended, with possibly conflicting names.

Anyway, it seems we're beating around the bush still. Responding to the particular reasons for generalized namespaces would be better than asserting that the global object is the only shared resource, simply because it must be shared.


Objects and their properties move around over time, both along the scope and prototype chains. Real web apps I've studied from a low-level actually take advantage of the ability to "pun" objects along both chains (including the global object).

Nontheless, the global namespace is unique. There's no way to replace the global object.

You're right, but that does not mean programmers should have to partition only the global object with namespaces or anything like them. The global object is the first object to come to mind, but not the only, and Prototype along with lots of other (library or ad-hoc) JS code on the web shows the utility of extending non-global objects.

I do not mean to oversell this point, since Ajax hackers have swerved away from Prototype-like extension. But that swerving is focused on standard prototypes, especially Object.prototype, and it depends also on the inability to prevent for-in enumeration. It is not reason for confining namespacing to the global object, any more than Prototype is proof that we *must* allow namespacing at any level in the object hierarchy.

The arguments so far are not going to make or break namespaces as proposed, by themselves. Moving along:


Also, JS hackers often prototype in global code and then push things down into closures or sub-objects.

Then there is the namespaces-for-versioning idea, which wants to cut across classes as well as global objects.

I'm not going to belabor the general argument for uniformity that favors namespaces as qualifiers usable in all objects that can reach the given namespace by reference (if it's opaque) or use it by name (if transparent), because it is a generalization. We have many and specific use-cases in ES4 (intrinsic, iterator, helper, informative come to mind) for sub-global namespacing. We've generalized, instead of making ad-hoc or particular and restrictive solutions.

The fact that the generalization seems to be unique to ES4 makes me dubious of its actual usefulness. If it has a performance cost, then the generalization seems like a dubious choice.

First, performance is not king or JS would not have prototypes and dynamic typing. It's not a trump card.

Second (after all the warm-up sparring), you didn't respond to the particulars that led to the generalization:

* internal namespace per compilation unit for information hiding -- hardcode as a special case?
* iterator and meta hooks in objects. Ugly __get__, etc., names instead?
* helper_foo() and informative_bar() in the RI?

The use of __ brackets is a problem for rewriting systems like Caja. Whitelisting standard __hook__ names could work, but is this really the best we can do? I doubt it.


Is the cost too high? I think that depends on how the name lookup algorithm works on real-world code. AS3 developers have data to share. Let's get into that.

I'd love to hear the data. AS3 developers, can unqualified lookup of object properties on untyped references in the presence of property namespaces be as fast as when there aren't namespaces at all? If so, how? The most obvious way to do property lookup when there is no static type info is a hashtable lookup on each prototype chain entry, but I do not see an obvious way that a single hashtable lookup can look in multiple namespaces.

Competitively optimizing JS, excluding namespaces, increasingly requires non-obvious implementation techniques.

This is a good trade-off if it can be done in reasonable footprint, since there is a huge installed base, and a pretty-big knowledge base. We're not, for example, going to remove the ability to replace String.prototype.charAt, in any compatible ESn version.

Optimization ease is not and should not be the sole consideration. Exotic techniques should not be mandated by the spec, on the other hand. But without 'use namespace N' pragmas, programmers will not run into ambiguities at compile time, that result in run-time cost.

Programmers can buy by the yard here, as with other parts of the language that trade performance (or alternatively: that fuel demand for more optimized runtimes) in exchange for expressiveness. And for a lot of JS code, core language performance does not matter even if you go nuts with eval and 'with', compared to other costs dominating the critical paths.


I suspect the answer to this in AS3 is that if you want performance, you have to use type declarations.

That may be the case for AS3 code using Flex, but even such a result would be informative -- don't open multiple namespaces if you're using untyped objects and targeting an unoptimized implementation.

But really, why is any of the several feature combinations that could hurt performance (with, eval, deep scope chains and prototype chains in most implementations) a reason to cripple the language? Performance is not king, and JS ain't C++.

/be

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Maciej Stachowiak

On May 27, 2008, at 11:00 AM, Brendan Eich wrote:
What's at issue is whether and why unqualified import matters in any object, even the global object only, since the NAS proposal did not allow unqualified import even at global level, and the use-case for unqualified import was dismissed as not compelling.

There's really 4 separable issues:

1) Namespacing of names at global scope (via lexically scoped reference).
2) Unqualified import of names into global scope.
3) Namespacing of arbitrary object properties.
4) Unqualified import of namespaces for arbitrary object properties.

I would claim 1 and 2 are essential, 3 can be done by convention in the absence of 4 (a la the NAS proposal) and 4 is unnecessary and harmful to performance.

That's an interesting idea, although we use namespace qualification along the prototype chain all over the place in ES4, and for what seem like good reasons.

Other languages with successful namespacing features don't have such a mechanism, so I am dubious of the goodness of these ideas. I am concerned that the namespace lookup algorithm for object property access is too complicated.

Agreed, this is the big issue. I share your concern, but the conservative approach (esp. with reference to C++) of throwing out non-global open namespaces looks like an overreaction, and it may not save much complexity.

It could save a lot of complexity, by not requiring any first-class support for namespace lookup on arbitrary objects.

It makes object property lookup depend on the set of open namespaces, which means obj.property may compile to entirely different code depending on the context,

Lexical context, no dynamic open-namespaces scope.

Note I said "compile to" so I think this was clear.


and it seems likely it will slow down property lookup when multiple namespaces are open but static type info is missing.

It certainly could, although we think not in implementations under way. Opening multiple namespaces without is not free in a dynamic language.

Is the name lookup algorithm much simpler if namespaces are top-level only? Since obj.prop could end up with obj referring to the (or I should write "a") global object, I don't see it. Unless you're proposing outlawing such object references using the namespaces open at top-level when obj is the global object.

I would propose that unqualified import only affects lexically scoped lookups, not object property access, even if the object in question is the global object. In particular, if you are willing to say "global.property" instead of "property", it is not such a hardship to say "global.ns::property".


If the only real justification is that it's a nice generalization, then I do not think it is worth the performance hit.

The nice generalization followed from particular use-cases, it did not precede them. I cited those cases (briefly). How about being responsive to them?

I think many (perhaps all) of those cases either use namespaces gratuitously or work fine without unqualified import (and so could use namespaces by convention). For example it doesn't seem important to allow unqualified import of the meta namespace. 



ES (any version) has objects as scopes, as well as prototypes. It's hard to keep the gander -- objects below the top level, or on the prototype chain -- from wanting the same sauce that the goose -- the global object -- is trying to hog all to itself.

Is it really? Is there any other language where namespacing of the global namespace has led to namespacing at the sub-object level? C++, Java and Python all get by fine without namespacing of individual object properties.

C++ and Java are not the right paradigms for JS/ES. Python is better, but Python *does* allow import in local scope.

Python allows import from inside a local namespace, but does it allow import from outside a local namespace to affect lookup into that namespace? I am not aware of such a feature but I'm not a Python expert.


The reason namespacing at top level is essential to programming in the large is that the global namespace is a shared resource and must be partitioned in controlled ways to avoid collision in a large system. But I do not see how this argument applies to classes or objects.

See Mark's big post, which discusses (in item (b)) extending objects, including standard ones.

Saying the global object is a shared resource that must be partitioned, etc., but no others reachable from it, particularly class objects, are shared resources, is begging the question: what makes any object a shared resource? That the global is the only necessarily shared object does not reduce the benefit, or make the cost prohibitive, of sharing other objects reachable from it.

The benefit is less, because you can use separate objects in different namespaces instead of a shared object with namespaces inside it. The cost is greater because it makes all property lookup more expensive.

The fact that the generalization seems to be unique to ES4 makes me dubious of its actual usefulness. If it has a performance cost, then the generalization seems like a dubious choice.

First, performance is not king or JS would not have prototypes and dynamic typing. It's not a trump card.

JS does have many features that are not good for performance. But that does not mean we should add more.


Second (after all the warm-up sparring), you didn't respond to the particulars that led to the generalization:

* internal namespace per compilation unit for information hiding -- hardcode as a special case?

I'm not sure how this applies to unqualified import of namespaces on arbitrary object properties.

* iterator and meta hooks in objects. Ugly __get__, etc., names instead?

Unqualified import is not necessary for iterator or meta hooks. Namespaces by convention (or __decoratedNames__) would be enough.

* helper_foo() and informative_bar() in the RI?

I don't think any language feature should exist solely for the convenience of the RI.


The use of __ brackets is a problem for rewriting systems like Caja. Whitelisting standard __hook__ names could work, but is this really the best we can do? I doubt it.


Is the cost too high? I think that depends on how the name lookup algorithm works on real-world code. AS3 developers have data to share. Let's get into that.

I'd love to hear the data. AS3 developers, can unqualified lookup of object properties on untyped references in the presence of property namespaces be as fast as when there aren't namespaces at all? If so, how? The most obvious way to do property lookup when there is no static type info is a hashtable lookup on each prototype chain entry, but I do not see an obvious way that a single hashtable lookup can look in multiple namespaces.

Competitively optimizing JS, excluding namespaces, increasingly requires non-obvious implementation techniques.

For that very reason, it is a very bad idea to add features that intrinsically require non-obvious implementation techniques to get decent performance. If more effort must be spent the necessary complexity of the language just to preserve current levels of performance, then that takes away resources from implementing unnecessary complexity to improve performance beyond current levels.

In general, keeping the language simpler is good for performance. Other things being equal, simpler implementations are easier to change, and have more room to add complexity for optimization without becoming too complex for human understanding.

I will agree that some added language features are essential but I think minor improvements in expressiveness that have large complexity cost are a poor tradeoff.

This is a good trade-off if it can be done in reasonable footprint, since there is a huge installed base, and a pretty-big knowledge base. We're not, for example, going to remove the ability to replace String.prototype.charAt, in any compatible ESn version.

Preserving compatibility with existing performance-harming features is not the same thing as introducing new ones. 

Optimization ease is not and should not be the sole consideration. Exotic techniques should not be mandated by the spec, on the other hand. But without 'use namespace N' pragmas, programmers will not run into ambiguities at compile time, that result in run-time cost.

Programmers can buy by the yard here, as with other parts of the language that trade performance (or alternatively: that fuel demand for more optimized runtimes) in exchange for expressiveness. And for a lot of JS code, core language performance does not matter even if you go nuts with eval and 'with', compared to other costs dominating the critical paths.

Programmers have found ways to live with today's performance, and it is true that for some applications core language performance is not the bottleneck. But that doesn't mean we can feel free to ignore performance considerations in the design of new language features. 



I suspect the answer to this in AS3 is that if you want performance, you have to use type declarations.

That may be the case for AS3 code using Flex, but even such a result would be informative -- don't open multiple namespaces if you're using untyped objects and targeting an unoptimized implementation.

But really, why is any of the several feature combinations that could hurt performance (with, eval, deep scope chains and prototype chains in most implementations) a reason to cripple the language? Performance is not king, and JS ain't C++.

Is removing unqualified import of namespaces at non-global scope (the only aspect of namespaces that seems prima facie harmful to performance) really "crippling the language"?

Regards,
Maciej



_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

Mike Shaver
2008/5/27 Maciej Stachowiak <[hidden email]>:
> It could save a lot of complexity, by not requiring any first-class support
> for namespace lookup on arbitrary objects.

Is the expectation then that having two lookup models, one for global
objects and the other for non-global objects, going to provide less
complexity?

In a browser, "window" is the global object; would property lookup on
"window" be namespaced when referenced as such?  When you have a
handle to another window?  When you use |this.prop| in a global
function?

If we have namespace-aware lookup, it seems to me that it would be
less complex for implementors and script authors alike for it to
always apply, rather than just for one magical object.

Mike
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Namespaces as Sugar (was: complexity tax)

ihab.awad
Delurk to ask a question --

On Tue, May 27, 2008 at 12:18 PM, Mike Shaver <[hidden email]> wrote:
> In a browser, "window" is the global object; would property lookup on
> "window" be namespaced when referenced as such?  When you have a
> handle to another window?  When you use |this.prop| in a global
> function?

What is wrong with the following strawman syntax: Define a form --

  import into <target> values <namespace>;

which puts all the values <namespace>.* into <target>. This can be
explained in terms of two first class objects, <target> and
<namespace>. Now the global case is just a matter of defining an alias
for the global <target>, in case it is not mentionable by a given JS
environment. Like maybe --

  import values <namespace>;

The remainder of the asymmetry, where the global lexical scope is
addressable as an object yet nested scopes are not mentionable as
first-class objects, is endemic to JavaScript and perhaps not a valid
topic of debate or change at this point.

This seems to solve the problem for module linkage, yet does not
introduce complexities in general purpose object key lookup. It can be
modeled simply as an addition of (possibly "virtual") keys to an
object. And it (correctly) requires the client to have write access to
the <target>.

The problem occurs if you wish to fail "late" in case two namespaces
define the same name. This is where the keys can be virtualized so
that, at lookup time, an error occurs if a name is ambiguous. Yet this
is still localized to one first-class object resolving string keys to
first-class object values, which is well within the simple programmer
model of existing JS.

Ihab

--
Ihab A.B. Awad, Palo Alto, CA
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
12