Re: New private names proposal

2010-12-21 Thread Brendan Eich
[Resending as you did to the right group, although I filter both to the same 
folder and prune dups. Whee! /be]

On Dec 21, 2010, at 10:22 PM, David-Sarah Hopwood wrote:

> On 2010-12-21 22:12, Brendan Eich wrote:
>> On Dec 20, 2010, at 11:05 PM, David-Sarah Hopwood wrote:
> 
> Please retain all relevant attribution lines.

Oops, sorry about that.

But really, lighten up. I don't think anyone mixed up your words for mine.


>>> Brendan Eich wrote:
 The new equivalence under private names would be x[#.id] === x.id.
> 
> You said "under private names" here, but it should actually be
> "under the syntax proposed for private names".

Didn't I propose separating "private x" syntax two messages ago (but after I 
wrote the cited bit you snip here), and repeat that request last message? Argh.


> It applies to that
> syntax with either the soft fields or private names semantics.

No. #.id does not apply to soft fields.


>>> ... which is strictly weaker, more complex, and less explanatory.
>> 
>> So is a transposed get from an inherited soft field. Soft fields change the
>> way square brackets work in JS, for Pete's sake!
> 
> They do not.

Ok, then I'm arguing with someone else on that point. But I still believe 
apples-to-apples comparison means mapping the same syntax to the two different 
semantics.

If the "private x" syntax, without #.id, is supported on soft fields, there's 
still a change to evaluating identifiers on the right of dot and the left of 
colon-in-object-initialisers, which has some complexity cost. This particular 
lexical binding and lookup cost doesn't change whether you use soft field side 
tables or private-named object properties for the value storage. At the very 
bottom of your reply, you return to this point (cited below).


>>> So, what if we want to understand '_._' in terms of existing constructs?
>>> Unfortunately, '#.id' must be primitive; there is nothing else that it
>>> can desugar to because 'private id' does not introduce an ordinary
>>> variable (unlike 'const id_ = SoftField()', say).
>> 
>> SoftField(), #.id -- something new in either case.
> 
> 
> Oh, OK, it obviously doesn't matter what we add to the language, it's
> all the same. Library abstractions, new syntax, major changes in
> semantics, who cares? Something new is something new. Let's just roll
> a bunch of dice and pick proposals at random.
> 

This is sad. You can do better, read what I wrote, model it fairly and respond 
directly.


> Sheesh. A library class, specified in terms of existing language constructs,
> is not the same as a new primitive construct, and does not have the same
> consequences for language complexity.

No, we still disagree. "Executable specifications" have complexity and bugs. 
Weak maps (however harmonious) are complex too. Users who understand properties 
and objects do not generally know about "ephemeron tables". It still seems to 
me (and others who've sounded off) that you are discounting some complexity as 
a starting point for your favored approach, and ignoring the further complexity 
inherent in building library code as spec.


>> And what's this "const id_"? A gensym?
> 
> A possible convention for naming variables holding private names.

Ok. That wasn't clear.


> It doesn't matter, you're picking on details.

I'm trying to understand what you wrote!

We are all detail-oriented here, no need to take offense all of a sudden. You 
yourself always wield a fine-toothed comb on details ;-).


>> It's tiresome to argue by special pleading that one extension or
>> transformation (including generated symbols) is "more complex, and less
>> explanatory", while another is less so, when the judgment is completely
>> subjective. And the absolutism about how it's *always* better in every
>> instance to use strong encapsulation is, well, absolutist (i.e., wrong).
> 
> I gave clear technical arguments in that post. If you want to disagree with
> them, disagree with specific arguments, rather than painting me as an
> absolutist. (I'm not.)

Here's a quote: "As you can probably tell, I'm not much impressed by this 
counterargument. It's a viewpoint that favours short-termism and code that 
works by accident, rather than code that reliably works by design."

How do you expect anyone to respond? By endorsing bugs or programming based on 
partial knowledge and incomplete understanding? Yet the real world doesn't 
leave us the option to be perfect very often. This is what I mean by absolutism.

Weak encapsulation is defensible. It's not inherently wrong in all settings. 
When prototyping, weak or even no encapsulation is often the right thing, but 
you have to be careful with prototypes that get pressed into products too 
quickly (I should know). JS is used to prototype all the time.

Ok, of course prototypers need not use any of these facilities. But (it 
shouldn't surprise you to hear) I think prototype builders would benefit from 
very convenient private field support of some kind. Dave said 

Re: New private names proposal

2010-12-21 Thread Kam Kasravi
Caja is a good example of looking at the ramifications of freezing objects 
especially related to the DOM.
MarkM (and others) could comment on its impacts. For YUI 2.8 - there were some 
problems when 
Yahoo cajoled the library, but I believe less than expected. We had some app 
breakage for 3rd party 
apps that were cajoled for open social as well.

Would extending the descriptor in Object.defineProperty(obj, prop, descriptor) 
to provide 
a meta-value for private field be less confusing to the user?
- where the descriptor could be extended in have a field of visible or private?

{value: 'foo', private: true}

though it doesn't make much sense to have

{value:'foo',private:true,enumerable:true,writable:true} 

in which case an exception could be thrown about incompatible descriptor 
values...




From: Brendan Eich 
To: Alex Russell 
Cc: es-discuss@mozilla.org
Sent: Tue, December 21, 2010 10:40:59 PM
Subject: Re: New private names proposal

On Dec 21, 2010, at 10:17 PM, Alex Russell wrote:

> On Dec 21, 2010, at 10:14 PM, Brendan Eich wrote:
> 
> I fear APIs that freeze, only take frozen objects or only have versions that 
>do, or are so mutability-hostile that they warp our use of the language toward 
>frozen-by-default constructs. Those are the sorts of things that spread it.

Spread it how, pray tell?

Putting Object.create/freeze/etc. in ES5 (let's leave aside the API design 
errors that people debate) does not create a wolf in the fold, or a runaway 
water crystallization threat. No coercive entity forces developers to use any 
of 
the freezy bits here.

You think TC39 will make APIs that only work with frozen objects? Or HTML5 or 
Web Apps in the w3c? There's no evidence for this fear, no obvious way these 
APIs could be deployed in a mixed-browser version market, and plenty of 
evidence 
that developers -- both web and browser -- would reject such attempts. I know a 
bunch of us at Mozilla would.

I think we've gone way off the technical beam here. There are valid uses for 
immutability, in building systems that have safety and parallelization 
properties. That's a fact. We're not going to reject freeze from JS just out of 
fear that someone might become Dr. Freeze. If that happens, call Batman. 
Better: 
be Batman.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Private names use cases

2010-12-21 Thread David-Sarah Hopwood
On 2010-12-21 18:20, Allen Wirfs-Brock wrote:
> Even if this style did become the norm, I don't see why you would argue in
> support of mechanisms that allow extension of frozen objects.  Isn't the
> whole point of freezing to prevent any extensions.  why is the fact that
> the extension is accomplished using a side-channel any more acceptable to you.

That's straightforward: adding an association to an object in a side table
in no way breaks the encapsulation of that object. (If it did, then WeakMaps
or any simulation of them would also break encapsulation, which is not the
case.)

Note on terminology: a "side channel" is a channel by which sensitive
information is unintentionally leaked from some operation to potential
attackers. This has no relation to a "side table".

>> Note that I emphasized "properties" rather than a new concept such as 
>> "private fields".
>> I believe we should be trying to build upon the conceptual foundation of the 
>> existing
>> JavaScript object model whenever possible. We should strive to avoid 
>> introducing new
>> concepts such as non-property fields into the object model.  (see
>> http://www.wirfs-brock.com/allen/posts/43  for further thoughts on this 
>> topic.)
>>
>> I find this latter point and your elaboration on that web page bizarre. It 
>> is the
>> private names proposal that would change the object model, even if you 
>> consider
>> these changes minor. The soft fields proposal does not change the object 
>> model
>> at all. It has the semantics of a side table.
> 
> I am speaking of the object model, as perceived to by a JavaScript programmer 
> of
> moderate skill and also by JavaScript implementors.

This is already problematic. The object model is defined by the spec, not by
what any particular programmer or implementor perceives.

Soft fields would not extend the object model as defined by the spec at all.
That is an objective statement independent of anyone's perceptions.

What a JavaScript programmer of moderate skill will perceive depends on
how the feature is explained to them. A good explanation will say both that
soft field slots can be viewed as entries in a side table, and that they can
be viewed as being stored "with" the key object (and that the latter is
likely to be closer to the truth in an optimized implementation, modulo any
pointer indirections).

(A minority -- but an important minority -- of programmers will read the spec
itself, which will give the side table view normatively, and the other view
in a nonnormative NOTE. Other programmers will read interpretations of the
spec. Writers of such interpretations will not be able to miss that there
are two views; it is possible that they will oversimplify or give bad
explanations, but there is not much we can do about that, other than comment
on them.)

JS implementors can also be expected to know both views and translate between
them as necessary.

> To me, an incremental extension of a concept that is already present 
> (extending
> the set of values that can be used as a property name) is a much smaller
> extension to the object model than the introduction of a new form of per
> object state (whether called a private field, a soft field, or something 
> else).

It can be viewed as a form of per-object state, but it's not anything
fundamentally "new" that could not be implemented (perhaps inefficiently) in
ES5 + WeakMap, or even just ES5.

> The fact that you are proposing implementing you object extension as a 
> look-aside
> table

But that is completely backwards! Mark is proposing to *specify* the extension
that way. Specifications do not dictate implementation.

> doesn't mean it isn't a conceptual extension to the object model perceived by
> JavaScript programmers.

The soft field abstraction is a library feature.

This library feature may, if we decide to do so, be supported by syntax.

The syntax may be what is currently proposed in the private names proposal,
or something else.

The syntax proposed in the private names proposal requires extensions to
the object model.

Clearly, this does not imply that the soft field abstraction by itself
requires extensions to the object model. The combination of the soft field
abstraction and the private names syntax does, because the private names
syntax does by itself.

> That might arguably be the case if you were simply defining a set of 
> conventions
> based upon Ephemeron tables for decorating objects with additional 
> non-encapsulated
> state.  However, as soon as you tie into either the language's property 
> access syntax
> ( . and []) as you have (perhaps reluctantly) proposed you have extended the
> conceptual object model.

Mark has criticized that syntax partly because it depends on extending the
object model, and so have I. I intend to propose an alternative syntax, but
I'll do that in another post/thread.

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com



signature.asc
Description: OpenPGP digital signature
_

Re: New private names proposal

2010-12-21 Thread David Flanagan

Brendan wrote:

>   use private cachedHotness;

We have that kind of syntax reserved for pragmas:


I know, and that is why I threw it out there.  To me, this kind of 
messing around with the meaning of identifiers feels like a compile-time 
thing, not a runtime thing...  Allen's proposal treats "private" like 
"var" and "const", and it makes me uneasy because it seems as if there 
is something deeply non-parallel there. More below, but for now, I 
withdraw the "use private" suggestion.


On 12/21/2010 07:33 PM, Allen Wirfs-Brock wrote:

My request to anyone who wants some sort of private object state access is:  
propose the syntax you want to use.


Okay.  I've read the strawman now, and I'm ready to make a sketchy proposal:

What we do currently for weak encapsulation (where currently weak means 
advisory only) is prefix our identifiers with underscores. I would like 
it if the private names syntax just made something like this work to 
give us a stronger form of weak encapsulation.  The strawman already 
uses the # character, so let's stick with that.  I propose that if you 
prefix an identifier with #, you get a private name:


var counter = {
   #count: 0;
   next: function() { return this.#count++; }
   reset: function() { this.#count = 0; }
};

This is just what we might write today, but with # instead of _.

In order for this to work you have to abandon the idea of scoped private 
identifiers.  I say: make all private identifiers scoped to the 
compilation unit. Names wouldn't be private within a file or 

Re: New private names proposal [repost]

2010-12-21 Thread David-Sarah Hopwood
On 2010-12-21 22:12, Brendan Eich wrote:
> On Dec 20, 2010, at 11:05 PM, David-Sarah Hopwood wrote:

Please retain all relevant attribution lines.

>> Brendan Eich wrote:
>>> The new equivalence under private names would be x[#.id] === x.id.

You said "under private names" here, but it should actually be
"under the syntax proposed for private names". It applies to that
syntax with either the soft fields or private names semantics.

>> ... which is strictly weaker, more complex, and less explanatory.
> 
> So is a transposed get from an inherited soft field. Soft fields change the
> way square brackets work in JS, for Pete's sake!

They do not.

Again you seem to be confusing the "inherited soft fields" proposal with
the *separate* proposal on desugaring the private name syntax to inherited
soft fields.

The matter at hand is how the proposed syntax changes affect the semantic
equivalences of ECMAScript. I argued against the syntax changes (including
those to the square bracket operator) on that basis. Now you seem to be
arguing as though I supported the syntax changes. To be clear, I do not
support the currently proposed change to how square brackets work in JS,
regardless of whether that change is specified on top of the soft fields
semantics or the private names semantics. I know that some people consider
it to be an improvement in usability, and I disagree that it is sufficient
improvement to justify the increase in language complexity. There may be
alternative syntaxes that obtain a similar or better usability
improvement with a smaller increase in complexity; I hope so.

(One thing is clear to me; driving experts like MarkM away from participating
in syntax discussions is not going to help with that. Please reconsider,
Mark.)

> Talk about more complex and less explanatory. Yes, if you know about weak 
> maps and soft fields, then it follows -- that is a bit too circular, too 
> much assuming the conclusion.

This has absolutely nothing to do with weak maps. We're talking about the
consequences of the syntax changes, on top of either proposal.

[...]
>> So, what if we want to understand '_._' in terms of existing constructs?
>> Unfortunately, '#.id' must be primitive; there is nothing else that it
>> can desugar to because 'private id' does not introduce an ordinary
>> variable (unlike 'const id_ = SoftField()', say).
> 
> SoftField(), #.id -- something new in either case.


Oh, OK, it obviously doesn't matter what we add to the language, it's
all the same. Library abstractions, new syntax, major changes in
semantics, who cares? Something new is something new. Let's just roll
a bunch of dice and pick proposals at random.


Sheesh. A library class, specified in terms of existing language constructs,
is not the same as a new primitive construct, and does not have the same
consequences for language complexity.

> And what's this "const id_"? A gensym?

A possible convention for naming variables holding private names. It doesn't
matter, you're picking on details.

> It's tiresome to argue by special pleading that one extension or
> transformation (including generated symbols) is "more complex, and less
> explanatory", while another is less so, when the judgment is completely
> subjective. And the absolutism about how it's *always* better in every
> instance to use strong encapsulation is, well, absolutist (i.e., wrong).

I gave clear technical arguments in that post. If you want to disagree with
them, disagree with specific arguments, rather than painting me as an
absolutist. (I'm not.)

> We should debate strong vs. weak encapsulation, for sure, and in the other 
> thread you started (thanks for that). But without absolutes based on 
> preferences or judgment calls about trade-offs and economics.

Tell you what, I'll debate based on the things I think are important, and
you debate based on the things you think are important. Agreed?

>> Rather it introduces an element in an entirely new lexically scoped
>> namespace alongside ordinary variables. This is fundamentally more
>> complex than "id", which is just a stringification of the identifier.
> 
> I agree that "private x" adds complexity to the spec.

Good, that's a start.

To be clear, it's not the syntax itself, but the parallel namespace
introduced by 'private x' that I find problematic in terms of both
specification complexity, and conceptual complexity for programmers.

> It adds something to solve a use-case not satisfied by the existing
> language. There's (again) a trade-off, since with this new syntax, the
> use-cases for private names become more usably expressible.

It isn't at all clear that there aren't alternative syntaxes that would
achieve the usability benefit while not being subject to the criticisms
that have been made of the current syntax proposal. Lasse Reichstein posted
some possibilities (_.#_ or _[#_]). The syntax design space has been barely
explored in the discussion so far.

>> The fact that the proposal is entangled with that

Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 10:17 PM, Alex Russell wrote:

> On Dec 21, 2010, at 10:14 PM, Brendan Eich wrote:
> 
> I fear APIs that freeze, only take frozen objects or only have versions that 
> do, or are so mutability-hostile that they warp our use of the language 
> toward frozen-by-default constructs. Those are the sorts of things that 
> spread it.

Spread it how, pray tell?

Putting Object.create/freeze/etc. in ES5 (let's leave aside the API design 
errors that people debate) does not create a wolf in the fold, or a runaway 
water crystallization threat. No coercive entity forces developers to use any 
of the freezy bits here.

You think TC39 will make APIs that only work with frozen objects? Or HTML5 or 
Web Apps in the w3c? There's no evidence for this fear, no obvious way these 
APIs could be deployed in a mixed-browser version market, and plenty of 
evidence that developers -- both web and browser -- would reject such attempts. 
I know a bunch of us at Mozilla would.

I think we've gone way off the technical beam here. There are valid uses for 
immutability, in building systems that have safety and parallelization 
properties. That's a fact. We're not going to reject freeze from JS just out of 
fear that someone might become Dr. Freeze. If that happens, call Batman. 
Better: be Batman.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Alex Russell

On Dec 21, 2010, at 10:14 PM, Brendan Eich wrote:

> On Dec 21, 2010, at 10:03 PM, Alex Russell wrote:
> 
>>> This is not a relevant fear in my view. It's also kind of silly given all 
>>> the open source JS libraries. If someone did over-freeze, you could stop 
>>> using their library, or fork and fix it. Libraries that suck tend to die 
>>> fast.
>> 
>> That's...an *interesting* reading of recent history.
> 
> What recent history? Please cite some specifics.
> 
> ES5 isn't even implemented in final versions of shipping browsers, so overuse 
> of its Object.freeze can't be a historical fact yet.
> 
> 
>>> Mark did bring up freezing primordials recently, and I know that causes 
>>> some "Dr. Freeze" fear (even on this list the other year, from Arv, IIRC).
>> 
>> And from me right this minute.
> 
> What are you afraid of?
> 
> 
>>> Nevertheless, it's simply not credible that we on TC39 will agree to freeze 
>>> primordials in any ECMA-262 edition I can foresee.
>>> 
>>> Sometimes fear is an appropriate reaction. The lamb fears the wolf. When 
>>> some overwhelming force threatens you, be afraid. But there is no Freeze 
>>> Force both willing and able to take over the JS world.
>>> 
>>> We don't need to be afraid of well-used immutability for safety and 
>>> parallelization. Such filter-pipeline architectures do need weak maps or 
>>> better to associate filter-specific fields with shared immutable data.
>> 
>> So long as the application of freezing is restricted to the uses at hand and 
>> doesn't find its way into the drinking water (ice-nine style).
> 
> I've used that metaphor, it is apt when transitively freezing a graph, while 
> developing your freeze-based code.
> 
> As a runaway that freezes the web, forever? C'mon. It's not even plausible as 
> a worm vector, let alone a standardization mistake that developers reject. 
> I'm not sure what we are talking about at this point (I hope not "Cat's 
> Cradle").


I fear APIs that freeze, only take frozen objects or only have versions that 
do, or are so mutability-hostile that they warp our use of the language toward 
frozen-by-default constructs. Those are the sorts of things that spread it.

--
Alex Russell
slightly...@google.com
slightly...@chromium.org
a...@dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 10:03 PM, Alex Russell wrote:

>> This is not a relevant fear in my view. It's also kind of silly given all 
>> the open source JS libraries. If someone did over-freeze, you could stop 
>> using their library, or fork and fix it. Libraries that suck tend to die 
>> fast.
> 
> That's...an *interesting* reading of recent history.

What recent history? Please cite some specifics.

ES5 isn't even implemented in final versions of shipping browsers, so overuse 
of its Object.freeze can't be a historical fact yet.


>> Mark did bring up freezing primordials recently, and I know that causes some 
>> "Dr. Freeze" fear (even on this list the other year, from Arv, IIRC).
> 
> And from me right this minute.

What are you afraid of?


>> Nevertheless, it's simply not credible that we on TC39 will agree to freeze 
>> primordials in any ECMA-262 edition I can foresee.
>> 
>> Sometimes fear is an appropriate reaction. The lamb fears the wolf. When 
>> some overwhelming force threatens you, be afraid. But there is no Freeze 
>> Force both willing and able to take over the JS world.
>> 
>> We don't need to be afraid of well-used immutability for safety and 
>> parallelization. Such filter-pipeline architectures do need weak maps or 
>> better to associate filter-specific fields with shared immutable data.
> 
> So long as the application of freezing is restricted to the uses at hand and 
> doesn't find its way into the drinking water (ice-nine style).

I've used that metaphor, it is apt when transitively freezing a graph, while 
developing your freeze-based code.

As a runaway that freezes the web, forever? C'mon. It's not even plausible as a 
worm vector, let alone a standardization mistake that developers reject. I'm 
not sure what we are talking about at this point (I hope not "Cat's Cradle").

/be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Alex Russell

On Dec 21, 2010, at 9:38 PM, Brendan Eich wrote:

> On Dec 21, 2010, at 8:17 PM, Allen Wirfs-Brock wrote:
> 
>> However, why would you bother freezing your AST nodes in the first place.  
>> JavaScript has a great mechanism for "soft fields" -- it's called 
>> properties. You can even make your base  properties non-configurable if you 
>> want to.  But why make them non-extensible in this situation.
> 
> For safer parallelization: see, e.g., 
> http://www.ics.uci.edu/~franz/Site/pubs-pdf/ICS-TR-07-12.pdf, or its 
> successor: http://www.springerlink.com/content/u16t58805r879263/ (trace-trees 
> of linear SSA, not ASTs, but no matter).
> 
> The pattern is pretty common in compilers these days (rustc, the self-hosted 
> Rust compiler, has an immutable AST; McPeak & Wilkerson's Elsa/Oink tools 
> from UCB, which we at Mozilla used at the start for our C++ static analysis 
> work over four years ago, had an immutable AST). It's not AOP.
> 
> We're looking into data parallel extensions to JS, not anywhere near ready to 
> propose for standardization, but plausible now given the ability to freeze.
> 
> 
>> My sense that this is a great fear of an important segment of the JavaScript 
>> usage community.  That people will start arbitrarily freezing or otherwise 
>> locking down objects resulting in systems that are much less "elastic" then 
>> they are today.
> 
> This is not a relevant fear in my view. It's also kind of silly given all the 
> open source JS libraries. If someone did over-freeze, you could stop using 
> their library, or fork and fix it. Libraries that suck tend to die fast.

That's...an *interesting* reading of recent history.

> Mark did bring up freezing primordials recently, and I know that causes some 
> "Dr. Freeze" fear (even on this list the other year, from Arv, IIRC).

And from me right this minute.

> Nevertheless, it's simply not credible that we on TC39 will agree to freeze 
> primordials in any ECMA-262 edition I can foresee.
> 
> Sometimes fear is an appropriate reaction. The lamb fears the wolf. When some 
> overwhelming force threatens you, be afraid. But there is no Freeze Force 
> both willing and able to take over the JS world.
> 
> We don't need to be afraid of well-used immutability for safety and 
> parallelization. Such filter-pipeline architectures do need weak maps or 
> better to associate filter-specific fields with shared immutable data.

So long as the application of freezing is restricted to the uses at hand and 
doesn't find its way into the drinking water (ice-nine style).

Regards

> This can of course be done explicitly, but the implicit "private x" or (to a 
> lesser extent) the transposed square-bracket access of implicit soft fields, 
> look strictly easier to use, albeit at the price that dherman pointed out: 
> implicit side table access using property syntax is confusing, it makes for a 
> syntax vs. mental model conflict.
> 
> /be
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

--
Alex Russell
slightly...@google.com
slightly...@chromium.org
a...@dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 8:17 PM, Allen Wirfs-Brock wrote:

> However, why would you bother freezing your AST nodes in the first place.  
> JavaScript has a great mechanism for "soft fields" -- it's called properties. 
> You can even make your base  properties non-configurable if you want to.  But 
> why make them non-extensible in this situation.

For safer parallelization: see, e.g., 
http://www.ics.uci.edu/~franz/Site/pubs-pdf/ICS-TR-07-12.pdf, or its successor: 
http://www.springerlink.com/content/u16t58805r879263/ (trace-trees of linear 
SSA, not ASTs, but no matter).

The pattern is pretty common in compilers these days (rustc, the self-hosted 
Rust compiler, has an immutable AST; McPeak & Wilkerson's Elsa/Oink tools from 
UCB, which we at Mozilla used at the start for our C++ static analysis work 
over four years ago, had an immutable AST). It's not AOP.

We're looking into data parallel extensions to JS, not anywhere near ready to 
propose for standardization, but plausible now given the ability to freeze.


> My sense that this is a great fear of an important segment of the JavaScript 
> usage community.  That people will start arbitrarily freezing or otherwise 
> locking down objects resulting in systems that are much less "elastic" then 
> they are today.

This is not a relevant fear in my view. It's also kind of silly given all the 
open source JS libraries. If someone did over-freeze, you could stop using 
their library, or fork and fix it. Libraries that suck tend to die fast.

Mark did bring up freezing primordials recently, and I know that causes some 
"Dr. Freeze" fear (even on this list the other year, from Arv, IIRC). 
Nevertheless, it's simply not credible that we on TC39 will agree to freeze 
primordials in any ECMA-262 edition I can foresee.

Sometimes fear is an appropriate reaction. The lamb fears the wolf. When some 
overwhelming force threatens you, be afraid. But there is no Freeze Force both 
willing and able to take over the JS world.

We don't need to be afraid of well-used immutability for safety and 
parallelization. Such filter-pipeline architectures do need weak maps or better 
to associate filter-specific fields with shared immutable data.

This can of course be done explicitly, but the implicit "private x" or (to a 
lesser extent) the transposed square-bracket access of implicit soft fields, 
look strictly easier to use, albeit at the price that dherman pointed out: 
implicit side table access using property syntax is confusing, it makes for a 
syntax vs. mental model conflict.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Allen Wirfs-Brock

On Dec 21, 2010, at 2:12 PM, Brendan Eich wrote:

> I also see the ocap purity of soft fields, and I like Mark's 
> AST-decorated-sparsely soft fields use-case. But we already have weak maps in 
> harmony:proposals, so one can write such code now, just  at some loss of 
> convenience: without square brackets or (even better) dots for convenient 
> soft-field access expressions.

(I'm not sure where Mark's original AST use case is, or I would have also 
quoted it.)

To me, this use case sounds like a form of aspect oriented programming.  I'm 
not at all sure that AOP support is something we want to add as an additional 
requirement to our designs.  As Brendan points out, if you really want to do 
this, you can use weak maps whose inclusion I strongly support for exactly this 
sort of use case. 

However, why would you bother freezing your AST nodes in the first place.  
JavaScript has a great mechanism for "soft fields" -- it's called properties. 
You can even make your base  properties non-configurable if you want to.  But 
why make them non-extensible in this situation.   My sense that this is a great 
fear of an important segment of the JavaScript usage community.  That people 
will start arbitrarily freezing or otherwise locking down objects resulting in 
systems that are much less "elastic" then they are today.

Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Allen Wirfs-Brock

On Dec 21, 2010, at 4:01 PM, Oliver Hunt wrote:

> function MyAwesomeThing() {
>
> }
> 
> MyAwesomeThing.prototype.myCoolFunction = function() {
>if (!this._myCachedHotness)
>this._myCachedHotness = doExpensiveThing(this)
>return this._myCachedHotness;
> }
> 
> I see this nifty private names feature, and say "cool! now i can make my 
> cache super secret!" and do:
> 
> MyAwesomeThing.prototype.myCoolFunction = function() {
>private cachedHotness;
>if (!this.cachedHotness)
>this.cachedHotness = doExpensiveThing(this)
>return this.cachedHotness;
> }
> 
> I would _expect_ this to work.  That's what the syntax makes me think.  But 
> it won't work because 'cachedHotness' is going to be different on every call 
> (at least to my reading).
> 
> I am not trying to argue that making the above work is impossible -- you just 
> need to use a few closures to get everything into the right place.  But it is 
> contrary to what I might expect or want.

I don't think there is any new issue here we don't already have with things 
like closure captured object state or prototype construction such as:

function awesomeFactory(a,b) {
const awesomeProto = { ...};  //oops, better move this outside of 
awesomeFactory!!
return Object.create(awesomeProto, {a: {value:a}, b: {value:b}});
}

Personally, I think function own (aka static) declarations are a good solution 
to this problem and could be apply equally well to private name declarations.  
However, that's not something that I want to put on the table at this time.

Allen___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Allen Wirfs-Brock

On Dec 21, 2010, at 5:57 PM, Brendan Eich wrote:

>> 
>> A use directive feels vaguely more comfortable here to me.  It makes it 
>> clearer to the programmer that some kind of magic is going on.
>> 
>> But I confess that I haven't actually read Allen's proposal, so take this 
>> with a grain of salt.
> 
> What's generative in JS already? Mutable object "literals":
> 
>  function f() {} // inside the outer myCoolFunction
>  var o = {p:1};
>  var a = [1,2];
>  var r = /hi/;   // thanks to ES5 recognizing reality over ES3
> 
> That suggests the obvious:
> 
>  private cachedHotness = gensym();
> 
> but then the gensym() initializer, which does indeed scream "new generated 
> value here on every evaluation!", becomes both proper notice and (over time) 
> deadwood, boilerplate. Plus, what's gensym calling? Maybe that built-in is 
> shadowed.
> 
> We could try shortening and using a keyword for unambiguous and novel 
> generativity-here notice to readers:
> 
>  private cachedHotness = new;
> 
> I admit, it looks weird. Lose the =, try for special-form syntax like a 
> function declaration uses:
> 
>  private cachedHotness {};
> 
> Does this "look generative"?
> 
> How about a "more special" special form:
> 
>  new private cachedHotness;
> 
> Not generative-looking enough?
> 
> Discussion list fodder, glad we have es-discuss for this stuff.
> 
> /be

This is a useful line of discussion.  Up to this point there has been quite a 
bit of "I don't like the syntax in the private names proposal" but not a lot of 
suggested alternatives.

My request to anyone who wants some sort of private object state access is:  
propose the syntax you want to use.

In doing so, you will have do decide what constraints you are going to impose 
upon yourself.  In the private name proposal, a constraint we imposed was that 
we would only use keywords that were already identified as future reserved 
words in the ES5 spec.  That pretty much left "private" and "protected" as 
usable keywords.  After some private conversations I concluded that "private" 
was probably going to be a better choice than "protected".

How much of the discomfort about the proposed syntax comes form implications 
associated the word "private"?  What if we allowed expansion of the set of 
available keywords.  Would any of the following be more comfortable:

property cachedHotness;
field cachedHotness;
name cachedHotness;

Alternatively, if we eliminated the ability to use dotted access syntax for 
private properties/fields we wouldn't need a declarator for at all.  We could 
get by with something like:
const cachedHotness  = gensym();  //this was new Name() in the original Names 
proposal
const obj = {};
obj[cachedHotness] =  foo.hotness;

This still requires the ToPrivateName extension of the [ ] semantics described 
in the "Accessing Private Names as Values" section of the proposal. It 
eliminates the ability to say obj.cachedHotness and have it mean anything 
related to the value that was gensym'ed.  obj.chachedHotness would always mean 
obj["cachedHotness"] exactly as it does now. It would also eliminate any 
scoping issues related to private names.

However, a consequence of eliminating the private declaration is that we also 
eliminate the obvious way to extend object literals to support private 
properties:
const obj = {
   cachedHotness: foo.hotness//not the same as obj[cachedHotness] =  
foo.hotness; in the above example.
   }

This seems quite undesirable as  I think quite a few of us favor declarative 
object construction using object literals over imperative object construction.

There are a lot of trade-off like this that went into the private names 
proposal.  I'd be happy to see other alternative complete proposals.  I'm also 
happy to talk about the rationale behind each feature of the proposal and to 
consider alternatives.  However, there are a number of inter-related design 
decisions and you can't necessarily change just one of them without impacting 
the others.

Allen



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 5:13 PM, David Flanagan wrote:

> On 12/21/2010 04:25 PM, Brendan Eich wrote:
>> 
>> Why does your expectation differ here compared to the following:
>> 
>> MyAwesomeThing.prototype.myCoolFunction = function() {
>> var cachedHotness = gensym();
>> if (!this[cachedHotness])
>> this[cachedHotness] = doExpensiveThing(this)
>> return this[cachedHotness];
>> }
>> 
>> Is it because |private cachedHotness;| does not "look generative"?
>> 
> 
> I agree with Oliver: the private keyword is going to cause confusion. It 
> looks like it is declaring something, not generating something.

It's a fair objection for sure.

Mark made a different objection in 
http://wiki.ecmascript.org/doku.php?id=strawman:inherited_explicit_soft_fields#can_we_subsume_names:
 "I (MarkM) do not like the sugar proposed for Names, as I think it encourages 
confusion between literal text and lexical lookup."

That is, without private_names, the "p" in the expression |o.p| is literal 
text, not lexically bound as it could be via a prior |private p|. This too is a 
fair objection, not an absolute as Mark's words convey, rather an informed 
opinion given with pretty-clear reason backing it.

So (must remember to say this), thanks to Oliver and Mark for these objections 
(and to David for amplifying).


> A small step toward making the proposed syntax less Java-like (and therefore 
> less likely to cause confusion) might be:
> 
>   use private cachedHotness;

We have that kind of syntax reserved for pragmas:

http://wiki.ecmascript.org/doku.php?id=strawman:pragmas

It seems even less generative, since pragmas are typically compile-time (or 
compile-and-runtime, but at least compile-time).


> A use directive feels vaguely more comfortable here to me.  It makes it 
> clearer to the programmer that some kind of magic is going on.
> 
> But I confess that I haven't actually read Allen's proposal, so take this 
> with a grain of salt.

What's generative in JS already? Mutable object "literals":

  function f() {} // inside the outer myCoolFunction
  var o = {p:1};
  var a = [1,2];
  var r = /hi/;   // thanks to ES5 recognizing reality over ES3

That suggests the obvious:

  private cachedHotness = gensym();

but then the gensym() initializer, which does indeed scream "new generated 
value here on every evaluation!", becomes both proper notice and (over time) 
deadwood, boilerplate. Plus, what's gensym calling? Maybe that built-in is 
shadowed.

We could try shortening and using a keyword for unambiguous and novel 
generativity-here notice to readers:

  private cachedHotness = new;

I admit, it looks weird. Lose the =, try for special-form syntax like a 
function declaration uses:

  private cachedHotness {};

Does this "look generative"?

How about a "more special" special form:

  new private cachedHotness;

Not generative-looking enough?

Discussion list fodder, glad we have es-discuss for this stuff.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 5:09 PM, Oliver Hunt wrote:

> On Dec 21, 2010, at 5:00 PM, Brendan Eich wrote:
> 
>> On Dec 21, 2010, at 4:51 PM, Oliver Hunt wrote:
>> 
 But what is an array index, then? uint32 is not a type in the language. 
 Would proxy[3.14] really pass a double through?
>>> Yes, I would expect no coercion of any non-object.  The reason for 
>>> disallowing objects is safety afaik, those arguments don't apply to 
>>> non-objects.
>>> 
 Array elements are named by a weird uint32 index name, with consequences 
 on 'length' (but only up to 2^32 - 1 for length). I don't think passing 
 the property name through uncoerced helps, unless you assume a normalizing 
 layer above all name-based operations that specializes to index-names per 
 Array's uint32 magic weirdness.
>>> 
>>> And people are welcome to implement those semantics if they so desire.
>> 
>> If engines do not agree on whether 0x as a property name goes 
>> through a proxy get trap as a number and not a string, we have a problem.
>> 
>> Not all engines optimize 0x to the same (uint32) value; some keep it 
>> as a string since it doesn't fit in an int32.
> 
> What does that have to do with anything?  That's an internal implementation 
> detail, not something that is directly observable from js (you can direct 
> indirectly through timing, etc)

It matters to implementors what they might have to convert back to if the 
object is a proxy.

This started because you said "It would solve the problem of communicating 
private names to a proxy and allow efficient array-like implementations." Two 
issues:

1. Some people do *not* want to communicate private names to proxies. Others 
do, but there's no problem in principle, whether private names are a new 
typeof-type or just a built-in object [[Class]]. Your proposal here does 
nothing for the people who object, and doesn't really matter for those in favor 
of leaking private names via proxy handler trap name parameters.

2. "allow efficient array-like implementations" -- not really. Arrays must 
equate "42" and 42, and must update length for indexes in [0, 0xfffe] 
(closed range notation). Other properties must be string-equated. While it 
helps to get 42 instead of "42", it does not help to get 3.14 instead of "3.14" 
if you are implementing an array-like.

You want arbitrary values as identifiers to flow through to the proxy handler 
trap's name param without coercion. But many engines currently *do* coerce, and 
to internal types (not in-language) types.

So either implementations have to use a generic Value type for all property 
names above the per-[[Class]] implementation layer, and coerce only under that 
layer; or else keep their optimized above-the-[[Class]]-layer property-name 
type encodings (using internal types, etc.) and undo the coercion in the Proxy 
(object and function proxy) implementations, to implement what you want.

I don't believe all implementations will re-layer to let values pass through 
uncoerced. This leaves undoing the coercion in proxy trap-calling code, which 
is not only more expensive for "3.14" -> 3.14, it is ambiguous: the original 
type was lost due to coercion, so you're really talking about requiring all 
engines to layer things so property names are never coerced (apart from string 
intern'ing).

I don't see that flying with all implementors, and I don't see it buying 
array-like proxies much. It still looks like overspecification.

To let private names through, we need only enlarge the type of names in 
ECMA-262 from string to (string | private name) as the proposal says. To let 
array indexes through, we might do something similar, but it would not let 3.14 
through as a double.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread David Flanagan

On 12/21/2010 04:25 PM, Brendan Eich wrote:


Why does your expectation differ here compared to the following:

MyAwesomeThing.prototype.myCoolFunction = function() {
var cachedHotness = gensym();
if (!this[cachedHotness])
this[cachedHotness] = doExpensiveThing(this)
return this[cachedHotness];
}

Is it because |private cachedHotness;| does not "look generative"?



I agree with Oliver: the private keyword is going to cause confusion. 
It looks like it is declaring something, not generating something.
A small step toward making the proposed syntax less Java-like (and 
therefore less likely to cause confusion) might be:


   use private cachedHotness;

A use directive feels vaguely more comfortable here to me.  It makes it 
clearer to the programmer that some kind of magic is going on.


But I confess that I haven't actually read Allen's proposal, so take 
this with a grain of salt.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Oliver Hunt

On Dec 21, 2010, at 5:00 PM, Brendan Eich wrote:

> On Dec 21, 2010, at 4:51 PM, Oliver Hunt wrote:
> 
>>> But what is an array index, then? uint32 is not a type in the language. 
>>> Would proxy[3.14] really pass a double through?
>> Yes, I would expect no coercion of any non-object.  The reason for 
>> disallowing objects is safety afaik, those arguments don't apply to 
>> non-objects.
>> 
>>> Array elements are named by a weird uint32 index name, with consequences on 
>>> 'length' (but only up to 2^32 - 1 for length). I don't think passing the 
>>> property name through uncoerced helps, unless you assume a normalizing 
>>> layer above all name-based operations that specializes to index-names per 
>>> Array's uint32 magic weirdness.
>> 
>> And people are welcome to implement those semantics if they so desire.
> 
> If engines do not agree on whether 0x as a property name goes through 
> a proxy get trap as a number and not a string, we have a problem.
> 
> Not all engines optimize 0x to the same (uint32) value; some keep it 
> as a string since it doesn't fit in an int32.

What does that have to do with anything?  That's an internal implementation 
detail, not something that is directly observable from js (you can direct 
indirectly through timing, etc)

>> I just see no reason to artificially limit behaviour.
> 
> The spec must prescribe exactly what is coerced and what is not, or we lose 
> interoperation.

Okay, this and the prior comment indicate that you're missing what I am saying.

I am not suggesting that we expose the internal optimisations for avoiding 
int->string->int.

I am being very precise: anything that is _not_ an object goes is passed 
through with no coercion of any kind.

eg.
assuming the get trap is:
function getTrap(property) {
log(property + ": " + typeof property);
}

myProxy[0] => 0: number
myProxy[1.5] => 1.5: number
myProxy["0"] => 0: string
myProxy[true] => true: boolean
myProxy[undefined] => undefined: undefined
myProxy[null] => null: object // questionable - null is classed as an object 
but i doubt many people actually think of it in that way
myProxy[somePrivateNameThingy] => ???:  // I have no idea what typeof 
privatename or String(privateName) are expected to do

--Oliver


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 4:51 PM, Oliver Hunt wrote:

>> But what is an array index, then? uint32 is not a type in the language. 
>> Would proxy[3.14] really pass a double through?
> Yes, I would expect no coercion of any non-object.  The reason for 
> disallowing objects is safety afaik, those arguments don't apply to 
> non-objects.
> 
>> Array elements are named by a weird uint32 index name, with consequences on 
>> 'length' (but only up to 2^32 - 1 for length). I don't think passing the 
>> property name through uncoerced helps, unless you assume a normalizing layer 
>> above all name-based operations that specializes to index-names per Array's 
>> uint32 magic weirdness.
> 
> And people are welcome to implement those semantics if they so desire.

If engines do not agree on whether 0x as a property name goes through a 
proxy get trap as a number and not a string, we have a problem.

Not all engines optimize 0x to the same (uint32) value; some keep it as 
a string since it doesn't fit in an int32.


> I just see no reason to artificially limit behaviour.

The spec must prescribe exactly what is coerced and what is not, or we lose 
interoperation.

Engines that choose to optimize id to a union of string with int32, e.g., might 
need to change. Some engines use tagged words still, so 31-bit signed int, not 
int32.

It's not clear every implementor will agree. It's also not obvious why the spec 
must dictate implementation here if the performance has been tuned already for 
non-proxy classes, and the results were whatever they were (different among 
implementations, probably; non-standard, definitely). Why should proxies cause 
retuning in some value-neutral way that assumes a certain dynamic frequency of 
id types?

This looks like over-specification.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Oliver Hunt

On Dec 21, 2010, at 4:25 PM, Brendan Eich wrote:

> On Dec 21, 2010, at 4:01 PM, Oliver Hunt wrote:
> 
>> Just giving my feedback to this (so it's recorded somewhere other than my 
>> head).
>> 
>> I find the apparent necessity of conflating syntax and semantics irksome, 
>> i'd much rather that there be two distinct discussions one of syntax and the 
>> other for semantics of soft-fields, private names, gremlins, etc (or 
>> whatever this general concept ends up being called)
>> 
>> That said I don't really like the private names syntax, mostly for reasons 
>> others have bought up already, but one case I don't recall seeing is 
>> something that I think will lead to surprise on the part of developers.  Say 
>> i have a piece of code:
>> 
>> function MyAwesomeThing() {
>>
>> }
>> 
>> MyAwesomeThing.prototype.myCoolFunction = function() {
>>if (!this._myCachedHotness)
>>this._myCachedHotness = doExpensiveThing(this)
>>return this._myCachedHotness;
>> }
>> 
>> I see this nifty private names feature, and say "cool! now i can make my 
>> cache super secret!" and do:
>> 
>> MyAwesomeThing.prototype.myCoolFunction = function() {
>>private cachedHotness;
>>if (!this.cachedHotness)
>>this.cachedHotness = doExpensiveThing(this)
>>return this.cachedHotness;
>> }
>> 
>> I would _expect_ this to work.  That's what the syntax makes me think.  But 
>> it won't work because 'cachedHotness' is going to be different on every call 
>> (at least to my reading).
> 
> Why does your expectation differ here compared to the following:
> 
> MyAwesomeThing.prototype.myCoolFunction = function() {
>var cachedHotness = gensym();
>if (!this[cachedHotness])
>this[cachedHotness] = doExpensiveThing(this)
>return this[cachedHotness];
> }
> 
> Is it because |private cachedHotness;| does not "look generative"?

Yes.  The fact that we know how they are implemented behind the scenes may make 
the non-obvious appear obvious.

> 
> 
>> I am not trying to argue that making the above work is impossible -- you 
>> just need to use a few closures to get everything into the right place.  But 
>> it is contrary to what I might expect or want.
>> 
>> wrt. proxies, I still think that we should just allow all non-objects 
>> property names to transfer through uncoerced.  It would solve the problem of 
>> communicating private names to a proxy and allow efficient array-like 
>> implementations.
> 
> You mean non-string property names, right?

Yes

> 
> But what is an array index, then? uint32 is not a type in the language. Would 
> proxy[3.14] really pass a double through?
Yes, I would expect no coercion of any non-object.  The reason for disallowing 
objects is safety afaik, those arguments don't apply to non-objects.

> 
> Array elements are named by a weird uint32 index name, with consequences on 
> 'length' (but only up to 2^32 - 1 for length). I don't think passing the 
> property name through uncoerced helps, unless you assume a normalizing layer 
> above all name-based operations that specializes to index-names per Array's 
> uint32 magic weirdness.

And people are welcome to implement those semantics if they so desire.  I just 
see no reason to artificially limit behaviour.  Especially when the alternative 
is to say that the argument to the trap "will be a string, except in this case 
that you don't expect".  I think it's better to be consistent and simply allow 
all non-objects through.  This allows better perf for some use cases, and to my 
mind simpler semantics in the face of things like private names.

> /be
--Oliver___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 4:01 PM, Oliver Hunt wrote:

> Just giving my feedback to this (so it's recorded somewhere other than my 
> head).
> 
> I find the apparent necessity of conflating syntax and semantics irksome, i'd 
> much rather that there be two distinct discussions one of syntax and the 
> other for semantics of soft-fields, private names, gremlins, etc (or whatever 
> this general concept ends up being called)
> 
> That said I don't really like the private names syntax, mostly for reasons 
> others have bought up already, but one case I don't recall seeing is 
> something that I think will lead to surprise on the part of developers.  Say 
> i have a piece of code:
> 
> function MyAwesomeThing() {
>
> }
> 
> MyAwesomeThing.prototype.myCoolFunction = function() {
>if (!this._myCachedHotness)
>this._myCachedHotness = doExpensiveThing(this)
>return this._myCachedHotness;
> }
> 
> I see this nifty private names feature, and say "cool! now i can make my 
> cache super secret!" and do:
> 
> MyAwesomeThing.prototype.myCoolFunction = function() {
>private cachedHotness;
>if (!this.cachedHotness)
>this.cachedHotness = doExpensiveThing(this)
>return this.cachedHotness;
> }
> 
> I would _expect_ this to work.  That's what the syntax makes me think.  But 
> it won't work because 'cachedHotness' is going to be different on every call 
> (at least to my reading).

Why does your expectation differ here compared to the following:

MyAwesomeThing.prototype.myCoolFunction = function() {
   var cachedHotness = gensym();
   if (!this[cachedHotness])
   this[cachedHotness] = doExpensiveThing(this)
   return this[cachedHotness];
}

Is it because |private cachedHotness;| does not "look generative"?


> I am not trying to argue that making the above work is impossible -- you just 
> need to use a few closures to get everything into the right place.  But it is 
> contrary to what I might expect or want.
> 
> wrt. proxies, I still think that we should just allow all non-objects 
> property names to transfer through uncoerced.  It would solve the problem of 
> communicating private names to a proxy and allow efficient array-like 
> implementations.

You mean non-string property names, right?

But what is an array index, then? uint32 is not a type in the language. Would 
proxy[3.14] really pass a double through?

Array elements are named by a weird uint32 index name, with consequences on 
'length' (but only up to 2^32 - 1 for length). I don't think passing the 
property name through uncoerced helps, unless you assume a normalizing layer 
above all name-based operations that specializes to index-names per Array's 
uint32 magic weirdness.

/be___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Oliver Hunt
Just giving my feedback to this (so it's recorded somewhere other than my head).

I find the apparent necessity of conflating syntax and semantics irksome, i'd 
much rather that there be two distinct discussions one of syntax and the other 
for semantics of soft-fields, private names, gremlins, etc (or whatever this 
general concept ends up being called)

That said I don't really like the private names syntax, mostly for reasons 
others have bought up already, but one case I don't recall seeing is something 
that I think will lead to surprise on the part of developers.  Say i have a 
piece of code:

function MyAwesomeThing() {

}

MyAwesomeThing.prototype.myCoolFunction = function() {
if (!this._myCachedHotness)
this._myCachedHotness = doExpensiveThing(this)
return this._myCachedHotness;
}

I see this nifty private names feature, and say "cool! now i can make my cache 
super secret!" and do:

MyAwesomeThing.prototype.myCoolFunction = function() {
private cachedHotness;
if (!this.cachedHotness)
this.cachedHotness = doExpensiveThing(this)
return this.cachedHotness;
}

I would _expect_ this to work.  That's what the syntax makes me think.  But it 
won't work because 'cachedHotness' is going to be different on every call (at 
least to my reading).

I am not trying to argue that making the above work is impossible -- you just 
need to use a few closures to get everything into the right place.  But it is 
contrary to what I might expect or want.

wrt. proxies, I still think that we should just allow all non-objects property 
names to transfer through uncoerced.  It would solve the problem of 
communicating private names to a proxy and allow efficient array-like 
implementations.

--Oliver

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: es-discuss Digest, Vol 46, Issue 22

2010-12-21 Thread Brendan Eich
On Dec 21, 2010, at 2:52 PM, thaddee yann tyl wrote:

> I was very interested when I heard about private names. It seems like
> a very good idea. However, the specification that the strawman gives
> is harder than I thought it would be.
> 
> I am unsure I fully understand this _private names_ proposal.
> 
> For starters, what is the "scope" of private names?

This is spec'ed at 
http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declaration_scoping
 to some level of precision:

"private declarations are lexically scoped, like all declarations in Harmony. 
Inner private declarations shadow access to like-named private declarations in 
outer scopes. Within a block, the scoping rules for private declarations are 
the same as for const declarations. "


> eg,
> 
> private name;
> var obj = {};
> obj.name = 5;  // We want obj to have a Private Name value.
> // ... Later on ... (here, we should do something so that the
> // following lines work).
> var foo = {};
> foo.name = {name:'foo'};  // Here, we would like foo to have a
> // property "name" whose value is an object whose name property holds the
> // value "foo".
> // How to do so? Is foo['name'] = {'name':'foo'}; unavoidable; does it
> // even work?
> // Is {name:'foo'} going to contain a Private Name, or rather a
> // property (which is what we want)?

Yes, if you don't close the block scope (even if implicit, top-level script or 
function body scope) then |private name| is still in effect.

If you want {name: 'foo'} to mean {"name": 'foo'}, then either close the block 
scope (open a fresh one first if necessary), or quote the identifier. Same for 
foo.name (foo["name"]).


> Secondly, I am trying to understand what this code does, too:
> a = {};
> k = {a: a};
> a['k'] = k;
> 
> function aa(o) {
>  private a;
>  k.a = o;  // Does it "override" the fact that a is a property?

I don't know what you mean by "override". The private_names strawman is clear 
enough about what happens here. k has a new property named by the private name 
lexically bound to a in function aa, and *not* named by the string "a", created 
by assignment and set to have as its value the value of |o|.


>  a.a = a.k.a;
>  return #.a;
> }
> 
> var a1 = aa(a);
> var a2 = aa(a);  // Does it return the same thing?

No, you get a fresh one per evaluation of the private declaration. See

function Thing() {
private key;   // each invocation will use a new private key value

and related examples from 
http://wiki.ecmascript.org/doku.php?id=strawman:private_names#using_private_identifiers.

As one might hope, you can nest closures to make "class private" vs "instance 
private" names. There's no need for extra keywords or special cases. A private 
declaration is evaluated by generating a new, unique name.


> print(a2);
> print(a1 === a2);

false


> print(typeof a2);

The strawman answers this, but includes words about an alternative design 
wherein private names are built-in objects.


> print(a[a2] === a.k.a);

false

Note that (a[a2] === a.k[a2] && a[a2] === a).

This is all kind of plug-and-chug from my reading of the strawman. Was it 
unclear in a way where you could suggest a fix? Or maybe it just didn't start 
with a minimal statement of the rules.

/be___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: I recuse myself (was: Private names use cases)

2010-12-21 Thread David Herman
> I never said I don't want syntactic support. I said I don't like the syntax 
> you proposed. You and Dave have now both said that you consider this to be 
> the main issue.

Hm, I certainly didn't intend to say that. I'm not quite sure what you're 
referring to that I said. I don't necessarily have a single sine-qua-non in 
this design space. Sorry I haven't been as clear as I should have.

There's a lot going by in this conversation, and I don't want to add too much 
noise, but I do want to emphasize something: the various options we've 
discussed *all* have a syntactic component, even if we separate out the 
|private| syntax. Brendan mentioned this in reply to David-Sarah, but I think 
it's worth repeating: whether in the soft fields approach or the private names 
approach, [] is overloaded in a new way.

Maybe that's the key sticking point for me about the soft fields approach: 
overloading that syntax to mean lookup in a side table is what seems like a 
drastic break from the intuitive model of objects. I have nothing against side 
tables as a programming idiom; it's when you make them look like they aren't 
side tables that they become confusing. Especially when you can do 
counter-intuitive things like add new properties to a frozen object. Of course, 
there are clearly use cases where you want to associate new data with a frozen 
object, and convenience would be helpful. I'm just not convinced that making it 
look like ordinary object lookup is the right programmer-interface. So yes, 
it's a syntax issue, but it's a syntax issue that frames the mental model, and 
I think that matters.

What am I saying with all this? Not sure. I'm disheartened at the level of 
controversy too, but I think it's worth pushing through, because as a JS 
programmer, I really feel the lack of private fields-or-properties (with 
apologies to the English language... trying to remain diplomatic here...) in 
day-to-day programming.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: es-discuss Digest, Vol 46, Issue 22

2010-12-21 Thread thaddee yann tyl
I was very interested when I heard about private names. It seems like
a very good idea. However, the specification that the strawman gives
is harder than I thought it would be.

I am unsure I fully understand this _private names_ proposal.

For starters, what is the "scope" of private names?
eg,

private name;
var obj = {};
obj.name = 5;  // We want obj to have a Private Name value.
// ... Later on ... (here, we should do something so that the
following lines work).
var foo = {};
foo.name = {name:'foo'};  // Here, we would like foo to have a
property "name" whose value is an object whose name property holds the
value "foo".
// How to do so? Is foo['name'] = {'name':'foo'}; unavoidable; does it
even work?
// Is {name:'foo'} going to contain a Private Name, or rather a
property (which is what we want)?


Secondly, I am trying to understand what this code does, too:
a = {};
k = {a: a};
a['k'] = k;

function aa(o) {
  private a;
  k.a = o;  // Does it "override" the fact that a is a property?
  a.a = a.k.a;
  return #.a;
}

var a1 = aa(a);
var a2 = aa(a);  // Does it return the same thing?
print(a2);
print(a1 === a2);
print(typeof a2);
print(a[a2] === a.k.a);


On Tue, Dec 21, 2010 at 9:29 PM,   wrote:
> I am not sure what point you are referring to. Do you mean
>
> 1) Allow JavaScript programmers, who choose to do so, to manage the direct
> accessibly of object *properties*.  This may mean limiting access to methods
> of a particular instance, or to methods of the same "class", or to various
> friends or cohorts, etc.
>
>
> ? Other than terminology, I don't see how the proposals differ in this
> regard. If the issue is that we call the new state " properties"
> so that it seems more familiar, fine.
>
>
>
>> and your argument concerning the second point is based upon an assumption
>> that I don't share regarding a particular "defensive programming" style.
>>
>
> What assumption is that? If the assumption in question is whether "everyone"
> agrees that defensive programming should be "the norm", then I don't share
> that assumption either.
>
>
> --
>    Cheers,
>    --MarkM
> -- next part --
> An HTML attachment was scrubbed...
> URL: 
> <http://mail.mozilla.org/pipermail/es-discuss/attachments/20101221/552d2516/attachment.html>
>
> --
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
> End of es-discuss Digest, Vol 46, Issue 22
> **
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: I recuse myself (was: Private names use cases)

2010-12-21 Thread Allen Wirfs-Brock

On Dec 21, 2010, at 12:39 PM, Mark S. Miller wrote:

> The promised separate email:
> 
> On Tue, Dec 21, 2010 at 10:20 AM, Allen Wirfs-Brock  
> wrote:
> 
> It seems to me, the real point of difference here is whether or not we should 
> add a syntactic mechanism that supports information hiding in the context of 
> JavaScript objects.  Some constituents want this, others do not. 
> 
> 
> I never said I don't want syntactic support. I said I don't like the syntax 
> you proposed. You and Dave have now both said that you consider this to be 
> the main issue. To me it is a minor and separate issue. Were soft fields to 
> be adopted with your syntax, I would consider that to be an overall good 
> outcome.

It wasn't you that I had in mind with the above statement.  I have heard from 
several individuals that they would prefer to have no enforced information 
hiding (or encapsulation if you prefer that terminology).

> 
> From private email, I have even been made aware that my attempts to separate 
> the syntax and semantics debates is perceived by some to be "a trick" to kill 
> both the syntax and semantics of private names. I am shocked and distressed 
> that the level of suspicion is now so high that I must cope with these 
> suspicions. That I am against both does not make insincere my sense that they 
> are orthogonal questions. I will point out that it occurred to me as I was 
> writing those wiki pages that it would be strategic not to reveal my dislike 
> of the syntax until we'd settled the semantics issues. I chose not to do so 
> in order to avoid giving a false impression that I like the syntax. I have 
> been open about my opinions throughout the process.

I do think there are some fundamental differences in both what problems we are 
trying to solve and in our approaches to a solution.  There is probably even 
some frustration about the difficulty we seem to be having in reaching an 
understanding of whether or not we are addressing the same problem.  However, I 
don't question your sincerity  or think any trickery is involved.

> 
> Nevertheless, because such suspicions have arose, and because I consider only 
> the semantics issues crucial, I will recuse myself from further discussion -- 
> either on list or in the meetings -- of the syntax to be associated with this 
> functionality. I will proceed as if we're all in agreement on your syntax and 
> argue only about the semantics.

Please don't totally disengage from the syntax discussion.  Most programmers 
understanding of the language starts with the concrete (syntax) and then 
proceeds to the abstract (semantics).  Syntax design can have a big impact on 
the usability of the underlying semantics

Allen.



> 
> 
> -- 
> Cheers,
> --MarkM

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Brendan Eich
On Dec 20, 2010, at 11:05 PM, David-Sarah Hopwood wrote:

>> The new equivalence under private names would be x[#.id] === x.id.
> 
> ... which is strictly weaker, more complex, and less explanatory.

So is a transposed get from an inherited soft field. Soft fields change the way 
square brackets work in JS, for Pete's sake!

Talk about more complex and less explanatory. Yes, if you know about weak maps 
and soft fields, then it follows -- that is a bit too circular, too much 
assuming the conclusion.

Either way (soft fields vs. private names), something changes from the old 
x["id"] / x.id equivalence.


>  So, what if we want to
> understand '_._' in terms of existing constructs? Unfortunately,
> '#.id' must be primitive; there is nothing else that it can desugar
> to because 'private id' does not introduce an ordinary variable
> (unlike 'const id_ = SoftField()', say).

SoftField(), #.id -- something new in either case. And what's this "const id_"? 
A gensym?

It's tiresome to argue by special pleading that one extension or transformation 
(including generated symbols) is "more complex, and less explanatory", while 
another is less so, when the judgment is completely subjective. And the 
absolutism about how it's *always* better in every instance to use strong 
encapsulation is, well, absolutist (i.e., wrong).

We should debate strong vs. weak encapsulation, for sure, and in the other 
thread you started (thanks for that). But without absolutes based on 
preferences or judgment calls about trade-offs and economics. People differ on 
abstraction leak costs and make different trade-offs in programming all the 
time.


> Rather it introduces an
> element in an entirely new lexically scoped namespace alongside
> ordinary variables. This is fundamentally more complex than "id",
> which is just a stringification of the identifier.

I agree that "private x" adds complexity to the spec. It adds something to 
solve a use-case not satisfied by the existing language. There's (again) a 
trade-off, since with this new syntax, the use-cases for private names become 
more usably expressible.


> The fact that the proposal is entangled with that syntax, so that it is
> difficult to see its semantic consequences separate from the syntax,
> cannot possibly be considered a feature of the proposal, at the meta level
> of the language design process.

Didn't I already agree that it's a good idea to separate "private x" from the 
semantics, since we have a conflict over semantics?

So let's do that (my plea to everyone, not just you). Let's separate "private 
x" syntax, since I now know of a use-case courtesy Mark, and it's a good one (a 
frozen AST being extended sparsely via soft fields) that wants that "private x" 
and the sweet dot operator syntax, but on top of soft fields not private 
property names that require unfrozen objects.


>> The inherited soft fields approach is more entangled with its
>> reference implementation, which is not the efficient route VM
>> implementors can swallow.
> 
> I think you're being rather patronising to VM implementors (including
> yourself!) if you think that they're incapable of understanding 

I wrote "can swalow" not "can understand". "Swallow" and "understand" have 
pretty different connotations.

Mapping from soft fields to something more efficient that VM implementors will 
implement is non-trivial. Requiring all implementors (the primary audience of 
ECMA-262) to do this mapping, each on his or her own, is a bad idea. The spec 
should use formalisms that are not at odds with common implementation. But 
let's wait to hear from more implementors on this point.

In the mean time, how about we quit fencing over matters of taste or trade-offs 
turned into false absolutes, and try to get ahead on semantics: the issues that 
remain even after separating syntax are the abstraction leaks.

With inherited soft fields, the ability to "extend" frozen objects with private 
fields is an abstraction leak (and a feature, I agree).

With inherited soft fields, the transposed get or set magic that changes how 
square brackets work in JS is a leak on the inside of the abstraction. If you 
don't like x[#.id] / x.id supplanting x["id"] / x.id, it seems to me you have 
to count some similar demerits against this change.

With private names as proposed in full, the #.id syntax which can reflect a 
private name as an expression result, including the typeof-type or built-in 
class of a private name, is a definitely both new complexity that makes an 
overt observable difference between soft fields and private names. No such 
operator for soft fields.

The weak encapsulation design points are likewise "leaky" for private names, 
where no such leaks arise with soft fields: reflection and proxies can learn 
private names, they "leak" in the real ocap sense that secure subsets will have 
to plug.

To make progress, we could try to agree on strong encapsulation only. TC39 
works by consensus, meaning general a

I recuse myself (was: Private names use cases)

2010-12-21 Thread Mark S. Miller
The promised separate email:

On Tue, Dec 21, 2010 at 10:20 AM, Allen Wirfs-Brock
wrote:

>
> It seems to me, the real point of difference here is whether or not we
> should add a syntactic mechanism that supports information hiding in the
> context of JavaScript objects.  Some constituents want this, others do not.
>


I never said I don't want syntactic support. I said I don't like the syntax
you proposed. You and Dave have now both said that you consider this to be
the main issue. To me it is a minor and separate issue. Were soft fields to
be adopted with your syntax, I would consider that to be an overall good
outcome.

>From private email, I have even been made aware that my attempts to separate
the syntax and semantics debates is perceived by some to be "a trick" to
kill both the syntax and semantics of private names. I am shocked and
distressed that the level of suspicion is now so high that I must cope with
these suspicions. That I am against both does not make insincere my sense
that they are orthogonal questions. I will point out that it occurred to me
as I was writing those wiki pages that it would be strategic not to reveal
my dislike of the syntax until we'd settled the semantics issues. I chose
not to do so in order to avoid giving a false impression that I like the
syntax. I have been open about my opinions throughout the process.

Nevertheless, because such suspicions have arose, and because I consider
only the semantics issues crucial, I will recuse myself from further
discussion -- either on list or in the meetings -- of the syntax to be
associated with this functionality. I will proceed as if we're all in
agreement on your syntax and argue only about the semantics.


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Private names use cases

2010-12-21 Thread Mark S. Miller
On Tue, Dec 21, 2010 at 10:20 AM, Allen Wirfs-Brock
wrote:

> See below:
>
> On Dec 21, 2010, at 9:03 AM, Mark S. Miller wrote:
>
> On Mon, Dec 20, 2010 at 9:21 AM, Allen Wirfs-Brock 
> wrote:
>
>> I've seen mentions in the recent thread that the goal of the "Private
>> Names" proposal was to support "private fields" for objects.  While that may
>> be a goal of some participants in the discussion, it is not what I would
>> state as the goal.
>>
>> I have two specific use cases in mind for "private names":
>> 1) Allow JavaScript programmers, who choose to do so, to manage the direct
>> accessibly of object *properties*.  This may mean limiting access to
>> methods of a particular instance, or to methods of the same "class", or to
>> various friends or cohorts, etc.
>> 2) Allow third-party *property* extensions to built-in objects or
>> third-party frameworks that are guaranteed to not have naming conflicts
>>  with unrelated extensions to the same objects.
>>
>> Of these two use cases, the second may be the more important.
>>
>
> I'm glad you agree. By incremental fiddling, such as repairing the
> encapsulation leaks of private names, perhaps we could brings these two
> proposals closer together to try to find common ground. However, this second
> use case would still be a real difference. <
> http://wiki.ecmascript.org/doku.php?id=strawman:names_vs_soft_fields#conflict-free_object_extension_using_soft_fields>
> uses your example of this use case. In light of your message, I just added a
> note on the crucial difference:
>
> For defensive programming, best practice in many environments will be to
> freeze the primordials early, as the dual of the existing best practice that
> one should not mutate the primordials. Evaluating the dynamic behaviour of
> Python applications  (See
> also http://gnuu.org/2010/12/13/too-lazy-to-type/) provides evidence that
> this will be compatible with much existing content. We should expect these
> best practices to grow during the time when people feel they can target ES5
> but not yet ES6.
>
> Consider if Object.prototype or Array.prototype were already frozen, as
> they should be, before the code above executes. Using soft fields, this
> extension works. Using private names, it is rejected.
>
>
>
> Not everybody in the JavaScript community agrees that this style of
> defensive programming is desirable or should be a "best practice".
>

How did "best practice in many environments" become a question of
whether "everybody
in the JavaScript community agrees" on this, or indeed anything?



>  On my blog, there was resistance expressed to JavaScript providing any
> sort of information hiding mechanism. I would not anticipate frozen
> primordials becoming the norm anytime soon.
>

How about "a norm"? I can't help feeling that your uses of "everyone" and
"the" is an attempt to (in the pejorative sense) strawman the discussion. I
am claiming only that it will become *a* norm, an important one, and one
that we should strive to support.


>
> Even if this style did become the norm, I don't see why you would argue in
> support of mechanisms that allow extension of frozen objects.  Isn't the
> whole point of freezing to prevent any extensions.
>

No. Let's distinguish two use cases. The point of shallow freezing is to
create a "tamper proof object" (the phrase I've been using in talks). If x
is a tamper proof object given to otherwise isolated subsystems A and B,
then the only interactions between them enabled by giving them x are those
that the author of x chooses to provide. This helps both security and
modularity. As David-Sarah points out, only if the author of x is in control
of what public interface they export can they know what changes they can
make without breaking clients.

Building on this, the point of transitive immutability is to create objects
that can be safely shared between isolated subsystems without thereby giving
them *any* means to interact. With out historic inability to freeze the
primordials (Object.prototype, etc), our only isolation mechanism was the
creation of separate frames. In the browser, separate same-origin frames by
themselves provides no security benefit, but are increasingly used for their
modularity benefit -- to ensure that various complex subsystems do not
interfere with each other. Notice that the clone code, whether expressed
using soft fields or private names, will not succeed at associating default
behavior with objects from other frames. If same-origin frames grows as the
best practice, we both lose.

When we are able to freeze the primordials, and combined with our desire to
remove the global object from the bottom of the scope chain, then we can
arrange to bring separate subsystems into one frame without interference.
Then the soft field clone works but the private names clone does not. The
private names clone *only* works if we bring these all into one frame and
(by not freezing the primor

Re: New private names proposal

2010-12-21 Thread David-Sarah Hopwood
On 2010-12-21 08:49, Lasse Reichstein wrote:
> On Thu, 16 Dec 2010 23:19:12 +0100, Mark S. Miller  wrote:
>> On Thu, Dec 16, 2010 at 1:58 PM, Kris Kowal  wrote:
>>> On Thu, Dec 16, 2010 at 1:53 PM, David Herman  wrote:
>>> >
[...]
>>> > than
>>> >
>>> >function Point(x, y) {
>>> >var _x = gensym(), _y = gensym();
>>> >this[_x] = x;
>>> >this[_y] = y;
>>> >}
>>>
>>> I tend to disagree with most developers, so take it with a grain of
>>> salt that I find the latter form, with all the implied abilities,
>>> easier to understand.
> 
>> I do too. While terseness clearly contributes to understandability,
>> regularity and simplicity do too. When these conflict, we should be very
>> careful about sacrificing regularity.
> 
> While I dislike the "private" syntax just as much, it does have the advantage
> of being statically detectable as using a private name, both "this.foo" in the
> scope of "private foo", and "this[#.foo]".

That's not correct in general, since '#.foo' is first-class. (The specific
case "expr[#.foo]" is more easily optimizable without type inference, but
that's a case in which the #. syntax need not have been used.)

> The "gensym" syntax requires runtime checks to recognize that _x is a 
> non-string
> property name.

Any expr[p] lookup needs a check for whether p is a string, when that cannot
be determined by type inference. The check that it is a private name or
soft field when when it is not a string is on the infrequent path, so will
not significantly affect performance.

>> Currently is JS, x['foo'] and x.foo are precisely identical in all contexts.
>> This regularity helps understandability. The terseness difference above is
>> not an adequate reason to sacrifice it.
> 
> Agree. I would prefer something like x.#foo to make it obvious that it's not 
> the
> same as x.foo (also so you can write both in the same scope), and use
> "var bar = #foo /* or just foo */; x[#bar]" for computed private name lookup.
> I.e. effectively introducing
> ".#", "[#" as alternatives to just "." or "[".

If we're going to add an operator specifically for private lookup, we only
need one, for example:

function Point(x, y) {
var x = SoftField(), y = SoftField();
this.#x = x;
this.#x = y;
}

(i.e. 'MemberExpression .# PrimaryExpression' or alternatively
'MemberExpression [ # Expression ]')

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com



signature.asc
Description: OpenPGP digital signature
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Private names use cases

2010-12-21 Thread Allen Wirfs-Brock
See below:

On Dec 21, 2010, at 9:03 AM, Mark S. Miller wrote:

> On Mon, Dec 20, 2010 at 9:21 AM, Allen Wirfs-Brock  
> wrote:
> I've seen mentions in the recent thread that the goal of the "Private Names" 
> proposal was to support "private fields" for objects.  While that may be a 
> goal of some participants in the discussion, it is not what I would state as 
> the goal.
> 
> I have two specific use cases in mind for "private names":
> 1) Allow JavaScript programmers, who choose to do so, to manage the direct 
> accessibly of object properties.  This may mean limiting access to methods of 
> a particular instance, or to methods of the same "class", or to various 
> friends or cohorts, etc.
> 2) Allow third-party property extensions to built-in objects or third-party 
> frameworks that are guaranteed to not have naming conflicts  with unrelated 
> extensions to the same objects.
> 
> Of these two use cases, the second may be the more important.
> 
> I'm glad you agree. By incremental fiddling, such as repairing the 
> encapsulation leaks of private names, perhaps we could brings these two 
> proposals closer together to try to find common ground. However, this second 
> use case would still be a real difference. 
> 
>  uses your example of this use case. In light of your message, I just added a 
> note on the crucial difference:
> 
> For defensive programming, best practice in many environments will be to 
> freeze the primordials early, as the dual of the existing best practice that 
> one should not mutate the primordials. Evaluating the dynamic behaviour of 
> Python applications (See also http://gnuu.org/2010/12/13/too-lazy-to-type/) 
> provides evidence that this will be compatible with much existing content. We 
> should expect these best practices to grow during the time when people feel 
> they can target ES5 but not yet ES6.
> 
> Consider if Object.prototype or Array.prototype were already frozen, as they 
> should be, before the code above executes. Using soft fields, this extension 
> works. Using private names, it is rejected.
> 
> 

Not everybody in the JavaScript community agrees that this style of defensive 
programming is desirable or should be a "best practice".  On my blog, there was 
resistance expressed to JavaScript providing any sort of information hiding 
mechanism. I would not anticipate frozen primordials becoming the norm anytime 
soon. 

Even if this style did become the norm, I don't see why you would argue in 
support of mechanisms that allow extension of frozen objects.  Isn't the whole 
point of freezing to prevent any extensions.  why is the fact that the 
extension is accomplished using a side-channel any more acceptable to you.


>  
> 
> Note that I emphasized "properties" rather than a new concept such as 
> "private fields".  I believe we should be trying to build upon the conceptual 
> foundation of the existing JavaScript object model whenever possible. We 
> should strive to avoid introducing new concepts such as non-property fields 
> into the object model.  (see http://www.wirfs-brock.com/allen/posts/43  for 
> further thoughts on this topic.)
> 
> I find this latter point and your elaboration on that web page bizarre. It is 
> the private names proposal that would change the object model, even if you 
> consider these changes minor. The soft fields proposal does not change the 
> object model at all. It has the semantics of a side table.

I am speaking of the object model, as perceived to by a JavaScript programmer 
of moderate skill and also by JavaScript implementors.  To me, an incremental 
extension of a concept that is already present (extending the set of values 
that can be used as a property name) is a much smaller extension to the object 
model than the introduction of a new form of per object state (whether called a 
private field, a soft field, or something else).

The fact that you are proposing implementing you object extension as a 
look-aside table doesn't mean it isn't a conceptual extension to the object 
model perceived by JavaScript programmers.  That might arguably be the case if 
you were simply defining a set of conventions based upon Ephemeron tables for 
decorating objects with additional non-encapsulated state.  However, as soon as 
you tie into either the language's property access syntax ( . and []) as you 
have (perhaps reluctantly) proposed you have extended the conceptual object 
model.

It seems to me, the real point of difference here is whether or not we should 
add a syntactic mechanism that supports information hiding in the context of 
JavaScript objects.  Some constituents want this, others do not. 

If you don't care about syntactic support for information hiding than we 
already have solutions. Ephemeron tables provide a side-band mechanisms for 
dynamically associating additional state with an objects.  Y

Re: Announcing ES5.1, final draft

2010-12-21 Thread Allen Wirfs-Brock
The ES5.1 draft has been updated with corrections noted on this lists.  See 
http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_proposal_working_draft  

Thanks to David and David-Sarah for careful reading.

Allen


On Dec 15, 2010, at 10:11 AM, Allen Wirfs-Brock wrote:

> The process for advancing ES5 from an Ecma standard to an ISO standard should 
> be completed in early 2011.  The ISO edition of the specification 
> incorporates a number of editorial and technical corrections including those 
> listed in the current ES5 errata.
> 
> In order to keep the ISO and Ecma specifications in strict alignment, TC39 is 
> preparing a revision to the ES5 spec. whose content is identical to the ISO 
> version. It also includes a new Annex F that lists the technically 
> significant changes incorporated into the revision. This revision will be 
> known as Ecma-262, Edition 5.1.  We'll probably just talk about it as ES5.1.
> 
> The final draft is available from the ecmascript.org 
> wiki:http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_proposal_working_draft
>   
> 
> Note that the ISO version is currently frozen so the only changes  to the 
> ES5.1 draft that can be considered at this time are the content of Annex F or 
> any Ecma-spec boilerplate or formatting issues.
> 
> There are a few ES5 issues that have been discovered subsequent to the ISO 
> spec. freeze and there are undoubtably further errors to be discovered in 
> these new editions.  I will start an ES5.1 errata to track such items.
> 
> Allen
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Private names use cases

2010-12-21 Thread Mark S. Miller
On Mon, Dec 20, 2010 at 9:21 AM, Allen Wirfs-Brock wrote:

> I've seen mentions in the recent thread that the goal of the "Private
> Names" proposal was to support "private fields" for objects.  While that may
> be a goal of some participants in the discussion, it is not what I would
> state as the goal.
>
> I have two specific use cases in mind for "private names":
> 1) Allow JavaScript programmers, who choose to do so, to manage the direct
> accessibly of object *properties*.  This may mean limiting access to
> methods of a particular instance, or to methods of the same "class", or to
> various friends or cohorts, etc.
> 2) Allow third-party *property* extensions to built-in objects or
> third-party frameworks that are guaranteed to not have naming conflicts
>  with unrelated extensions to the same objects.
>
> Of these two use cases, the second may be the more important.
>

I'm glad you agree. By incremental fiddling, such as repairing the
encapsulation leaks of private names, perhaps we could brings these two
proposals closer together to try to find common ground. However, this second
use case would still be a real difference. <
http://wiki.ecmascript.org/doku.php?id=strawman:names_vs_soft_fields#conflict-free_object_extension_using_soft_fields>
uses your example of this use case. In light of your message, I just added a
note on the crucial difference:

For defensive programming, best practice in many environments will be to
freeze the primordials early, as the dual of the existing best practice that
one should not mutate the primordials. Evaluating the dynamic behaviour of
Python applications  (See
also http://gnuu.org/2010/12/13/too-lazy-to-type/) provides evidence that
this will be compatible with much existing content. We should expect these
best practices to grow during the time when people feel they can target ES5
but not yet ES6.

Consider if Object.prototype or Array.prototype were already frozen, as they
should be, before the code above executes. Using soft fields, this extension
works. Using private names, it is rejected.




>
> Note that I emphasized "properties" rather than a new concept such as
> "private fields".  I believe we should be trying to build upon the
> conceptual foundation of the existing JavaScript object model whenever
> possible. We should strive to avoid introducing new concepts such as
> non-property fields into the object model.  (see
> http://www.wirfs-brock.com/allen/posts/43  for further thoughts on this
> topic.)
>

I find this latter point and your elaboration on that web page bizarre. It
is the private names proposal that would change the object model, even if
you consider these changes minor. The soft fields proposal does not change
the object model *at all*. It has the semantics of a side table.

It seems both of your key points in this message support soft fields over
private names.


>
> Allen
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Private names use cases

2010-12-21 Thread Kam Kasravi
Coming from the commonjs perspective I did something similar to create private 
data per instance using a closure. 
I feed an object literal into a 'type' generator so that: 

Type.create('Foo', {
  imports: {
log: "require('log')"
  },
  specification: {
'private': { 
  bar: null, 
  baz: null
},
'constructor': function(props) {
  try {
var properties = props || {};
bar = properties.bar;
  } catch(e) {
log.Logger.error(this,e);
  } 
  return this;
},
'public': { 
  print: function() {
log.Logger.debug(this,'bar='+this.getBar());
  }
} 
  }   
}, require, exports);

generates

// Foo
var Foo = (function() {
  // imports
  var log = require('log');
  // public
  Foo.prototype['print'] = function print() {
log.Logger.debug(this, 'bar=' + this.getBar());
  };
  function Foo() {
// private
function privateData() {
  this.bar = null;
  this.baz = null;
};
var p_vars = new privateData();
var bar = p_vars.bar;
this.getBar = function getBar() {
  return bar;
};  
this.setBar = function setBar(b) {
  bar = b;
  return this;
};
var baz = p_vars.baz;
this.getBaz = function getBaz() {
  return baz;
};  
this.setBaz = function setBaz(b) {
  baz = b;
  return this;
};
// constructor
var args = Array.prototype.slice.call(arguments);
arguments.callee.ctor = function(props) {
  try {
var properties = props || {};
bar = properties.bar;
  } catch(e) {
log.Logger.error(this, e);
  }
  return this;
};
return arguments.callee.ctor.apply(this, args) || this;
  };
  return function() {
var args = Array.prototype.slice.call(arguments);
arguments.callee['constructor'] = Foo;
return new Foo(args && args.length && args[0]);
  };
})();
exports.Foo = Foo;


the object literal looks a little like the object initializer strawman 
(http://wiki.ecmascript.org/doku.php?id=strawman:object_initialiser_extensions).
The idea is the user is shielded from private data lookup when creating an 
object instance.

eg  
Foo({bar:'hello'}).print(); // internally calls new
Foo({bar:'world'}).print();
  


From: Garrett Smith 
To: Allen Wirfs-Brock 
Cc: es-discuss@mozilla.org
Sent: Mon, December 20, 2010 11:28:15 PM
Subject: Re: Private names use cases

On 12/20/10, Allen Wirfs-Brock  wrote:
> I've seen mentions in the recent thread that the goal of the "Private Names"
> proposal was to support "private fields" for objects.  While that may be a
> goal of some participants in the discussion, it is not what I would state as
> the goal.
>
> I have two specific use cases in mind for "private names":
> 1) Allow JavaScript programmers, who choose to do so, to manage the direct
> accessibly of object properties.  This may mean limiting access to methods
> of a particular instance, or to methods of the same "class", or to various
> friends or cohorts, etc.

If private is based on lexical scope then it's already possible but it
can be a bad smell.

For example:

var Blah = function() {
  var privateBlah =  {
complicatedDirtyWork : function() { alert("blah.") }
  };
  var Blah = {
goBang : function() {
  privateBlah.complicatedDirtyWork();
}
  };
  return Blah;
}();
Blah.goBang()

Great for a one-off, but when you wanna have many of the ADT (many
instances of Blah), then there's an equal number of privateBlah and
the strategy must make some sort of lookup, e.g.

  var delegateBlah = getPrivateBlah( this );
  delegateBlah.doTrick();

That's a bit more work and when there are only a couple of fields, it
seems like too much trouble.

If it were authored in a way that obviates that cruft but could still
be facilitated by using scope tricks, as above?
-- 
Garrett
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New private names proposal

2010-12-21 Thread Lasse Reichstein
On Thu, 16 Dec 2010 23:19:12 +0100, Mark S. Miller   
wrote:



On Thu, Dec 16, 2010 at 1:58 PM, Kris Kowal  wrote:

On Thu, Dec 16, 2010 at 1:53 PM, David Herman   
wrote:

>
>function Point(x, y) {
>private x, y;
>this.x = x;
>this.y = y;
>...
>}
>
> than
>
>function Point(x, y) {
>var _x = gensym(), _y = gensym();
>this[_x] = x;
>this[_y] = y;
>}

I tend to disagree with most developers, so take it with a grain of
salt that I find the latter form, with all the implied abilities,
easier to understand.



I do too. While terseness clearly contributes to understandability,
regularity and simplicity do too. When these conflict, we should be very
careful about sacrificing regularity.


While I dislike the "private" syntax just as much, it does have the  
advantage
of being statically detectable as using a private name, both "this.foo" in  
the scope

of "private foo", and "this[#.foo]".
The "gensym" syntax requires runtime checks to recognize that _x is a  
non-string

property name.


Currently is JS, x['foo'] and x.foo are precisely identical in all  
contexts.
This regularity helps understandability. The terseness difference above  
is not an adequate reason to sacrifice it.


Agree. I would prefer something like x.#foo to make it obvious that it's  
not the

same as x.foo (also so you can write both in the same scope), and use
"var bar = #foo /* or just foo */; x[#bar]" for computed private name  
lookup. I.e. effectively introducing

".#", "[#" as alternatives to just "." or "[".

I'm not sure it's better to use an operator to reify the private name  
("#foo") or it being directly

denotable ("foo") in an expression context. Both can be used.
In the latter case, x.#foo and x[#foo] would be equivalent.

/Lasse
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Strong vs weak encapsulation [correction]

2010-12-21 Thread David-Sarah Hopwood
On 2010-12-21 08:27, David-Sarah Hopwood wrote:
> The private names and soft field proposals are similar in the
> visibility mechanisms they can simulate, but soft fields are slightly
> more general. In either proposal, visibility can be restricted to a
> particular lexical scope. In the soft fields proposal, because
> SoftFields are first-class values, it can also be restricted to any
> set of objects that can get access to a given SoftField.

Correction: the #.id syntax also allows private names to be treated as
first-class values, so the proposals are equivalent in this respect.

> I don't
> claim this to be a critical benefit, but it is occasionally
> useful in object-capability programming. For example, in
> ,
> a Purse of a given currency is supposed to be able to access a
> private field of other Purses of the same currency, but not other
> Purses of different currencies. The implementation at
> 
> uses WeakMaps to do this, and could just as well use soft fields

or private names

> if transliterated to ECMAScript.

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com



signature.asc
Description: OpenPGP digital signature
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Strong vs weak encapsulation

2010-12-21 Thread David-Sarah Hopwood
Strong encapsulation means that the code implementing an abstraction can
control the visibility of its fields (i.e. where they can be accessed
from), without any loopholes that can be exploited by code outside the
abstraction's scope. Weak encapsulation allows such loopholes. Note that
I deliberately use the term "fields", in order to avoid the over-
specification that private fields necessarily have to be ECMAScript
properties.

I suggest that we discuss which of these strengths of encapsulation we
want, separately from the choice of how to specify the semantics of
private fields.

In principle there are three possible positions:

a) private fields should always be strongly encapsulated;
b) private fields should be weakly encapsulated;
c) private fields should be strongly encapsulated when a sandbox
   is in effect, and weakly encapsulated if not.

I will be arguing for a) and against both b) and c).

We can analyse this question from the complementary perspectives
of either software engineering or security. The security perspective
is fairly straightforward: weak encapsulation does not provide any
benefit because it can be bypassed by attacking code. c) may be
acceptable, but a) is preferred, so that code not originally written
for use in a sandbox is less likely to fail when run inside one.

From the software engineering perspective, we need any benefits of
encapsulation to be derived even when not running in a sandbox, which
means that b) and c) are roughly equivalent, and the choice is between
those and a):

Weak encapsulation creates a situation where the incentives of the
programmer(s) providing an abstraction are misaligned with the
incentives of the programmer(s) using it. The provider wants to be
able to rely on the encapsulation to prevent clients from depending
on implementation details, so that those details can be changed
compatibly. The client programmers just want their code to work.
The client can (sometimes) get their code to work by breaking the
encapsulation. This is often perceived to be easier than communicating
with the provider in order to get the bug fixed or support the missing
feature.

Some client programmers, faced with such a problem, might refrain from
breaking the encapsulation, even though they could have used it to
work around the problem. In that case, of course, they obtain no
advantage from the encapsulation mechanism being weak. Only clients
who do choose to break the encapsulation obtain any such advantage,
and they do so only at the expense of making their code more fragile
and creating compatibility problems for the provider. The provider
can choose to ignore such problems, but then any client code that
violated encapsulation will be liable to malfunction when it is used
with the new version of the provider's code. (It is possible that any
particular change will not break any particular client, but that would
only be by luck.)

Misaligned incentives do neither party any good.

There are a couple more points that strengthen the above argument:

 - it may be the case that an encapsulation-violating client *appears*
   to work in testing, but actually doesn't in all situations. This is
   quite likely when the client programmers' understanding of the
   provider code is based on reverse-engineering.

 - the ability to break encapsulation as a workaround may create a
   disincentive to reporting the bug or feature request.
   The abstraction is therefore less likely to be changed in a way
   that other users could benefit from.


A possible counterargument goes something like this:

By breaking encapsulation, a client programmer may be able to make
this version of their code work with the *current* version of the
abstraction they are violating. This does have some value (even though
the code is now fragile, and less understandable because the provider
and client code cannot be understood independently).

As you can probably tell, I'm not much impressed by this counterargument.
It's a viewpoint that favours short-termism and code that works by
accident, rather than code that reliably works by design.

Note that in the case where the same programmers are writing the
provided abstraction and its *only* clients, it makes no sense to
use reflection to bypass encapsulation; they might as well make the
field public (or use selective visibility as discussed below).
Doing so would result in clearer code. So weak encapsulation provides
no advantage in this case either.


There's another potential counterargument against the way strong
encapsulation is supported in some (typically class-based) languages,
that may have more merit. It says that a sharp distinction between
"public" and "private", where "private" fields can only be accessed
from within their class definition, can sometimes be insufficiently
expressive. That is, we might want "private" fields to be selectively
accessible from outside the class definition, but not to all code
outside it.

Note, however, that for both th