Lexically Scoped Object Extensions (was About private names)

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Mar 21 17:42:38 PDT 2011


On Mar 21, 2011, at 1:13 PM, Erik Arvidsson wrote:
> 
> The above use case cannot be solved using private names because
> private names conflict with public names.
> 


Erik, I'm not sure that my understanding of the intended semantics of your extension statement is totally correct.  But given what I I think  you intended here is how I might imagine it desugaring using private names.  Let me know what I misinterpretered:

{
  private filter;
  Object.prototype.filter = function(fun) {
     var publicFilter= this["filter"];
     if  (publicFilter) return publicFilter.apply(this,arguments);
     var retval = {};
     for (var key in this) {
       if (fun(this[key])
         retval[key] = this[key];
     }
     return retval;
   }

function largerThanN(obj, n) {
   return obj.filter(function(item) {
     return item > n;
   }
 }

 var a = [0, 1, 2, 3, 4];
 print(largerThanN(a, 2));
 var o = {a: 0, b: 1, c: 2, d: 3, e: 4};
 print(largerThanN(0, 2));

delete Object.prototype.filter
}

On Mar 21, 2011, at 1:13 PM, Erik Arvidsson wrote:

> The thread about using private names is getting a bit unwieldy but I'd
> like to focus on the  use case that I have been thinking of as
> "Lexically scoped monkey patching" or "Lexically scoped object
> extensions" instead of focusing on how to use "private names" to fit
> this scenario.
> 
> Extending built ins and modifying existing classes to work around bugs
> or to provide a better API is (or was) a common pattern. Today a lot
> of JS library shun this approach due to the risk of conflicts.
> 
> Let us assume that you could extend an object in your current lexical
> scope and that such extensions could be imported from a module into
> your current scope.
> 
> Given:
> 
> {
>  function largerThanN(obj, n) {
>    return obj.filter(function(item) {
>      return item > n;
>    }
>  }
> 
>  var a = [0, 1, 2, 3, 4];
>  print(largerThanN(a, 2));
> }
> 
> Now we would like to make largerThanN to work with Object objects. The
> naïve thing to do is to just to add a filter method to
> Object.prototype. However, this might cause conflicts with other code
> that uses objects. The idea here is that we can do this safely in our
> scope (ignore syntax except that it is important that it can be done
> statically).
> 
> {
>  extend Object.prototype with {
>    filter: function(fun) {
>      var retval = {};
>      for (var key in this) {
>        if (fun(this[key])
>          retval[key] = this[key];
>      }
>      return retval;
>    }
>  };
> 
>  function largerThanN(obj, n) {
>    return obj.filter(function(item) {
>      return item > n;
>    }
>  }
> 
>  var a = [0, 1, 2, 3, 4];
>  print(largerThanN(a, 2));
>  var o = {a: 0, b: 1, c: 2, d: 3, e: 4};
>  print(largerThanN(0, 2));
> }
> 
> The above use case cannot be solved using private names because
> private names conflict with public names.
> 
> Can we agree that this is a use case that we care about and focus on
> this instead of whether private names can or cannot do this?
> 
> -- 
> erik
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110321/29203727/attachment-0001.html>


More information about the es-discuss mailing list