Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Tom Van Cutsem
2015-11-02 23:34 GMT+01:00 Coroutines :
>
> I come from Lua.  In Lua we make proxy objects with metamethods.  You
> create an empty table/object and define a metatable with a __index and
> __newindex to catch accesses and changes when a key/property doesn't
> exist.  I would primarily use this in sandboxes where I wanted to
> track the exact series of operations a user was performing to modify
> their environment (the one I'd stuck them in).


For this type of use case, you can use an ES6 Proxy <
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
You can think of the proxy handler's methods as the 'metamethods' of the
proxy object.

What O.o would provide beyond Proxy is the ability to observe changes to
already pre-existing objects. However, since you mention you'd start with
an empty table/object, you should be able to create a fresh Proxy and use
that to trace all property accesses.

Proxies are particularly well-suited when you want to sandbox things, since
you should be in control of the sandboxed environment anyway and can set-up
proxies to intermediate. O.o is particularly well-suited to scenarios where
there are already plenty of pre-existing objects and you don't know ahead
of time which ones to observe and which not.

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


Re: An update on Object.observe

2015-11-03 Thread Andrea Giammarchi
Just to be clear:

  1. I am very happy O.o is gone
  2. in my experience it's repeatedly clear that whatever proposal that
cannot be polyfilled will have hard time to be widely adopted.

As example, O.o has never been in other browsers so, unless you are
targeting Chrome and Chrome only, it's kinda a bad choice. Maybe it would
have been adopted more if it was cross platform?

Who knows, and let's move forward!

Best Regards



On Tue, Nov 3, 2015 at 11:26 AM, Alexander Jones  wrote:

> In my opinion, the fundamental record type we build our JS on should be
> getting dumber, not smarter. It feels inappropriate to be piling more
> difficult-to-reason-about mechanisms on top before reeling in exotic host
> objects. With Proxy out of the bag, I'm not so hopeful for the humble
> Object anymore.
>
>
> On Tuesday, 3 November 2015, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> Sure thing, meanwhile polymer or other libraries need to pollute getters
>> and setters and the rest of the web have been trying to polyfill it for at
>> least 6 years now *
>>
>> The reason is not widely "abused" is that it never made it as standard
>> and as it is feels like an outdated spec. Proxy would give us that and much
>> more, unfortunately proxies do not play so well cross environment. For
>> instance, I've tried to use them in GJS ( Gtk+3 JavaScript bindings ) and
>> while Object.prototype.watch always works, proxied GObjects fail to be used
>> like these were just GObjects.
>>
>> That might be a specific env problem though, but having a way to watch
>> properties, specially in two ways bindings scenarios, is a very needed
>> common thing.
>> As example, in DOMClass I'm replacing native getters/setters to be
>> notified about changes, it doesn't feel right even if it works.
>>
>> All this is over-off-topic though, so I might just stop.
>>
>> Best Regards
>>
>>
>>
>> * just few examples since 2009
>> https://gist.github.com/eligrey/384583
>> https://gist.github.com/adriengibrat/b0ee333dc1b058a22b66
>> question in SO
>> http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers
>> http://deploytonenyures.blogspot.co.uk/2013/02/objectwatch-polyfill.html
>>
>> https://code.google.com/p/chtor/source/browse/chtor/chrome/js/object-watch.js?spec=svn2c00820d48169bb678a00447e295fb31dcf448ed=2c00820d48169bb678a00447e295fb31dcf448ed
>>
>> yes, I've done that too
>> in 2009
>> http://webreflection.blogspot.co.uk/2009/01/internet-explorer-object-watch.html
>> and recently https://gist.github.com/WebReflection/366dc38574dc526308b5
>>
>>
>>
>> On Tue, Nov 3, 2015 at 2:11 AM, Boris Zbarsky  wrote:
>>
>>> On 11/2/15 4:55 PM, Andrea Giammarchi wrote:
>>>
 I agree with Benoit and I think there is a reason
 `Object.prototype.watch` is still in Firefox and  won't go away any time
 soon

>>>
>>> As far as I know the only reason it's there and hasn't been removed is
>>> because it's used to implement debugger watchpoints [1].  And the only
>>> reason it's web-exposed is because SpiderMonkey has not prioritized being
>>> able to expose APIs to privileged code but not the web (something that
>>> think should get fixed).
>>>
>>> -Boris
>>>
>>> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=934669
>>>
>>> ___
>>> 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: An update on Object.observe

2015-11-03 Thread Andrea Giammarchi
Sure thing, meanwhile polymer or other libraries need to pollute getters
and setters and the rest of the web have been trying to polyfill it for at
least 6 years now *

The reason is not widely "abused" is that it never made it as standard and
as it is feels like an outdated spec. Proxy would give us that and much
more, unfortunately proxies do not play so well cross environment. For
instance, I've tried to use them in GJS ( Gtk+3 JavaScript bindings ) and
while Object.prototype.watch always works, proxied GObjects fail to be used
like these were just GObjects.

That might be a specific env problem though, but having a way to watch
properties, specially in two ways bindings scenarios, is a very needed
common thing.
As example, in DOMClass I'm replacing native getters/setters to be notified
about changes, it doesn't feel right even if it works.

All this is over-off-topic though, so I might just stop.

Best Regards



* just few examples since 2009
https://gist.github.com/eligrey/384583
https://gist.github.com/adriengibrat/b0ee333dc1b058a22b66
question in SO
http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers
http://deploytonenyures.blogspot.co.uk/2013/02/objectwatch-polyfill.html
https://code.google.com/p/chtor/source/browse/chtor/chrome/js/object-watch.js?spec=svn2c00820d48169bb678a00447e295fb31dcf448ed=2c00820d48169bb678a00447e295fb31dcf448ed

yes, I've done that too
in 2009
http://webreflection.blogspot.co.uk/2009/01/internet-explorer-object-watch.html
and recently https://gist.github.com/WebReflection/366dc38574dc526308b5



On Tue, Nov 3, 2015 at 2:11 AM, Boris Zbarsky  wrote:

> On 11/2/15 4:55 PM, Andrea Giammarchi wrote:
>
>> I agree with Benoit and I think there is a reason
>> `Object.prototype.watch` is still in Firefox and  won't go away any time
>> soon
>>
>
> As far as I know the only reason it's there and hasn't been removed is
> because it's used to implement debugger watchpoints [1].  And the only
> reason it's web-exposed is because SpiderMonkey has not prioritized being
> able to expose APIs to privileged code but not the web (something that
> think should get fixed).
>
> -Boris
>
> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=934669
>
> ___
> 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: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Isiah Meadows
Lol... I feel I'm in an insane minority that can work relatively
productively in Java 7 and Haskell both.

Of course, I have a preference, but that preference lies around that of
OCaml and Clojure. It's more the expression-based, impure functional
languages that I'm most productive in. Observing mutations that I react to
using immutable data structures. Sounds very odd and/or blasphemous to
some, but that's what I like. MVC models like that are how Mithril and
similar smaller frameworks have started to get some attention. It prefers
highly local state, and an observed object would be a great state model for
that.

And on that note, I'm going to stop before I derail the topic too far.

On Tue, Nov 3, 2015, 11:26 Andrea Giammarchi 
wrote:

> That would make functional-programming-oriented developers wining forever
> about such monstrosity in  specs ... I'd personally love such possibility!
>
> Regards
>
> On Tue, Nov 3, 2015 at 2:41 PM, Matthew Robb 
> wrote:
>
>> I probably have a terrible understanding of how this all works at a low
>> level but I feel like a potential solution would be a method of "upgrading"
>> a non-proxy object to be a proxy. The reason accessors are being used as
>> they are now is because you can retro fit them. Maybe what I am suggesting
>> is essentially like swapping out the internal pointer of an object with
>> another object (such as the way live module bindings work). In this way you
>> might upgrade an existing object to behave like a proxy.
>>
>>
>> - Matthew Robb
>>
>> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem 
>> wrote:
>>
>>>
>>> 2015-11-02 23:34 GMT+01:00 Coroutines :

 I come from Lua.  In Lua we make proxy objects with metamethods.  You
 create an empty table/object and define a metatable with a __index and
 __newindex to catch accesses and changes when a key/property doesn't
 exist.  I would primarily use this in sandboxes where I wanted to
 track the exact series of operations a user was performing to modify
 their environment (the one I'd stuck them in).
>>>
>>>
>>> For this type of use case, you can use an ES6 Proxy <
>>> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
>>> You can think of the proxy handler's methods as the 'metamethods' of the
>>> proxy object.
>>>
>>> What O.o would provide beyond Proxy is the ability to observe changes to
>>> already pre-existing objects. However, since you mention you'd start with
>>> an empty table/object, you should be able to create a fresh Proxy and use
>>> that to trace all property accesses.
>>>
>>> Proxies are particularly well-suited when you want to sandbox things,
>>> since you should be in control of the sandboxed environment anyway and can
>>> set-up proxies to intermediate. O.o is particularly well-suited to
>>> scenarios where there are already plenty of pre-existing objects and you
>>> don't know ahead of time which ones to observe and which not.
>>>
>>> Cheers,
>>> Tom
>>>
>>> ___
>>> 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
>>
>>
> ___
> 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: An update on Object.observe

2015-11-03 Thread Mark S. Miller
On Tue, Nov 3, 2015 at 11:27 AM, lycheeJS Engine <
lycheejs+esdisc...@gmail.com> wrote:

> I think we still need Object.observe as a specification to implement
> proper sandboxing of feature-detecting closures.
>

What do you mean by "sandbox"?

(I was not able to make sense of the rest of this message using my normal
understanding of "sandbox".)




>
> For example, in lycheeJS we have a sandboxing system that can inject
> definitions (and their variants) at runtime, replaces them intelligently at
> runtime. The definition closures have, for that purpose, all a supports()
> and exports() method. Both are using a referenced object that is sandboxed.
> The global property therefore is just a reference to a custom object, so
> that we can trace the properties, data types and causes of the errors.
>
> The implementation got stuck because of missing support for ES6 Proxies in
> the wild, but the idea is to use them to figure out if an implementation is
> doing something like window.addEventListener('asdasd') in the background
> and escalating an error up to a delegation handler that figures out what to
> do and what to inject to run it again. It is necessary to not only track
> properties and their data type; we need a feature to track if it was a
> function that threw an error or not.
>
>
> Easy use case:
>
> Imagine a var sandbox = { setTimeout: window.setTimeout }; This would
> throw a context error and we would need that information with proper
> description on what happened in order to isolate setTimeout and inject our
> In-JS Debugger there.
>
> We think Object.observe is an essential feature to have the simulation
> part of this, because we need desperately the capabilities to have a
> in-JS-written Debugger that can find such issues for our training of the
> Graph NN. The execution time aspect of this is a show-stopper if it would
> not be possible.
>
>
> Advanced use case:
>
> We don't use a RendererFactory that is executed once a new Renderer is
> instantiated, we have multiple Renderer implementations for multiple
> platforms available. Each Renderer has its own platform
> (fertilizer)-specific implementation. Those implementations are called
> alternative Definitions.
>
> Each definition has a supports() method that is called once the runtime
> error-determination algorithm tries to inject a new instance of the
> Renderer somewhere or de-reference an old, now slowly running Renderer.
>
> The supports() method can have all kinds of ES5 / ES6 code in order for
> the determination; it is the essential point to determine the capabilities
> of the runtime - at the given execution time, not compile time.
>
> If, for example, the canvas binding in the runtime on Android has problems
> now and throws some errors; there might be a fallback implementation
> available (SDL / OpenGL / GLUT / whatever) and then the Environment sandbox
> updates its dependencies accordingly and tries out "if one of the fallback
> implementation would be supported right now".
>
> Therefore, we think that Object.observe is quite necessary for our
> live-update-and-inject algorithms to determine compatibility problems for
> out-rolled updates _before_ they are applied to have proper feedback for
> our NN on the other peer-side of things.
>
>
> PS:
>
> In case anyone is interested, the problem for which we would need
> Object.observe and ES6 Proxies available, is here:
> https://github.com/Artificial-Engineering/lycheeJS/blob/development-0.9/lychee/source/core/Environment.js#L112
>
>
> But I could be totally all-wrong with this. If the described features are
> possible to be implemented with ES6 Proxies alone, I'm fine with
> deprecating Object.observe and with switching to ES6 Proxies. But the
> features are essential for us to choose ES6/ES7 as a language and I hope
> that others have similar feature requests.
>
> ~Chris
>
> ___
> 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: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread William Edney
For those interested in using Proxies in the future, here are the
appropriate links to the two remaining holdouts (FF and MS Edge are already
there):

Safari/Webkit/JSC:

https://bugs.webkit.org/show_bug.cgi?id=35731

Chrome/V8:

https://code.google.com/p/v8/issues/detail?id=1543

Bug the appropriate owners ;-).

Cheers,

- Bill


On Tue, Nov 3, 2015 at 4:40 PM, Brendan Eich  wrote:

> Ah yes, the Smalltalk "become:" message, something that inspired
> SpiderMonkey's "Brain Transplants" -- see the [1] footnote at
> https://brendaneich.com/2010/11/proxy-inception/, and of course the
> bugzilla link, which leads to this:
>
>  Brendan Eich
> [:brendan] 2010-07-19 17:53:44 PDT
>
> Burns:[saws off the top of Homer's head.  No blood, very clean.
>The top of Homer's head rolls away.]
>   Smithers, hand me that ice-cream scoop.
> Smithers: Ice-cream scoop?!
> Burns:Dammit, Smithers, this isn't rocket science, it's brain surgery!
>
> ("If I Only Had a Brain", from "Treehouse of Horror II")
>
> /be
>
>
> On Tue, Nov 3, 2015 at 6:42 AM Matthew Robb 
> wrote:
>
>> I probably have a terrible understanding of how this all works at a low
>> level but I feel like a potential solution would be a method of "upgrading"
>> a non-proxy object to be a proxy. The reason accessors are being used as
>> they are now is because you can retro fit them. Maybe what I am suggesting
>> is essentially like swapping out the internal pointer of an object with
>> another object (such as the way live module bindings work). In this way you
>> might upgrade an existing object to behave like a proxy.
>>
>>
>> - Matthew Robb
>>
>> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem 
>> wrote:
>>
>>>
>>> 2015-11-02 23:34 GMT+01:00 Coroutines :

 I come from Lua.  In Lua we make proxy objects with metamethods.  You
 create an empty table/object and define a metatable with a __index and
 __newindex to catch accesses and changes when a key/property doesn't
 exist.  I would primarily use this in sandboxes where I wanted to
 track the exact series of operations a user was performing to modify
 their environment (the one I'd stuck them in).
>>>
>>>
>>> For this type of use case, you can use an ES6 Proxy <
>>> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
>>> You can think of the proxy handler's methods as the 'metamethods' of the
>>> proxy object.
>>>
>>> What O.o would provide beyond Proxy is the ability to observe changes to
>>> already pre-existing objects. However, since you mention you'd start with
>>> an empty table/object, you should be able to create a fresh Proxy and use
>>> that to trace all property accesses.
>>>
>>> Proxies are particularly well-suited when you want to sandbox things,
>>> since you should be in control of the sandboxed environment anyway and can
>>> set-up proxies to intermediate. O.o is particularly well-suited to
>>> scenarios where there are already plenty of pre-existing objects and you
>>> don't know ahead of time which ones to observe and which not.
>>>
>>> Cheers,
>>> Tom
>>>
>>> ___
>>> 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
>>
>
> ___
> 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: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Isiah Meadows
I'm neutral.

On Tue, Nov 3, 2015, 15:43 Matthew Robb  wrote:

> Isiah, could you elaborate some? I can't quite tell if you are expressing
> support for my suggestion or not. Thanks!
> On Nov 3, 2015 12:13 PM, "Isiah Meadows"  wrote:
>
>> Lol... I feel I'm in an insane minority that can work relatively
>> productively in Java 7 and Haskell both.
>>
>> Of course, I have a preference, but that preference lies around that of
>> OCaml and Clojure. It's more the expression-based, impure functional
>> languages that I'm most productive in. Observing mutations that I react to
>> using immutable data structures. Sounds very odd and/or blasphemous to
>> some, but that's what I like. MVC models like that are how Mithril and
>> similar smaller frameworks have started to get some attention. It prefers
>> highly local state, and an observed object would be a great state model for
>> that.
>>
>> And on that note, I'm going to stop before I derail the topic too far.
>>
>> On Tue, Nov 3, 2015, 11:26 Andrea Giammarchi 
>> wrote:
>>
>>> That would make functional-programming-oriented developers wining
>>> forever about such monstrosity in  specs ... I'd personally love such
>>> possibility!
>>>
>>> Regards
>>>
>>> On Tue, Nov 3, 2015 at 2:41 PM, Matthew Robb 
>>> wrote:
>>>
 I probably have a terrible understanding of how this all works at a low
 level but I feel like a potential solution would be a method of "upgrading"
 a non-proxy object to be a proxy. The reason accessors are being used as
 they are now is because you can retro fit them. Maybe what I am suggesting
 is essentially like swapping out the internal pointer of an object with
 another object (such as the way live module bindings work). In this way you
 might upgrade an existing object to behave like a proxy.


 - Matthew Robb

 On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem 
 wrote:

>
> 2015-11-02 23:34 GMT+01:00 Coroutines :
>>
>> I come from Lua.  In Lua we make proxy objects with metamethods.  You
>> create an empty table/object and define a metatable with a __index and
>> __newindex to catch accesses and changes when a key/property doesn't
>> exist.  I would primarily use this in sandboxes where I wanted to
>> track the exact series of operations a user was performing to modify
>> their environment (the one I'd stuck them in).
>
>
> For this type of use case, you can use an ES6 Proxy <
> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
> You can think of the proxy handler's methods as the 'metamethods' of the
> proxy object.
>
> What O.o would provide beyond Proxy is the ability to observe changes
> to already pre-existing objects. However, since you mention you'd start
> with an empty table/object, you should be able to create a fresh Proxy and
> use that to trace all property accesses.
>
> Proxies are particularly well-suited when you want to sandbox things,
> since you should be in control of the sandboxed environment anyway and can
> set-up proxies to intermediate. O.o is particularly well-suited to
> scenarios where there are already plenty of pre-existing objects and you
> don't know ahead of time which ones to observe and which not.
>
> Cheers,
> Tom
>
> ___
> 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


>>> ___
>>> 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: An update on Object.observe

2015-11-03 Thread Adam Klein
On Tue, Nov 3, 2015 at 1:25 PM, Coroutines  wrote:

> On Tue, Nov 3, 2015 at 1:24 PM, Adam Klein  wrote:
>
> > Note that O.o didn't help for the "as they happen" case anyway, as
> callbacks
> > were delayed until the end of the turn (same timing as Promise
> resolution).
> > Proxies are required to do synchronous interception.
>
> Would this be similar to .nextTick() in node?  I would still view this
> as much better than polling for changes with a timer :>


Yes, similar to nextTick() (and I agree that's better than polling,
conceptually). But Proxies are strictly more powerful.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Benoit Marchant
So would I, it would open up some very efficient opportunities 

> On Nov 3, 2015, at 8:26 AM, Andrea Giammarchi  
> wrote:
> 
> That would make functional-programming-oriented developers wining forever 
> about such monstrosity in  specs ... I'd personally love such possibility!
> 
> Regards
> 
> On Tue, Nov 3, 2015 at 2:41 PM, Matthew Robb  > wrote:
> I probably have a terrible understanding of how this all works at a low level 
> but I feel like a potential solution would be a method of "upgrading" a 
> non-proxy object to be a proxy. The reason accessors are being used as they 
> are now is because you can retro fit them. Maybe what I am suggesting is 
> essentially like swapping out the internal pointer of an object with another 
> object (such as the way live module bindings work). In this way you might 
> upgrade an existing object to behave like a proxy.
> 
> 
> - Matthew Robb
> 
> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem  > wrote:
> 
> 2015-11-02 23:34 GMT+01:00 Coroutines  >:
> I come from Lua.  In Lua we make proxy objects with metamethods.  You
> create an empty table/object and define a metatable with a __index and
> __newindex to catch accesses and changes when a key/property doesn't
> exist.  I would primarily use this in sandboxes where I wanted to
> track the exact series of operations a user was performing to modify
> their environment (the one I'd stuck them in).
> 
> For this type of use case, you can use an ES6 Proxy 
>   
> >.
>  You can think of the proxy handler's methods as the 'metamethods' of the 
> proxy object.
> 
> What O.o would provide beyond Proxy is the ability to observe changes to 
> already pre-existing objects. However, since you mention you'd start with an 
> empty table/object, you should be able to create a fresh Proxy and use that 
> to trace all property accesses.
> 
> Proxies are particularly well-suited when you want to sandbox things, since 
> you should be in control of the sandboxed environment anyway and can set-up 
> proxies to intermediate. O.o is particularly well-suited to scenarios where 
> there are already plenty of pre-existing objects and you don't know ahead of 
> time which ones to observe and which not.
> 
> Cheers,
> Tom
> 
> ___
> 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 
> 
> 
> 
> ___
> 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: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Matthew Robb
Isiah, could you elaborate some? I can't quite tell if you are expressing
support for my suggestion or not. Thanks!
On Nov 3, 2015 12:13 PM, "Isiah Meadows"  wrote:

> Lol... I feel I'm in an insane minority that can work relatively
> productively in Java 7 and Haskell both.
>
> Of course, I have a preference, but that preference lies around that of
> OCaml and Clojure. It's more the expression-based, impure functional
> languages that I'm most productive in. Observing mutations that I react to
> using immutable data structures. Sounds very odd and/or blasphemous to
> some, but that's what I like. MVC models like that are how Mithril and
> similar smaller frameworks have started to get some attention. It prefers
> highly local state, and an observed object would be a great state model for
> that.
>
> And on that note, I'm going to stop before I derail the topic too far.
>
> On Tue, Nov 3, 2015, 11:26 Andrea Giammarchi 
> wrote:
>
>> That would make functional-programming-oriented developers wining forever
>> about such monstrosity in  specs ... I'd personally love such possibility!
>>
>> Regards
>>
>> On Tue, Nov 3, 2015 at 2:41 PM, Matthew Robb 
>> wrote:
>>
>>> I probably have a terrible understanding of how this all works at a low
>>> level but I feel like a potential solution would be a method of "upgrading"
>>> a non-proxy object to be a proxy. The reason accessors are being used as
>>> they are now is because you can retro fit them. Maybe what I am suggesting
>>> is essentially like swapping out the internal pointer of an object with
>>> another object (such as the way live module bindings work). In this way you
>>> might upgrade an existing object to behave like a proxy.
>>>
>>>
>>> - Matthew Robb
>>>
>>> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem 
>>> wrote:
>>>

 2015-11-02 23:34 GMT+01:00 Coroutines :
>
> I come from Lua.  In Lua we make proxy objects with metamethods.  You
> create an empty table/object and define a metatable with a __index and
> __newindex to catch accesses and changes when a key/property doesn't
> exist.  I would primarily use this in sandboxes where I wanted to
> track the exact series of operations a user was performing to modify
> their environment (the one I'd stuck them in).


 For this type of use case, you can use an ES6 Proxy <
 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
 You can think of the proxy handler's methods as the 'metamethods' of the
 proxy object.

 What O.o would provide beyond Proxy is the ability to observe changes
 to already pre-existing objects. However, since you mention you'd start
 with an empty table/object, you should be able to create a fresh Proxy and
 use that to trace all property accesses.

 Proxies are particularly well-suited when you want to sandbox things,
 since you should be in control of the sandboxed environment anyway and can
 set-up proxies to intermediate. O.o is particularly well-suited to
 scenarios where there are already plenty of pre-existing objects and you
 don't know ahead of time which ones to observe and which not.

 Cheers,
 Tom

 ___
 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
>>>
>>>
>> ___
>> 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: An update on Object.observe

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 1:24 PM, Adam Klein  wrote:

> Note that O.o didn't help for the "as they happen" case anyway, as callbacks
> were delayed until the end of the turn (same timing as Promise resolution).
> Proxies are required to do synchronous interception.

Would this be similar to .nextTick() in node?  I would still view this
as much better than polling for changes with a timer :>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An update on Object.observe

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 3:26 AM, Alexander Jones  wrote:
> In my opinion, the fundamental record type we build our JS on should be
> getting dumber, not smarter. It feels inappropriate to be piling more
> difficult-to-reason-about mechanisms on top before reeling in exotic host
> objects. With Proxy out of the bag, I'm not so hopeful for the humble Object
> anymore.

As far as I know, without Proxy or Object.observe() there would be no
possible way to watch for changes *as they happen* and directly fire
off an observing function or handler.  You need assistance from the JS
runtime to track stuff like this correctly and efficiently.  The
polyfills for O.o() use timers to watch for changes - changes/accesses
can be missed between polls.  I am happy Proxy is at least staying
around - I was initially freaking out thinking Object.observe() was
the mechanism behind Proxy's magicalness.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An update on Object.observe

2015-11-03 Thread Adam Klein
On Tue, Nov 3, 2015 at 1:18 PM, Coroutines  wrote:

> On Tue, Nov 3, 2015 at 3:26 AM, Alexander Jones  wrote:
> > In my opinion, the fundamental record type we build our JS on should be
> > getting dumber, not smarter. It feels inappropriate to be piling more
> > difficult-to-reason-about mechanisms on top before reeling in exotic host
> > objects. With Proxy out of the bag, I'm not so hopeful for the humble
> Object
> > anymore.
>
> As far as I know, without Proxy or Object.observe() there would be no
> possible way to watch for changes *as they happen* and directly fire
> off an observing function or handler.  You need assistance from the JS
> runtime to track stuff like this correctly and efficiently.  The
> polyfills for O.o() use timers to watch for changes - changes/accesses
> can be missed between polls.  I am happy Proxy is at least staying
> around - I was initially freaking out thinking Object.observe() was
> the mechanism behind Proxy's magicalness.


Note that O.o didn't help for the "as they happen" case anyway, as
callbacks were delayed until the end of the turn (same timing as Promise
resolution). Proxies are required to do synchronous interception.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 12:20 AM, Tom Van Cutsem  wrote:

> What O.o would provide beyond Proxy is the ability to observe changes to
> already pre-existing objects.

I think I missed something important here.

You can watch for events with both Proxy and Object.observe() - but
Object.observe() lets you maintain the same object identity because
you're not replacing references to the watched object.

Let's say I want to watch for events on an object *I create*: I create
a Proxy to that object and then expose references to that proxy (not
the target object).  This is fine and dandy but if I want to observe
events on something like the `String` object/class (and its prototype)
I cannot replace all localized references to it in various modules.
Object.observe() could be seen as a 'cheat' in a sense that you can
observe events happening on the target object from code that is hidden
from you by a closure in another module (as long as you have a
reference to that object from where you use Object.observe()).  With
Proxy you can only observe changes where you can replace the target
object's references.

With Object.observe() you get a global view of events generated by the
target object, with Proxy you need to replace references to the target
object with references to the Proxy.

Now I'm changing my opinion again.  We need both.

But because of what Object.observe() can do to see into closures, I'd
relegate it to privileged code :>  It is incredibly useful for
debugging.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 3:22 PM, Coroutines  wrote:

> But because of what Object.observe() can do to see into closures, I'd
> relegate it to privileged code :>  It is incredibly useful for
> debugging.

I really need to make sure my thoughts are complete before I send a message.

Anyway, I just wanted to say I'm viewing this through my experience with Lua.

In Lua you would make a proxy (like I mentioned before) by creating an
empty table and setting the __index and __newindex metamethods to
trigger when a key doesn't exist for an access or having its value
set.  This is the only way to watch for changes, you cannot attach a
watch to an existing object - you create a separate object to act as
the proxy and replace the references to the existing/target object.
My last message was me realizing that Object.observe() has
functionality that would let you see into encapsulated, hidden
closures.  This is why I think Object.observe() is cool but probably
shouldn't be web-accessible.

Proxy is safe, Object.observe() should be debug-only functionality
((imo)).  Like, in browsers you'd only have access to it from the
console not from within a page?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 7:33 PM, Isiah Meadows  wrote:
> There's a reason Object.observe is async: it prevents you from changing how
> the value is first assigned, so it can't work like a proxy. And question:
> how does it let you see hidden closures?

In JS it is common to wrap everything in a (function (){})() for
organization and/or encapsulation purposes.  I would wrap a 'module'
in that, and within that module I might define local references to
common classes/libraries like: var string = require('String');
(example)

You cannot reach and redefine that private reference to String within
that module, but you do still have a reference to String from /where
you are/.  If you Object.observe(String) from another place you can
see events generated by the closed-over, private functions of that
module.

In my opinion this is bad, as it breaks the expectation of privacy you
have with a closure.

I think both should stay, but Object.observe() should not be
accessible "from the web" and only used for debugging.  With Proxy you
can't watch events from existing references that are hidden behind
closures.  Proxy creates a separate, 2nd object so it does not have
the same identity.  If you want to make sure you catch all events on
the target object you have to replace all the references to the target
with the proxy.  This is good, and does not allow closures to leak
events from hidden references to the same target you're watching
outside the closure.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An update on Object.observe

2015-11-03 Thread Coroutines
Okay, so I've been making a lot of noise on this list in the last few
days about Proxy and Object.observe().  I thought I would try to put
up some example code to show why both should stay, but
Object.observe() usage should be restricted so it's not web-accessible
(debug use only).

  var target = {} // this is the object we want to "observe", either
with Object.observe() or through a Proxy object.
  var p = new Proxy(target, {}); // this is the proxy where we can add
indirection, validation, or simply watch for events as we attempt to
operate on target

With Object.observe() we would be dealing with the same reference,
`target`.  If we used a Proxy we would replace the `target` reference
with that of the proxy to ensure that every operation on `target` is
going through the handling code of the Proxy:

  target = p; // and now only the Proxy holds an internal reference to
the original object (side question: is this accessible through
p.valueOf()?)

Anyway, my issue with Object.observe() is that you can observe
operations on an object from within closures, from references to
`target` that were made before you began observing.

My example is that you have global access to `String`, but a module
usually wraps all its implementation details and private functions in
a (function (){})() and returns either a constructor or an object with
public-facing functions.

(function () {
  var s = String;
  var private = function () { return new s("cat"); }
  var public = function () { return private(); }
  return public;
})()

Please accept this poor example with awful identifiers as code you
might see in the wild.

Now:

Should you be able to Object.observe() String and see that it is being
used to construct "cat" within the private function, within this
closure?

String is accessible and referenced from many places, so observing
that particular object that is very public seems reasonable.  I am on
the fence about if this should be allowed because while String is
quite 'visible', what is happening within that closure should not be.
Closures are used for organization and to hide implementation details
(of course).

The reason I think Proxy does it "right" is because you would need to
replace the reference to String with a Proxy that wraps String before
the closure makes a localized reference to it and exports its public
function.  I think this still respects the "black box" way closures
are used to hide what they do.  Proxy requires setup before references
are made, Object.observe() can begin watching for changes at any time.
This is because a Proxy is a separate object, and therefore has a
separate identity - while Object.observe() works with the original
object.  I want to say that because the closure seals away the
reference to String, that String should not be observable within the
closure - even if you have access to String outside the closure.  If
you wrap String before executing the closure, then you would of course
have the ability - but only if you proxy it before the closure.  To
*me* that would feel correct.

Anyway, I'm going to try to talk less I've been sending too many
messages.  I come from Lua and I love that this functionality exists
in Javascript exists in its own form.  I did a lot of fun things in
Lua so this is pretty personal to me if I want to continue having fun
in JS.

I want Object.observe() to stay for tricky debug situations, but I
think it would break information hiding/encapsulation on the web by
allowing you to observe changes made through existing private
references.  Proxy is what people should use, O.o() can be a private
sexy debug tool?

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


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Isiah Meadows
I was just thinking... Object.observe could, in theory, be used as a core
for a dispatcher and store in a Flux-like data flow. Basically, when a view
emits an event, you can use the first observed object as a memoized
dispatcher, and then it emits a list of changes that can then update
another observed object, the store. That store can then emit a list of
changes to be resolved with the views.

What do you all think?

On Tue, Nov 3, 2015, 22:32 Isiah Meadows  wrote:

> There's a reason Object.observe is async: it prevents you from changing
> how the value is first assigned, so it can't work like a proxy. And
> question: how does it let you see hidden closures?
>
> On Tue, Nov 3, 2015, 18:28 Coroutines  wrote:
>
>> On Tue, Nov 3, 2015 at 3:22 PM, Coroutines  wrote:
>>
>> > But because of what Object.observe() can do to see into closures, I'd
>> > relegate it to privileged code :>  It is incredibly useful for
>> > debugging.
>>
>> I really need to make sure my thoughts are complete before I send a
>> message.
>>
>> Anyway, I just wanted to say I'm viewing this through my experience with
>> Lua.
>>
>> In Lua you would make a proxy (like I mentioned before) by creating an
>> empty table and setting the __index and __newindex metamethods to
>> trigger when a key doesn't exist for an access or having its value
>> set.  This is the only way to watch for changes, you cannot attach a
>> watch to an existing object - you create a separate object to act as
>> the proxy and replace the references to the existing/target object.
>> My last message was me realizing that Object.observe() has
>> functionality that would let you see into encapsulated, hidden
>> closures.  This is why I think Object.observe() is cool but probably
>> shouldn't be web-accessible.
>>
>> Proxy is safe, Object.observe() should be debug-only functionality
>> ((imo)).  Like, in browsers you'd only have access to it from the
>> console not from within a page?
>> ___
>> 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: An update on Object.observe

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 10:08 PM, Isiah Meadows  wrote:
> Proxies can do a better, more thorough job of breaking encapsulation.
>
> ```js
> var log = [];
> String = new Proxy(String, {
>   construct(target, newTarget, args) {
> log.push(args);
> return Reflect.construct(target, newTarget, args);
>   }
> });
>
> (function () {
>   var s = String;
>   var private = function () { return new s("cat"); }
>   var public = function () { return private(); }
>   return public;
> })()
> ```

There's a possibility I am misunderstanding you but this is what I was
trying to say is 'okay'.  If you redefined String to be a proxy before
the closure runs then that seems "legal".

I disagree with Object.observe() because you can call it after the
closure has run and see changes made in String (or another object for
lack of a better example) when you call the exported function.  ...but
now I need to go read up on Reflect.  Be back in a few mins when I
have more slightly inaccurate things to say :o)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Isiah Meadows
There's a reason Object.observe is async: it prevents you from changing how
the value is first assigned, so it can't work like a proxy. And question:
how does it let you see hidden closures?

On Tue, Nov 3, 2015, 18:28 Coroutines  wrote:

> On Tue, Nov 3, 2015 at 3:22 PM, Coroutines  wrote:
>
> > But because of what Object.observe() can do to see into closures, I'd
> > relegate it to privileged code :>  It is incredibly useful for
> > debugging.
>
> I really need to make sure my thoughts are complete before I send a
> message.
>
> Anyway, I just wanted to say I'm viewing this through my experience with
> Lua.
>
> In Lua you would make a proxy (like I mentioned before) by creating an
> empty table and setting the __index and __newindex metamethods to
> trigger when a key doesn't exist for an access or having its value
> set.  This is the only way to watch for changes, you cannot attach a
> watch to an existing object - you create a separate object to act as
> the proxy and replace the references to the existing/target object.
> My last message was me realizing that Object.observe() has
> functionality that would let you see into encapsulated, hidden
> closures.  This is why I think Object.observe() is cool but probably
> shouldn't be web-accessible.
>
> Proxy is safe, Object.observe() should be debug-only functionality
> ((imo)).  Like, in browsers you'd only have access to it from the
> console not from within a page?
> ___
> 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: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Isiah Meadows
You can't get anything related to actual object access from Object.observe.
If you observe String, you can only get the following events:

- "add": String.newProp = value
- "update": String.existingProp = newValue
- "delete": delete String.prop
- "reconfigure": Object.defineProperty(String, ...)
- "setPrototype": String.__proto__ = newProto
- "preventExtensions": Object.preventExtensions(String)

None of these can detect access. Only changes and removal.

And from each change, the callback is called with a list of objects with
the following properties:

- "type": one of the types of actions above
- "object": the object being mutated
- "name": the name of the property
- "oldValue": if the action was "update", "delete", or "setPrototype", then
the value it previously was. Otherwise, this property doesn't exist.

You can only get the old value from objects that existed before the
closure. So it's already not necessarily unavailable outside the closure.
You could achieve similar by replacing the original reference with a proxy
before the closure, or even in theory by employing getters and setters. So
it's not really breaking encapsulation beyond what's already possible in
ES6. You can still leak closure references left and right with proxies. The
difference is the fact you don't have to explicitly replace the reference
beforehand. It could be implemented as an implicit reference replacement
under the hood.

As for detecting object accesses, that remains impossible with
Object.observe. The only thing you can do with it that you can't with
proxies is to observe the global object itself, an uncommon use case.
Everything else can be done with proxies. This just makes a common case
easier.

On Tue, Nov 3, 2015, 23:10 Coroutines  wrote:

> On Tue, Nov 3, 2015 at 7:33 PM, Isiah Meadows 
> wrote:
> > There's a reason Object.observe is async: it prevents you from changing
> how
> > the value is first assigned, so it can't work like a proxy. And question:
> > how does it let you see hidden closures?
>
> In JS it is common to wrap everything in a (function (){})() for
> organization and/or encapsulation purposes.  I would wrap a 'module'
> in that, and within that module I might define local references to
> common classes/libraries like: var string = require('String');
> (example)
>
> You cannot reach and redefine that private reference to String within
> that module, but you do still have a reference to String from /where
> you are/.  If you Object.observe(String) from another place you can
> see events generated by the closed-over, private functions of that
> module.
>
> In my opinion this is bad, as it breaks the expectation of privacy you
> have with a closure.
>
> I think both should stay, but Object.observe() should not be
> accessible "from the web" and only used for debugging.  With Proxy you
> can't watch events from existing references that are hidden behind
> closures.  Proxy creates a separate, 2nd object so it does not have
> the same identity.  If you want to make sure you catch all events on
> the target object you have to replace all the references to the target
> with the proxy.  This is good, and does not allow closures to leak
> events from hidden references to the same target you're watching
> outside the closure.
> ___
> 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: An update on Object.observe

2015-11-03 Thread Isiah Meadows
Proxies can do a better, more thorough job of breaking encapsulation.

```js
var log = [];
String = new Proxy(String, {
  construct(target, newTarget, args) {
log.push(args);
return Reflect.construct(target, newTarget, args);
  }
});

(function () {
  var s = String;
  var private = function () { return new s("cat"); }
  var public = function () { return private(); }
  return public;
})()
```

There's no equivalent with Object.observe. I could also redefine String as
a sloppy mode function and use `arguments.callee` or
`Function.prototype.callee` to get the `private` function, which would even
work in ES3. There's ways to break encapsulation already, that don't
involve Object.observe. And you can't observe references purely contained
within a closure.

On Wed, Nov 4, 2015, 00:51 Coroutines  wrote:

> Okay, so I've been making a lot of noise on this list in the last few
> days about Proxy and Object.observe().  I thought I would try to put
> up some example code to show why both should stay, but
> Object.observe() usage should be restricted so it's not web-accessible
> (debug use only).
>
>   var target = {} // this is the object we want to "observe", either
> with Object.observe() or through a Proxy object.
>   var p = new Proxy(target, {}); // this is the proxy where we can add
> indirection, validation, or simply watch for events as we attempt to
> operate on target
>
> With Object.observe() we would be dealing with the same reference,
> `target`.  If we used a Proxy we would replace the `target` reference
> with that of the proxy to ensure that every operation on `target` is
> going through the handling code of the Proxy:
>
>   target = p; // and now only the Proxy holds an internal reference to
> the original object (side question: is this accessible through
> p.valueOf()?)
>
> Anyway, my issue with Object.observe() is that you can observe
> operations on an object from within closures, from references to
> `target` that were made before you began observing.
>
> My example is that you have global access to `String`, but a module
> usually wraps all its implementation details and private functions in
> a (function (){})() and returns either a constructor or an object with
> public-facing functions.
>
> (function () {
>   var s = String;
>   var private = function () { return new s("cat"); }
>   var public = function () { return private(); }
>   return public;
> })()
>
> Please accept this poor example with awful identifiers as code you
> might see in the wild.
>
> Now:
>
> Should you be able to Object.observe() String and see that it is being
> used to construct "cat" within the private function, within this
> closure?
>
> String is accessible and referenced from many places, so observing
> that particular object that is very public seems reasonable.  I am on
> the fence about if this should be allowed because while String is
> quite 'visible', what is happening within that closure should not be.
> Closures are used for organization and to hide implementation details
> (of course).
>
> The reason I think Proxy does it "right" is because you would need to
> replace the reference to String with a Proxy that wraps String before
> the closure makes a localized reference to it and exports its public
> function.  I think this still respects the "black box" way closures
> are used to hide what they do.  Proxy requires setup before references
> are made, Object.observe() can begin watching for changes at any time.
> This is because a Proxy is a separate object, and therefore has a
> separate identity - while Object.observe() works with the original
> object.  I want to say that because the closure seals away the
> reference to String, that String should not be observable within the
> closure - even if you have access to String outside the closure.  If
> you wrap String before executing the closure, then you would of course
> have the ability - but only if you proxy it before the closure.  To
> *me* that would feel correct.
>
> Anyway, I'm going to try to talk less I've been sending too many
> messages.  I come from Lua and I love that this functionality exists
> in Javascript exists in its own form.  I did a lot of fun things in
> Lua so this is pretty personal to me if I want to continue having fun
> in JS.
>
> I want Object.observe() to stay for tricky debug situations, but I
> think it would break information hiding/encapsulation on the web by
> allowing you to observe changes made through existing private
> references.  Proxy is what people should use, O.o() can be a private
> sexy debug tool?
>
> FIN.
> ___
> 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: An update on Object.observe

2015-11-03 Thread Coroutines
On Tue, Nov 3, 2015 at 2:25 PM, Adam Klein  wrote:

> Yes, similar to nextTick() (and I agree that's better than polling,
> conceptually). But Proxies are strictly more powerful.

I agree as well - I had skipped over learning about Proxies until
someone told me about them last night.  They support trapping for a
larger number of uses - like for .. in iteration.  I had started
another thread to "Save Object.observe" after joining the mailing list
late.  I was misguided. ;>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Brendan Eich
Ah yes, the Smalltalk "become:" message, something that inspired
SpiderMonkey's "Brain Transplants" -- see the [1] footnote at
https://brendaneich.com/2010/11/proxy-inception/, and of course the
bugzilla link, which leads to this:

 Brendan Eich
[:brendan] 2010-07-19 17:53:44 PDT

Burns:[saws off the top of Homer's head.  No blood, very clean.
   The top of Homer's head rolls away.]
  Smithers, hand me that ice-cream scoop.
Smithers: Ice-cream scoop?!
Burns:Dammit, Smithers, this isn't rocket science, it's brain surgery!

("If I Only Had a Brain", from "Treehouse of Horror II")

/be


On Tue, Nov 3, 2015 at 6:42 AM Matthew Robb  wrote:

> I probably have a terrible understanding of how this all works at a low
> level but I feel like a potential solution would be a method of "upgrading"
> a non-proxy object to be a proxy. The reason accessors are being used as
> they are now is because you can retro fit them. Maybe what I am suggesting
> is essentially like swapping out the internal pointer of an object with
> another object (such as the way live module bindings work). In this way you
> might upgrade an existing object to behave like a proxy.
>
>
> - Matthew Robb
>
> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem  wrote:
>
>>
>> 2015-11-02 23:34 GMT+01:00 Coroutines :
>>>
>>> I come from Lua.  In Lua we make proxy objects with metamethods.  You
>>> create an empty table/object and define a metatable with a __index and
>>> __newindex to catch accesses and changes when a key/property doesn't
>>> exist.  I would primarily use this in sandboxes where I wanted to
>>> track the exact series of operations a user was performing to modify
>>> their environment (the one I'd stuck them in).
>>
>>
>> For this type of use case, you can use an ES6 Proxy <
>> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
>> You can think of the proxy handler's methods as the 'metamethods' of the
>> proxy object.
>>
>> What O.o would provide beyond Proxy is the ability to observe changes to
>> already pre-existing objects. However, since you mention you'd start with
>> an empty table/object, you should be able to create a fresh Proxy and use
>> that to trace all property accesses.
>>
>> Proxies are particularly well-suited when you want to sandbox things,
>> since you should be in control of the sandboxed environment anyway and can
>> set-up proxies to intermediate. O.o is particularly well-suited to
>> scenarios where there are already plenty of pre-existing objects and you
>> don't know ahead of time which ones to observe and which not.
>>
>> Cheers,
>> Tom
>>
>> ___
>> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An update on Object.observe

2015-11-03 Thread Isiah Meadows
Reflect.construct basically does `new Class(...args)`, but on a lower level
where you can set `new.target` in the call.

Object.observe makes it easier, but sometimes, it's useful to completely
break encapsulation from a closure. I've had a few use cases where I needed
that ability. There's been a couple times where I've explicitly yanked a
value out of a callback closure just to use it elsewhere.

And generally, Object.observe is useful for one of two things: listen for
changes as a break for encapsulation, which is what Angular 1 wanted it
for, or transfer changes to a new closure, which leads to extremely simple
POJO models in MV* architectures.

I did find a way to use it in Flux architectures as well. Here's a copy of
an email I already sent:

-

I was just thinking... Object.observe could, in theory, be used as a core
for a dispatcher and store in a Flux-like data flow. Basically, when a view
emits an event, you can use the first observed object as a memoized
dispatcher, and then it emits a list of changes that can then update
another observed object, the store. That store can then emit a list of
changes to be resolved with the views.

What do you all think?

On Wed, Nov 4, 2015, 01:17 Coroutines  wrote:

> On Tue, Nov 3, 2015 at 10:08 PM, Isiah Meadows 
> wrote:
> > Proxies can do a better, more thorough job of breaking encapsulation.
> >
> > ```js
> > var log = [];
> > String = new Proxy(String, {
> >   construct(target, newTarget, args) {
> > log.push(args);
> > return Reflect.construct(target, newTarget, args);
> >   }
> > });
> >
> > (function () {
> >   var s = String;
> >   var private = function () { return new s("cat"); }
> >   var public = function () { return private(); }
> >   return public;
> > })()
> > ```
>
> There's a possibility I am misunderstanding you but this is what I was
> trying to say is 'okay'.  If you redefined String to be a proxy before
> the closure runs then that seems "legal".
>
> I disagree with Object.observe() because you can call it after the
> closure has run and see changes made in String (or another object for
> lack of a better example) when you call the exported function.  ...but
> now I need to go read up on Reflect.  Be back in a few mins when I
> have more slightly inaccurate things to say :o)
> ___
> 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: An update on Object.observe

2015-11-03 Thread Brendan Eich
> a lot of noise on this list

Agreed (re: no one in particular). :-(

Best to step back and study all of the stuff already in JS, before doubling
down on reviving another withdrawn proposal.

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


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Matthew Robb
I probably have a terrible understanding of how this all works at a low
level but I feel like a potential solution would be a method of "upgrading"
a non-proxy object to be a proxy. The reason accessors are being used as
they are now is because you can retro fit them. Maybe what I am suggesting
is essentially like swapping out the internal pointer of an object with
another object (such as the way live module bindings work). In this way you
might upgrade an existing object to behave like a proxy.


- Matthew Robb

On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem  wrote:

>
> 2015-11-02 23:34 GMT+01:00 Coroutines :
>>
>> I come from Lua.  In Lua we make proxy objects with metamethods.  You
>> create an empty table/object and define a metatable with a __index and
>> __newindex to catch accesses and changes when a key/property doesn't
>> exist.  I would primarily use this in sandboxes where I wanted to
>> track the exact series of operations a user was performing to modify
>> their environment (the one I'd stuck them in).
>
>
> For this type of use case, you can use an ES6 Proxy <
> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
> You can think of the proxy handler's methods as the 'metamethods' of the
> proxy object.
>
> What O.o would provide beyond Proxy is the ability to observe changes to
> already pre-existing objects. However, since you mention you'd start with
> an empty table/object, you should be able to create a fresh Proxy and use
> that to trace all property accesses.
>
> Proxies are particularly well-suited when you want to sandbox things,
> since you should be in control of the sandboxed environment anyway and can
> set-up proxies to intermediate. O.o is particularly well-suited to
> scenarios where there are already plenty of pre-existing objects and you
> don't know ahead of time which ones to observe and which not.
>
> Cheers,
> Tom
>
> ___
> 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: An update on Object.observe

2015-11-03 Thread David Bruant

Hi,

Le 03/11/2015 12:26, Alexander Jones a écrit :
In my opinion, the fundamental record type we build our JS on should 
be getting dumber, not smarter. It feels inappropriate to be piling 
more difficult-to-reason-about mechanismson top before reeling in 
exotic host objects.
JS objects were never only the record you're talking about. They were 
also used for OOP (used as dynamic this values if one property was a 
function and called after a dot).
And DOM objects also exposed things that did not have equivalent in ES 
objects (aside from the easy "host objects" escape), so the language 
needed to catch up (as it did in ES5) despite having to be more 
difficult to reason about.


Immutable data structures might be what you're looking for though
https://github.com/sebmarkbage/ecmascript-immutable-data-structures

With Proxy out of the bag, I'm not so hopeful for the humble Object 
anymore.
This is a surprising statement. By exposing the low-level object API as 
userlang API (proxy traps + Reflect API), proxies make the low-level 
object API subject to the same backward-compat constraints as every 
other API.
If nothing else, the very existence of proxies puts an end to the 
evolution of the object model.


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


Re: An update on Object.observe

2015-11-03 Thread Andreas Rossberg
On 3 November 2015 at 14:58, David Bruant  wrote:
> Le 03/11/2015 12:26, Alexander Jones a écrit :
>>
>> In my opinion, the fundamental record type we build our JS on should be
>> getting dumber, not smarter. It feels inappropriate to be piling more
>> difficult-to-reason-about mechanismson top before reeling in exotic host
>> objects.

JS objects have never been simple. Since at least ES5, which
officially added accessors, attribute reflection, and irregular
inheritance rules, the last illusion of simplicity has been eternally
lost. But before that there already were various quirks and hidden
complexities.

>> With Proxy out of the bag, I'm not so hopeful for the humble Object
>> anymore.
>
> This is a surprising statement. By exposing the low-level object API as
> userlang API (proxy traps + Reflect API), proxies make the low-level object
> API subject to the same backward-compat constraints as every other API.
> If nothing else, the very existence of proxies puts an end to the evolution
> of the object model.

There is no end to evolution. The object model will grow more
features, like private properties, which are orthogonal to proxies.

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


Re: Save Object.observe()! (please) + make WeakMap/WeakSet observable.

2015-11-03 Thread Andrea Giammarchi
That would make functional-programming-oriented developers wining forever
about such monstrosity in  specs ... I'd personally love such possibility!

Regards

On Tue, Nov 3, 2015 at 2:41 PM, Matthew Robb  wrote:

> I probably have a terrible understanding of how this all works at a low
> level but I feel like a potential solution would be a method of "upgrading"
> a non-proxy object to be a proxy. The reason accessors are being used as
> they are now is because you can retro fit them. Maybe what I am suggesting
> is essentially like swapping out the internal pointer of an object with
> another object (such as the way live module bindings work). In this way you
> might upgrade an existing object to behave like a proxy.
>
>
> - Matthew Robb
>
> On Tue, Nov 3, 2015 at 3:20 AM, Tom Van Cutsem  wrote:
>
>>
>> 2015-11-02 23:34 GMT+01:00 Coroutines :
>>>
>>> I come from Lua.  In Lua we make proxy objects with metamethods.  You
>>> create an empty table/object and define a metatable with a __index and
>>> __newindex to catch accesses and changes when a key/property doesn't
>>> exist.  I would primarily use this in sandboxes where I wanted to
>>> track the exact series of operations a user was performing to modify
>>> their environment (the one I'd stuck them in).
>>
>>
>> For this type of use case, you can use an ES6 Proxy <
>> https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy>.
>> You can think of the proxy handler's methods as the 'metamethods' of the
>> proxy object.
>>
>> What O.o would provide beyond Proxy is the ability to observe changes to
>> already pre-existing objects. However, since you mention you'd start with
>> an empty table/object, you should be able to create a fresh Proxy and use
>> that to trace all property accesses.
>>
>> Proxies are particularly well-suited when you want to sandbox things,
>> since you should be in control of the sandboxed environment anyway and can
>> set-up proxies to intermediate. O.o is particularly well-suited to
>> scenarios where there are already plenty of pre-existing objects and you
>> don't know ahead of time which ones to observe and which not.
>>
>> Cheers,
>> Tom
>>
>> ___
>> 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
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An update on Object.observe

2015-11-03 Thread lycheeJS Engine
I think we still need Object.observe as a specification to implement proper
sandboxing of feature-detecting closures.

For example, in lycheeJS we have a sandboxing system that can inject
definitions (and their variants) at runtime, replaces them intelligently at
runtime. The definition closures have, for that purpose, all a supports()
and exports() method. Both are using a referenced object that is sandboxed.
The global property therefore is just a reference to a custom object, so
that we can trace the properties, data types and causes of the errors.

The implementation got stuck because of missing support for ES6 Proxies in
the wild, but the idea is to use them to figure out if an implementation is
doing something like window.addEventListener('asdasd') in the background
and escalating an error up to a delegation handler that figures out what to
do and what to inject to run it again. It is necessary to not only track
properties and their data type; we need a feature to track if it was a
function that threw an error or not.


Easy use case:

Imagine a var sandbox = { setTimeout: window.setTimeout }; This would throw
a context error and we would need that information with proper description
on what happened in order to isolate setTimeout and inject our In-JS
Debugger there.

We think Object.observe is an essential feature to have the simulation part
of this, because we need desperately the capabilities to have a
in-JS-written Debugger that can find such issues for our training of the
Graph NN. The execution time aspect of this is a show-stopper if it would
not be possible.


Advanced use case:

We don't use a RendererFactory that is executed once a new Renderer is
instantiated, we have multiple Renderer implementations for multiple
platforms available. Each Renderer has its own platform
(fertilizer)-specific implementation. Those implementations are called
alternative Definitions.

Each definition has a supports() method that is called once the runtime
error-determination algorithm tries to inject a new instance of the
Renderer somewhere or de-reference an old, now slowly running Renderer.

The supports() method can have all kinds of ES5 / ES6 code in order for the
determination; it is the essential point to determine the capabilities of
the runtime - at the given execution time, not compile time.

If, for example, the canvas binding in the runtime on Android has problems
now and throws some errors; there might be a fallback implementation
available (SDL / OpenGL / GLUT / whatever) and then the Environment sandbox
updates its dependencies accordingly and tries out "if one of the fallback
implementation would be supported right now".

Therefore, we think that Object.observe is quite necessary for our
live-update-and-inject algorithms to determine compatibility problems for
out-rolled updates _before_ they are applied to have proper feedback for
our NN on the other peer-side of things.


PS:

In case anyone is interested, the problem for which we would need
Object.observe and ES6 Proxies available, is here:
https://github.com/Artificial-Engineering/lycheeJS/blob/development-0.9/lychee/source/core/Environment.js#L112


But I could be totally all-wrong with this. If the described features are
possible to be implemented with ES6 Proxies alone, I'm fine with
deprecating Object.observe and with switching to ES6 Proxies. But the
features are essential for us to choose ES6/ES7 as a language and I hope
that others have similar feature requests.

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


Re: An update on Object.observe

2015-11-03 Thread Alexander Jones
In my opinion, the fundamental record type we build our JS on should be
getting dumber, not smarter. It feels inappropriate to be piling more
difficult-to-reason-about mechanisms on top before reeling in exotic host
objects. With Proxy out of the bag, I'm not so hopeful for the humble
Object anymore.

On Tuesday, 3 November 2015, Andrea Giammarchi 
wrote:

> Sure thing, meanwhile polymer or other libraries need to pollute getters
> and setters and the rest of the web have been trying to polyfill it for at
> least 6 years now *
>
> The reason is not widely "abused" is that it never made it as standard and
> as it is feels like an outdated spec. Proxy would give us that and much
> more, unfortunately proxies do not play so well cross environment. For
> instance, I've tried to use them in GJS ( Gtk+3 JavaScript bindings ) and
> while Object.prototype.watch always works, proxied GObjects fail to be used
> like these were just GObjects.
>
> That might be a specific env problem though, but having a way to watch
> properties, specially in two ways bindings scenarios, is a very needed
> common thing.
> As example, in DOMClass I'm replacing native getters/setters to be
> notified about changes, it doesn't feel right even if it works.
>
> All this is over-off-topic though, so I might just stop.
>
> Best Regards
>
>
>
> * just few examples since 2009
> https://gist.github.com/eligrey/384583
> https://gist.github.com/adriengibrat/b0ee333dc1b058a22b66
> question in SO
> http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers
> http://deploytonenyures.blogspot.co.uk/2013/02/objectwatch-polyfill.html
>
> https://code.google.com/p/chtor/source/browse/chtor/chrome/js/object-watch.js?spec=svn2c00820d48169bb678a00447e295fb31dcf448ed=2c00820d48169bb678a00447e295fb31dcf448ed
>
> yes, I've done that too
> in 2009
> http://webreflection.blogspot.co.uk/2009/01/internet-explorer-object-watch.html
> and recently https://gist.github.com/WebReflection/366dc38574dc526308b5
>
>
>
> On Tue, Nov 3, 2015 at 2:11 AM, Boris Zbarsky  > wrote:
>
>> On 11/2/15 4:55 PM, Andrea Giammarchi wrote:
>>
>>> I agree with Benoit and I think there is a reason
>>> `Object.prototype.watch` is still in Firefox and  won't go away any time
>>> soon
>>>
>>
>> As far as I know the only reason it's there and hasn't been removed is
>> because it's used to implement debugger watchpoints [1].  And the only
>> reason it's web-exposed is because SpiderMonkey has not prioritized being
>> able to expose APIs to privileged code but not the web (something that
>> think should get fixed).
>>
>> -Boris
>>
>> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=934669
>>
>> ___
>> 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