Even though I wrote it, I don't think the clone example on the Private Names 
pages is very clear so I'll take another trying at explaining the conflict free 
extension use cases.  Just to make sure that we don't confuse things with any 
assumptions about the implicit semantics of a clone operation I'm going to use 
a method named "work" instead of "clone".

#1 A framework writer needs to add a method to object prototype. They use that 
method extensive internally within the framework.They assign a private name 
that they internally reference as 'work' for that method.  They also provide a 
way for client code to access that private name.  

#2 An application developer uses the framework from #1 (let's call it MF).  
They are generally unaware that  MF has added an extension method to 
Object.prototype:
    var MF = InstallMF();
    var thing = MF.getAThing();  //behind the scene calls MF's work method

#3 The application developer for their own good reasons decides to add a method 
named 'work' to Object.prototype. MF internally just keeps working:
    var MF = InstallMF();
    Object.prototype.work = function () { ...};
    var thing = MF.getAThing();    //behind the scene calls MF's work method, 
still works fine
    var appThing = think.work();  //class the app work method.

#4 Another framework writer has also implemented method using the private name 
work.  The application developer decides to add that framework to the 
application. MF still works as does the apps own work method:
    var MF = InstallMF();
    var BF = BFLoader();
    Object.prototype.work = function () { ...};
    var thing = MF.getAThing();    //behind the scene calls MF's work method, 
still works fine
    var appThing = think.work();  //class the app work method.
    var bStuff = BF.buildStuff();   //behinds the scene calls BF's work method.

#5 The application writer studies the document of the MF framework and 
discovers that to accomplish some specific goal using the framework they need 
to call its work method on an object.  Because they are already using their own 
work method on the same objects they imports MF's work private name under 
another name of the apps choosing:
    var MF = InstallMF();
    var BF = BFLoader();
    Object.prototype.work = function () { ...};
    var thing = MF.getAThing();    //behind the scene calls MF's work method, 
still works fine
    var appThing = thing.work();  //class the app work method.
    var bStuff = BF.buildStuff();   //behinds the scene calls BF's work method.
    private workMF = MF.names.work;
    appThing.workMF();  //Explicitly  MF's work method

#6 The application writer subsequently discovers that they also need to invoke 
BF's work method  so they also  imports BFs work private name under another 
name of the apps choosing:
    var MF = InstallMF();
    var BF = BFLoader();
    Object.prototype.work = function () { ...};
    var thing = MF.getAThing();    //behind the scene calls MF's work method, 
still works fine
    var appThing = thing.work();  //class the app work method.
    var bStuff = BF.buildStuff();   //behinds the scene calls BF's work method.
    private workMF = MF.names.work;
    appThing.workMF();  //Explicitly  MF's work method
    private workBF = BF.getExtensionMethodName("work");
    appThing.workBF();

Note that it is only in scenarios #5 and #6  that any sort of explicit name 
disambiguation needs to be done.  There are situations where the app developer 
needs to have simultaneous access to similarly named extension methods. The 
disambiguation only is necessary within the local code that requires such 
access and the developer can choose what ever local name assignment will be 
most convenient and meaningful from the app perspective. 

I have a few additional comments embedded below.

 
On Mar 19, 2011, at 10:54 PM, Andrew Dupont wrote:

> On Mar 19, 2011, at 7:02 PM, Sam Tobin-Hochstadt wrote:
> 
>> You're correct -- this won't do what you probably intended.  But the
>> great thing about private names is that this is a problem you can
>> *locally* fix.  For example:
>> 
>> private myClone = installCloneLibrary();
>> var twin = [{a:0}, {b:1}].myClone();
>> var thing = MyObj.clone();
> 
> Yeah, but at that point one might as well just name the function myClone 
> (replacing "my" with some framework-specific prefix) and eschew private names 
> altogether. In this example, being able to name the method "clone" without 
> fear of naming collisions is the whole point.

True, the framework could have prefixed all its internal extension methods but 
that is not fool proof and all internal uses of the methods may look "ugly".  
From the framework perspective, you can view private names as a prefixing 
mechanism that guarantees you will never have conflicts with another frameworks 
prefixing. It also allows you to internally use pleasant, readable names.


> 
>> or
>> 
>> var cloneProp = installCloneLibrary();
>> var twin = [{a:0}, {b:1}][cloneProp]();
>> var thing = MyObj.clone();
> 
> This is more palatable, but I wager it's far harder for end-users to grok.

Which is one of the motivation for private names.  The above formulation would 
need to be used even when there wasn't a conflict and as you say, it is harder 
to grok.


> 
> Anyway, now that I've confirmed my suspicions, I'm hesitant about the private 
> names proposal as described. The fact that declaring a certain name as 
> private affects _all_ property name lookups in that scope (all lookups that 
> use the dot operator or object literal syntax, at least) — well, I'm not sure 
> I like the implications. It would mean a new  and _surprising_ distinction 
> between dot notation and bracket notation.

There is already a distinction between dot notation and bracket notation:
  var obj = {0: "zero", foo: "foo"};
  var foo = 0;
  print ( obj.foo === obj[foo]);  //false, really obj.foo ===obj[42]


> 
> As a maintainer of a framework that does quite a bit of built-in extension, I 
> can't imagine us using private names for this purpose. If we wanted to define 
> {}.clone in this manner, we'd be exchanging one potential collision (one 
> property defined in one place) for another (every property defined in the 
> same lexical scope). If the private names had their own operator (e.g., 
> twin#clone vs. twin.clone), it'd at least be worth considering.
> 
> I'm sure private names would be useful for other reasons, but IMO it wouldn't 
> solve the problem of safely extending built-ins.
> 
> Cheers,
> Andrew
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to