Re: Weak{Map,Set}.p.clear() implementation proposal
On 29 October 2014 02:48, Isiah Meadows impinb...@gmail.com wrote: I'm proposing simply initializing a new instance and GC'ing the old instance entirely (updating the `this` to point to the new) instead of the current algorithm of maintaining a list of keys. I know that it potentially slow down the method itself, but it could eliminate the need for keeping a Map-like index of keys. That makes no sense. I neither understand what this is supposed to achieve, nor how it could possibly be implemented other than by going over the entire heap and replace all pointers. You cannot just set 'this' to point to new map. It doesn't seem to intend changing the semantics either, so even if it made sense, would be entirely irrelevant for the spec. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Weak{Map,Set}.p.clear() implementation proposal
I'm proposing simply initializing a new instance and GC'ing the old instance entirely (updating the `this` to point to the new) instead of the current algorithm of maintaining a list of keys. I know that it potentially slow down the method itself, but it could eliminate the need for keeping a Map-like index of keys. I know that this is kinda on the late side for such drastic internal spec changes, but might fix the problem of indexing WeakMap and WeakSet entries Link to formal proposal: https://github.com/impinball/weakmap-weakset-clear ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
Nice idea, but there seems to be (some) complications. Set **this** to *T*. What is `this` specifically? As far as I can see, it is a value and not a reference. And even if it were a reference, setting it to point to another object does not affect the other references which point to the old WeakSet. On Tue, Oct 28, 2014 at 11:48 PM, Isiah Meadows impinb...@gmail.com wrote: I'm proposing simply initializing a new instance and GC'ing the old instance entirely (updating the `this` to point to the new) instead of the current algorithm of maintaining a list of keys. I know that it potentially slow down the method itself, but it could eliminate the need for keeping a Map-like index of keys. I know that this is kinda on the late side for such drastic internal spec changes, but might fix the problem of indexing WeakMap and WeakSet entries Link to formal proposal: https://github.com/impinball/weakmap-weakset-clear ___ 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
Fwd: Weak{Map,Set}.p.clear() implementation proposal
What I mean is, consider this code: ```js var wsRef = new WeakSet(); var wsRef2 = wsRef; wsRef.clear(); ``` As far as I can see, in the `wsRef.clear()` algorithm, the `this` value has no relation with the `wsRef` identifier. Even if there was some internal magic around changing the identifier's reference, there would still be other references pointing to the old WeakSet object. So your proposal seems to require replacing an object in the memory with another while keeping the references intact, which (I believe) does not exist in ECMAScript. I may be wrong though, let's other for someone with more experience to have a say on this. `=]` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
On Oct 28, 2014 10:18 PM, Fabrício Matté ultco...@gmail.com wrote: What I mean is, consider this code: ```js var wsRef = new WeakSet(); var wsRef2 = wsRef; wsRef.clear(); ``` As far as I can see, in the `wsRef.clear()` algorithm, the `this` value has no relation with the `wsRef` identifier. Even if there was some internal magic around changing the identifier's reference, there would still be other references pointing to the old WeakSet object. So your proposal seems to require replacing an object in the memory with another while keeping the references intact, which (I believe) does not exist in ECMAScript. I may be wrong though, let's other for someone with more experience than me to have a say. `=]` Not in pure ECMAScript being interpreted, but it can definitely be done in the implementation. On Oct 28, 2014 10:18 PM, Fabrício Matté ultco...@gmail.com wrote: What I mean is, consider this code: ```js var wsRef = new WeakSet(); var wsRef2 = wsRef; wsRef.clear(); ``` As far as I can see, in the `wsRef.clear()` algorithm, the `this` value has no relation with the `wsRef` identifier. Even if there was some internal magic around changing the identifier's reference, there would still be other references pointing to the old WeakSet object. So your proposal seems to require replacing an object in the memory with another while keeping the references intact, which (I believe) does not exist in ECMAScript. I may be wrong though, let's other for someone with more experience than me to have a say. `=]` You can't in plain ECMAScript interpreted, but you definitely can in the implementation backend. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
My client needs to not glitch on me... :( On Oct 28, 2014 10:25 PM, Isiah Meadows impinb...@gmail.com wrote: On Oct 28, 2014 10:18 PM, Fabrício Matté ultco...@gmail.com wrote: What I mean is, consider this code: ```js var wsRef = new WeakSet(); var wsRef2 = wsRef; wsRef.clear(); ``` As far as I can see, in the `wsRef.clear()` algorithm, the `this` value has no relation with the `wsRef` identifier. Even if there was some internal magic around changing the identifier's reference, there would still be other references pointing to the old WeakSet object. So your proposal seems to require replacing an object in the memory with another while keeping the references intact, which (I believe) does not exist in ECMAScript. I may be wrong though, let's other for someone with more experience than me to have a say. `=]` Not in pure ECMAScript being interpreted, but it can definitely be done in the implementation. On Oct 28, 2014 10:18 PM, Fabrício Matté ultco...@gmail.com wrote: What I mean is, consider this code: ```js var wsRef = new WeakSet(); var wsRef2 = wsRef; wsRef.clear(); ``` As far as I can see, in the `wsRef.clear()` algorithm, the `this` value has no relation with the `wsRef` identifier. Even if there was some internal magic around changing the identifier's reference, there would still be other references pointing to the old WeakSet object. So your proposal seems to require replacing an object in the memory with another while keeping the references intact, which (I believe) does not exist in ECMAScript. I may be wrong though, let's other for someone with more experience than me to have a say. `=]` You can't in plain ECMAScript interpreted, but you definitely can in the implementation backend. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
Not in pure ECMAScript being interpreted, but it can definitely be done in the implementation. Yeah I think so too, but if no where else in the specification uses this pattern, implementations would be required to implement new mechanisms and possibly have de-optimizations. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
Actually, the de-opts shouldn't exist, considering it's effective equivalent in C++ would be pretty straightforward (and could be polyfilled in Node literally via native code): ```cpp HandleJSWeakMap* createClearedInstance() { // ... } // ... HandleJSWeakMap* wm-inst = createClearedInstance(); ``` On Oct 28, 2014 10:30 PM, Fabrício Matté ultco...@gmail.com wrote: Not in pure ECMAScript being interpreted, but it can definitely be done in the implementation. Yeah I think so too, but if no where else in the specification uses this pattern, implementations would be required to implement new mechanisms and possibly have de-optimizations. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
On Tue, Oct 28, 2014 at 10:58 PM, Fabrício Matté ultco...@gmail.com wrote: Looks nice, then. `;)` Though, this may not be so easy to implement in other languages which don't provide direct access to memory addresses, affecting implementations such as Rhino which is written in Java. Nit: Object properties in Java are passed by reference, not value. Method behavior is similar. It would still be possible in this case. Also worth noting that as this can't be implemented in pure ECMAScript, polyfilling is impossible. Though, the whole Weak* semantics are very hard to implement in pure ECMAScript anyway. On Wed, Oct 29, 2014 at 12:41 AM, Isiah Meadows impinb...@gmail.com wrote: Actually, the de-opts shouldn't exist, considering it's effective equivalent in C++ would be pretty straightforward (and could be polyfilled in Node literally via native code): ```cpp HandleJSWeakMap* createClearedInstance() { // ... } // ... HandleJSWeakMap* wm-inst = createClearedInstance(); ``` On Oct 28, 2014 10:30 PM, Fabrício Matté ultco...@gmail.com wrote: Not in pure ECMAScript being interpreted, but it can definitely be done in the implementation. Yeah I think so too, but if no where else in the specification uses this pattern, implementations would be required to implement new mechanisms and possibly have de-optimizations. -- Isiah Meadows ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
I'm bumping the initial link: https://github.com/impinball/weakmap-weakset-clear ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak{Map,Set}.p.clear() implementation proposal
I understand that objects are passed by reference in Java (similarly to ECMAScript), however I'm not sure how implementations link Lexical Environments' identifiers to their respective values, and re-mapping these would be more complicated than the C++ sample you've posted I believe. As far as I can see, this seems a lot more complicated than it is worth, and it would at least require a new abstract operation for internally in-place replacing objects while keeping references intact. Wouldn't it be far easier to just have an internal data property in each Weak(Map|Set) which can be replaced by a new list/object? Then implementations can just access/pass-by-reference the Weak(Set|Map) object and methods can read its data property. In fact, that seems to be what the spec already does: ### [23.3.3.1 WeakMap.prototype.clear ( )]( https://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakmap.prototype.clear ) ... 5. Set the value of M’s [[WeakMapData]] internal slot to a new empty List. And ### [23.4.3.2 WeakSet.prototype.clear ( )]( https://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakset.prototype.clear ) ... 5. Set the value of S’s [[WeakSetData]] internal slot to a new empty List. How would your proposal simplify those algorithms? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
I mostly have a similar approach in mind for tail calls. Precise about the interface, imprecise/informative about the implementation requirements. For WeakMaps, that means a well-defined API with informal English describing the expectations about memory consumption. For tail calls, it means a well-defined spec for what is considered a tail call with, again, informal English describing the expectations about memory consumption. Dave On Sep 16, 2011, at 3:36 PM, Mark S. Miller wrote: On Fri, Sep 16, 2011 at 3:13 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: I'm not sure exactly how we are going to specify tail calls. I know that Dave Herman has ideas that I assume we will build upon . For weak maps I think that a non-normative note that make explicit the doesn't leak expectation and points implementors towards an ephemeron based implementation will suffice. +1. At least until we see how Dave proposes specing tail calls to see if he has any ideas we might adapt. -- Cheers, --MarkM ___ 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: {Weak|}{Map|Set}
On Fri, Oct 7, 2011 at 5:23 PM, David Herman dher...@mozilla.com wrote: I mostly have a similar approach in mind for tail calls. Precise about the interface, imprecise/informative about the implementation requirements. For WeakMaps, that means a well-defined API with informal English describing the expectations about memory consumption. For tail calls, it means a well-defined spec for what is considered a tail call with, again, informal English describing the expectations about memory consumption. Thanks Dave, Allen, ok then. +1 without further reservations ;). Dave On Sep 16, 2011, at 3:36 PM, Mark S. Miller wrote: On Fri, Sep 16, 2011 at 3:13 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: I'm not sure exactly how we are going to specify tail calls. I know that Dave Herman has ideas that I assume we will build upon . For weak maps I think that a non-normative note that make explicit the doesn't leak expectation and points implementors towards an ephemeron based implementation will suffice. +1. At least until we see how Dave proposes specing tail calls to see if he has any ideas we might adapt. -- Cheers, --MarkM ___ 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: {Weak|}{Map|Set}
Le 15/09/2011 17:47, Allen Wirfs-Brock a écrit : On Sep 15, 2011, at 6:49 AM, Andreas Rossberg wrote: On 15 September 2011 09:10, Brendan Eichbren...@mozilla.com wrote: On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. I don't. :) It is true to some extent that WeakMap is GC jargon -- but as Mark points out, the normal use case for weak maps _is_ to ensure a certain space behaviour closely related to GC. No the normal use case for WeakMaps is simply to make associations between objects and arbitrary values. The special GC behavior is necessary to avoid memory leaks, but that is a quality of implementation issue, not a use case. Furthermore, let imagine for a minute that i need an ECMAScript implementation for programs i write which i know (for some reason) all are short live and use a maximum finite amount of memory i know. Based on this knowledge (i admit this to be weird to have this knowledge), i could decide to not implement a garbage collector. My programs are short-live and use few memory, i may not need to care about the memory. In this imagniary ECMAScript environment without Garbage Collection, why would i care of references to be weak or strong? I don't, i write programs. The typical JS programmer who wants to form such associations is not going to be thinking about the possibility of a leaky map unless they have already been burnt by them in some other language. They could have been burnt in JS as well for performance reasons. So why obfuscate the very intent by purposely avoiding what is more or less standard terminology for it (if slightly ambiguous)? If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. ObjectMap would be too generic a name to catch my immediate attention. Because, the majority of JS programmers will simply be looking for a way to map objects to values and will not be thinking about GC consequences. We want them to find this thing we are currently trying to name. We don't want them to miss it because it has weak in its name and they don't know what weak means. We need to design first for the 95% (ass generated number) of JS programmers who don't understand GC. Also, the notion of garbage collection is a separate concern from programming. It comes from the necessity of being careful of resources. I recommand this read on the topic: http://www.cse.nd.edu/~dthain/courses/cse40243/spring2006/gc-survey.pdf Ideally, we'd wish memory used by an object to be free'd as soon as we don't need the object anymore. Since this notion is clearly undecidable (some roulette russe program could make undecidable whether or not an object will be used or not later in a program), we have come up with restrictions of this notion. A first naive approach was to count references of an object; when the number of reference drops to 0, then the object cannot be accessed anymore, consequently, we don't need the memory it uses to be occupied anymore and can free the object. The reference counting is tricked by reference cycles. A second approach is to consider that there are some root references and traverse the graph of accessible objects. All objects not accessible through this graph is not needed anymore since it can be accessed. Once again, this approach is a restriction of the general garbage collection problem of figuring out whether or not an object is needed in a program. A third approach could be to dynamically prove that an object won't be use even though there would be still references of it in the program. var m = new Map(); // iterable var o = {}; o.o = o; m.set(o, true); var f167 = fibonacci(167); // assumed defined beforehand Since this is my entire program, during the fibonacci call, a (very smart) garbage collector could figure out that even though there is a living reference to o (o.o or map key) and even though the map is iterable the o object can be gabage collected since it won't be used anymore. I admit that this kind of proof is very hard to achieve and impossible in so many cases. However, even in that context, a program is able to free o's memory even without the programmer having to say anything about references being weak or strong. My point is that current state-of-the-art GC technologies rely on reference graph traversing. Provinding information to help out the traversing algorithm is good, but providing names related to this particular help doesn't seem future-proof with regard to future GC technologies which may not need this information. It may also be misleading to implement a so-called WeakMap with ECMAScript arrays for compatibility reasons [1]. Maybe that WeakMap is not really what is needed from the programmer point of view and weak references are just a (non-necessary in some cases) convinience rather
Re: {Weak|}{Map|Set}
On 16 September 2011 13:52, David Bruant david.bru...@labri.fr wrote: Furthermore, let imagine for a minute that i need an ECMAScript implementation for programs i write which i know (for some reason) all are short live and use a maximum finite amount of memory i know. Based on this knowledge (i admit this to be weird to have this knowledge), i could decide to not implement a garbage collector. My programs are short-live and use few memory, i may not need to care about the memory. In this imagniary ECMAScript environment without Garbage Collection, why would i care of references to be weak or strong? I don't, i write programs. Right, but why would you care about WeakMap either? The canonical Map is perfectly fine for that situation. Also, the notion of garbage collection is a separate concern from programming. It comes from the necessity of being careful of resources. Well yes, but that's part of programming. In practice, all resources are finite. And the difference between finite and infinite space usage is a correctness criterium. Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
Le 16/09/2011 14:14, Andreas Rossberg a écrit : On 16 September 2011 13:52, David Bruantdavid.bru...@labri.fr wrote: Furthermore, let imagine for a minute that i need an ECMAScript implementation for programs i write which i know (for some reason) all are short live and use a maximum finite amount of memory i know. Based on this knowledge (i admit this to be weird to have this knowledge), i could decide to not implement a garbage collector. My programs are short-live and use few memory, i may not need to care about the memory. In this imagniary ECMAScript environment without Garbage Collection, why would i care of references to be weak or strong? I don't, i write programs. Right, but why would you care about WeakMap either? The canonical Map is perfectly fine for that situation. True. Also, the notion of garbage collection is a separate concern from programming. It comes from the necessity of being careful of resources. Well yes, but that's part of programming. In practice, all resources are finite. And the difference between finite and infinite space usage is a correctness criterium. Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. You are making a connection between program correctness and implementation consideration of what you use to write these programs. It doesn't sound right. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. = This is not true. If your server ever receives only one message, you should be fine. The problem is in implementation limitation, not correctness of your program. It turns out your programming style with nowadays reasonable use cases (size of input, number of messages...) makes current implementations fail. I agree that it is annoying, but it doesn't make your program incorrect. If we start considering implementation limitations as sources of program incorrectness, then some ECMAScript programs will always be incorrect. Regarding tail call optimization, as far as I'm concerned, an agreement between implementors sounds like a more reasonable approach. There is no way in the language to test this feature. In this video [1], David Herman explains that a test can be written (at 40:40), but the test relies on implementation limitations rather than the language by itself (unlike all tests that can currently be found on test262). If I cannot rely on GC, then allocating an object for each received message would be incorrect. = Can you refine this point? I don't understand the connection between garbage collection and correctness of your program. I allocate objects on a daily basis and have never /relied/ on garbage collection. Don't get me wrong, I'm glad it exists, I'm glad i can write long-running program because garbage collection recycles memory, but i can still write programs that can run out of memory. The language allows it. With regard to memory management, GC is a convinience and allows me to write program which can live longer without running out of memory in a minute. It is in no way something that can be relied on for program correctness, (unless i am missing something?) Same goes for tail call optimization. David [1] http://www.youtube.com/watch?v=hs6tF-RDX4U ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fwd: {Weak|}{Map|Set}
[Forgot the list.] -- Forwarded message -- From: Andreas Rossberg rossb...@google.com Date: 16 September 2011 15:35 Subject: Re: {Weak|}{Map|Set} To: David Bruant david.bru...@labri.fr On 16 September 2011 15:17, David Bruant david.bru...@labri.fr wrote: Well yes, but that's part of programming. In practice, all resources are finite. And the difference between finite and infinite space usage is a correctness criterium. Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. You are making a connection between program correctness and implementation consideration of what you use to write these programs. It doesn't sound right. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. = This is not true. If your server ever receives only one message, you should be fine. Obviously, I was talking about a server that is expected to get an unbounded number of messages during its uptime. The problem is in implementation limitation, not correctness of your program. It turns out your programming style with nowadays reasonable use cases (size of input, number of messages...) makes current implementations fail. I agree that it is annoying, but it doesn't make your program incorrect. If we start considering implementation limitations as sources of program incorrectness, then some ECMAScript programs will always be incorrect. The difference is, this limitation would be hit for the _normal_ use case of the server. If my program cannot deal with its expected use case, then it is incorrect. Regarding tail call optimization, as far as I'm concerned, an agreement between implementors sounds like a more reasonable approach. There is no way in the language to test this feature. In this video [1], David Herman explains that a test can be written (at 40:40), but the test relies on implementation limitations rather than the language by itself (unlike all tests that can currently be found on test262). That is true, but whether some property can be observed from within the language itself, or only by its environment, is not relevant. There is no test that you can reliably write for a 'print' function. Still you want to be able to rely on it printing what you gave it. Or consider a sleep(secs) function. How would you test it? If I cannot rely on GC, then allocating an object for each received message would be incorrect. = Can you refine this point? I don't understand the connection between garbage collection and correctness of your program. I allocate objects on a daily basis and have never /relied/ on garbage collection. I think you implicitly do, all the time. Just try turning off GC and see whether your programs still work reliably. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Implementation considerations in the ECMAScript standard (was {Weak|}{Map|Set})
Changing the subject to something more relavant. Le 16/09/2011 15:36, Andreas Rossberg a écrit : On 16 September 2011 15:17, David Bruantdavid.bru...@labri.fr wrote: Well yes, but that's part of programming. In practice, all resources are finite. And the difference between finite and infinite space usage is a correctness criterium. Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. You are making a connection between program correctness and implementation consideration of what you use to write these programs. It doesn't sound right. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. = This is not true. If your server ever receives only one message, you should be fine. Obviously, I was talking about a server that is expected to get an unbounded number of messages during its uptime. The problem is in implementation limitation, not correctness of your program. It turns out your programming style with nowadays reasonable use cases (size of input, number of messages...) makes current implementations fail. I agree that it is annoying, but it doesn't make your program incorrect. If we start considering implementation limitations as sources of program incorrectness, then some ECMAScript programs will always be incorrect. The difference is, this limitation would be hit for the _normal_ use case of the server. If my program cannot deal with its expected use case, then it is incorrect. What is the definition of normal use? Size of input? When machines will be powerful enough to handle your current normal case without tail call optimization, will the definition of normal use change? Once again, program correctness [1] (tell me if you use incorrect differently and please define it if so) has nothing to do with implementation considerations of the plaform that run your program. There is no contradiction in having a correct program which fails when implemented because of implementations issues (of the platform, not the program). I do not think the ECMAScript standard is the the place where implementation considerations should be addressed. For that matters, people have been writing JavaScript programs for years and the spec doesn't say a word on implementations. Also, why should tail call optimization should be standardized? There is a use case, but aren't there other implementation optimizations that could be considered? Should they all been standardized? Why this one in particular? Really, once again, an appendix named hints for implementors or a different document or a page on the wiki would be better than a normative section. Saying that ECMAScript implementations aren't standard because they do not support one programming style sounds like a lot. Regarding tail call optimization, as far as I'm concerned, an agreement between implementors sounds like a more reasonable approach. There is no way in the language to test this feature. In this video [1], David Herman explains that a test can be written (at 40:40), but the test relies on implementation limitations rather than the language by itself (unlike all tests that can currently be found on test262). That is true, but whether some property can be observed from within the language itself, or only by its environment, is not relevant. It is not for people who write programs, it is for implementors because it directly impacts their work. They are not implementing a language anymore (which they still were as of ES5.1), but a language and some implementation constraints. Let imagine for a minute that tomorrow, implementors find another implementation trick which allows to run without crash the use cases that motivated the proper tail calls proposal, why would it be problematic? Why does it have to be this optimization in particular? There is no test that you can reliably write for a 'print' function. Still you want to be able to rely on it printing what you gave it. I (if i was an implementor) would want to test my print function. I can decide to do it from within the language or not since i have more power. You can also test a function from outside a language (which is a more relevant choice for a print function). Or consider a sleep(secs) function. How would you test it? Time cannot be formalized. The best we do is a human-acceptable approximation of it. For what it's worth, I recommand reading the ES5.1 spec for Date.now(). I think that test262 does a pretty good job of test coverage for it. If I cannot rely on GC, then allocating an object for each received message would be incorrect. = Can you refine this
Re: {Weak|}{Map|Set}
On Thu, Sep 15, 2011 at 10:56 AM, Kyle Simpson get...@gmail.com wrote: If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. But if you're actually aware of weakrefs (as I am), and you're searching for them in JS (as I was), and you see WeakMap (as I did), and you make the conclusion that Weak in the name means in fact weak references (as I did), then you probably also (as I did) assume that *all* the refs are weak. That's a failed conclusion, because only the keyrefs are weak. I can second this _exact_ experience. The name doesn't do anything to enlighten you that it only offers weak keyrefs and not weak valuerefs -- in fact, by your discovery line of reasoning, the name is almost a landmine that traps/misleads someone who does in fact know about weakrefs -- someone who didn't know about weakrefs wouldn't necessarily make the same deductive assumption by seeing weak in the name. Misleading/confusing with an API name is, IMHO, worse than less implementation-self-**descriptive naming. --Kyle __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Fri, Sep 16, 2011 at 10:14 AM, Rick Waldron waldron.r...@gmail.comwrote: On Thu, Sep 15, 2011 at 10:56 AM, Kyle Simpson get...@gmail.com wrote: [...] WeakMap [...] That's a failed conclusion, because only the keyrefs are weak. I can second this _exact_ experience. [...] Does anyone see anything wrong with EphemeralMap? It seems like the only name suggested so far that no one has raised any objections to. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Fri, Sep 16, 2011 at 10:41 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: [...] This is the exact situation that exists for any ECMAScript dynamic allocation. There are no guarantees in the ES spec. that resources allocated with an inaccessible object will be freed in a timely manner or ever. Given the state of the art of memory management isn't clear how you could make such guarantees without unreasonably limiting implementors. Does everyone, on both sides of this debate, agree that the WeakMap GC issue is and the tail-call issue are equivalent specification problems? I propose that the way to look at both of these is a way I have seen proposed somewhere[1] about how to deal with specifying tail calls. Rather than taking it as a correctness criteria on an implementation, instead view it as a statement about how to analyze the space complexity of programs. When writing Andreas' server, it would be nice if he could analyze whether his algorithms have O(1) asymptotic space complexity. Does this mean it will succeed on every implementation? Of course not. It may be that a given implementation doesn't even have enough memory for the server to load. Or the server might crash for other reasons. In order to do this analysis, we need a model of how much memory is retained by a computational state -- not in terms of how many bytes, but in terms adequate to make statements about asymptotic space complexity. Then an implementation that runs out of space on programs held to be reasonable by such analysis can be viewed as low quality implementations. [1] At one of the citations on the tail-call page, I forget which. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On 16 September 2011 19:42, Mark S. Miller erig...@google.com wrote: Does anyone see anything wrong with EphemeralMap? Yes. It's a longish name, and one that I will never be able to remember how to spell correctly. And to most programmers it probably sounds about as reassuring as endofunctor or catamorphism. ;) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implementation considerations in the ECMAScript standard (was {Weak|}{Map|Set})
I think we are digressing. There are three separate questions: 1. Intent 2. Specification 3. Testing Sometimes the intent is hard or impossible to specify formally, sometimes a specification is hard or impossible to test for. That doesn't necessarily invalidate such an intent or such a specification. Something you cannot test you might still be able to prove, for example. The whole point of having weak maps are space complexity consideration. So the name should be chosen accordingly IMO, regardless of whether we have a good solution to (2) and (3), which are really separate problems. But I'll leave it at that, nobody wants another longish bike-shedding discussion. On 16 September 2011 18:50, David Bruant david.bru...@labri.fr wrote: Changing the subject to something more relavant. Le 16/09/2011 15:36, Andreas Rossberg a écrit : On 16 September 2011 15:17, David Bruantdavid.bru...@labri.fr wrote: Well yes, but that's part of programming. In practice, all resources are finite. And the difference between finite and infinite space usage is a correctness criterium. Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. You are making a connection between program correctness and implementation consideration of what you use to write these programs. It doesn't sound right. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. = This is not true. If your server ever receives only one message, you should be fine. Obviously, I was talking about a server that is expected to get an unbounded number of messages during its uptime. The problem is in implementation limitation, not correctness of your program. It turns out your programming style with nowadays reasonable use cases (size of input, number of messages...) makes current implementations fail. I agree that it is annoying, but it doesn't make your program incorrect. If we start considering implementation limitations as sources of program incorrectness, then some ECMAScript programs will always be incorrect. The difference is, this limitation would be hit for the _normal_ use case of the server. If my program cannot deal with its expected use case, then it is incorrect. What is the definition of normal use? Size of input? When machines will be powerful enough to handle your current normal case without tail call optimization, will the definition of normal use change? Once again, program correctness [1] (tell me if you use incorrect differently and please define it if so) has nothing to do with implementation considerations of the plaform that run your program. There is no contradiction in having a correct program which fails when implemented because of implementations issues (of the platform, not the program). I do not think the ECMAScript standard is the the place where implementation considerations should be addressed. For that matters, people have been writing JavaScript programs for years and the spec doesn't say a word on implementations. Also, why should tail call optimization should be standardized? There is a use case, but aren't there other implementation optimizations that could be considered? Should they all been standardized? Why this one in particular? Really, once again, an appendix named hints for implementors or a different document or a page on the wiki would be better than a normative section. Saying that ECMAScript implementations aren't standard because they do not support one programming style sounds like a lot. Regarding tail call optimization, as far as I'm concerned, an agreement between implementors sounds like a more reasonable approach. There is no way in the language to test this feature. In this video [1], David Herman explains that a test can be written (at 40:40), but the test relies on implementation limitations rather than the language by itself (unlike all tests that can currently be found on test262). That is true, but whether some property can be observed from within the language itself, or only by its environment, is not relevant. It is not for people who write programs, it is for implementors because it directly impacts their work. They are not implementing a language anymore (which they still were as of ES5.1), but a language and some implementation constraints. Let imagine for a minute that tomorrow, implementors find another implementation trick which allows to run without crash the use cases that motivated the proper tail calls proposal, why would it be problematic? Why does it have to be this optimization in particular? There is no test that
Re: {Weak|}{Map|Set}
On Sep 16, 2011, at 5:14 AM, Andreas Rossberg wrote: ... Consider writing a server. If I cannot rely on tail call optimization then writing its message loop as a recursive function (e.g. actors style) would be incorrect. If I cannot rely on GC, then allocating an object for each received message would be incorrect. But at the extreme you can't rely on GC. Any allocation may be the one that exhausts actual available storage or triggers a interminable GC thrashing of virtual memory. In the real world these are quality of implementation issues that developers must deal with via load testing on real implementations. If I cannot rely on weak maps, then, say, mapping every message object to a return IP would be incorrect. A WeakMap reliably maintains a mapping from an object to a value. If you have access to an object key then you can rely upon a WeakMap preserving any mappings it has for that key. What you can not rely upon is the timely recycling of any resources that are used to represent inaccessible WeakMap mappings. This is the exact situation that exists for any ECMAScript dynamic allocation. There are no guarantees in the ES spec. that resources allocated with an inaccessible object will be freed in a timely manner or ever. Given the state of the art of memory management isn't clear how you could make such guarantees without unreasonably limiting implementors. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Sep 16, 2011, at 10:52 AM, Mark S. Miller wrote: On Fri, Sep 16, 2011 at 10:41 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: [...] This is the exact situation that exists for any ECMAScript dynamic allocation. There are no guarantees in the ES spec. that resources allocated with an inaccessible object will be freed in a timely manner or ever. Given the state of the art of memory management isn't clear how you could make such guarantees without unreasonably limiting implementors. Does everyone, on both sides of this debate, agree that the WeakMap GC issue is and the tail-call issue are equivalent specification problems? I propose that the way to look at both of these is a way I have seen proposed somewhere[1] about how to deal with specifying tail calls. Rather than taking it as a correctness criteria on an implementation, instead view it as a statement about how to analyze the space complexity of programs. When writing Andreas' server, it would be nice if he could analyze whether his algorithms have O(1) asymptotic space complexity. Does this mean it will succeed on every implementation? Of course not. It may be that a given implementation doesn't even have enough memory for the server to load. Or the server might crash for other reasons. In order to do this analysis, we need a model of how much memory is retained by a computational state -- not in terms of how many bytes, but in terms adequate to make statements about asymptotic space complexity. Then an implementation that runs out of space on programs held to be reasonable by such analysis can be viewed as low quality implementations. This all sounds reasonable but I don't see how it particularly impacts the actual specification. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Fri, Sep 16, 2011 at 12:41 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: [...] This all sounds reasonable but I don't see how it particularly impacts the actual specification. The spec has multiple customers. I agree it doesn't change the spec's normative requirements on implementors. If this simply gets demoted to clear a non-normative note, I think that would be fine. Do you agree that the specification of the weak map gc issue should be handled the same way as the tail call issue? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Fri, Sep 16, 2011 at 3:13 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: I'm not sure exactly how we are going to specify tail calls. I know that Dave Herman has ideas that I assume we will build upon . For weak maps I think that a non-normative note that make explicit the doesn't leak expectation and points implementors towards an ephemeron based implementation will suffice. +1. At least until we see how Dave proposes specing tail calls to see if he has any ideas we might adapt. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Sep 14, 2011, at 9:42 PM, Kyle Simpson wrote: I too have been confused by the name weakmap...partially because the name is misleading, and partially because documentation on it is ambiguous/misleading. Specifically, weakmap really means weakkeymap, because only the key is weak, not the value. But then again, weakkeymap would be even more implementation-instead-of-semantics naming. We've discussed the naming of this abstraction several times: https://mail.mozilla.org/pipermail/es-discuss/2010-July/011465.html resulted in WeakMap name https://mail.mozilla.org/pipermail/es-discuss/2010-September/011711.html https://mail.mozilla.org/pipermail/es-discuss/2011-May/014211.html and at least two of the above threads seem to have their start in confusion over the meaning of weak in this context. I continue to think that WeakMap is a poor name (although it is much better than EphemerionMap, which it replaced). To me, weak in this context is not a meaningful term for everyday programmers. It is GC jargon. It also adds nothing to a user's conceptual model of the abstraction. If a map is a non-enumerable associative table, then you would never want to have a nonweakMap as that would simply be a leaky map, i.e a buggy map implementation. Perhaps it can be argued is that, in the case of WeakMap, the Weak really is intended to mean nonleaky/nonbuggy and that this is necessary to make this explicit because of the prevalence of leaky map implementations in other languages. I would prefer ObjectMap (the keys are restricted to objects). ObjectRegistry is another possibility that is suggestive of a primary use cases. Kyle's suggestion of Map would also be fine although I think there is a valid objection that the name is too general (and perhaps too conflict prone) given that the keys may not be values other than objects. This issue keeps coming back around, starting with different people. Perhaps the present name really is a problem and we could revisit it. Is not, my guess is that we will see the same issue again. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
The reference to private is actually in the Map, Set classes shown below. The BNF is also below: CallExpression : ... private ( AssignmentExpression ) ConstructorElement : ... PrivateVariableDefinition PrivateVariableDefinition : private ExportableDefinition class Map { private keys, vals; constructor() { private(this).keys = []; private(this).vals = []; } get(key) { const keys = private(this).keys; const i = indexOfIdentical(keys, key); return i 0 ? undefined : private(this).values[i]; } has(key) { const keys = private(this).keys; return indexOfIdentical(keys, key) = 0; } set(key, val) { const keys = private(this).keys; const vals = private(this).vals; let i = indexOfIdentical(keys, key); if (i 0) { i = keys.length; } keys[i] = key; vals[i] = val; } delete(key) { const keys = private(this).keys; const vals = private(this).vals; const i = indexOfIdentical(keys, key); if (i 0) { return false; } keys.splice(i, 1); vals.splice(i, 1); return true; } // todo: iteration } class Set { private map; constructor() { private(this).map = Map(); } has(key) { return private(this).map.has(key); } add(key) { private(this).map.set(key, true); } delete(key) { return private(this).delete(key); } // todo: iteration } From: Kam Kasravi kamkasr...@yahoo.com To: Mark S. Miller erig...@google.com Cc: es-discuss es-discuss@mozilla.org Sent: Wednesday, September 14, 2011 7:53 PM Subject: Re: {Weak|}{Map|Set} I noticed that these class definitions declare private names within the class body but not the constructor. My latest read of the class proposal was that private could only be declared within the constructor. Have I interpreted the BNF incorrectly? On Sep 14, 2011, at 6:20 PM, Mark S. Miller erig...@google.com wrote: On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree. Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking I need a non-enumerable table. Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ 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: {Weak|}{Map|Set}
On Wed, Sep 14, 2011 at 11:47 PM, Kam Kasravi kamkasr...@yahoo.com wrote: The reference to private is actually in the Map, Set classes shown below. Hi Kam, You're correct. Fixed now. Thanks for pointing it out. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. People who know a bit about GC also confuse WeakMap with WeakRef/WeakPtr, which we have only in the strawman space: http://wiki.ecmascript.org/doku.php?id=strawman:weak_references /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On 15 September 2011 09:10, Brendan Eich bren...@mozilla.com wrote: On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. I don't. :) It is true to some extent that WeakMap is GC jargon -- but as Mark points out, the normal use case for weak maps _is_ to ensure a certain space behaviour closely related to GC. So why obfuscate the very intent by purposely avoiding what is more or less standard terminology for it (if slightly ambiguous)? If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. ObjectMap would be too generic a name to catch my immediate attention. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. But if you're actually aware of weakrefs (as I am), and you're searching for them in JS (as I was), and you see WeakMap (as I did), and you make the conclusion that Weak in the name means in fact weak references (as I did), then you probably also (as I did) assume that *all* the refs are weak. That's a failed conclusion, because only the keyrefs are weak. The name doesn't do anything to enlighten you that it only offers weak keyrefs and not weak valuerefs -- in fact, by your discovery line of reasoning, the name is almost a landmine that traps/misleads someone who does in fact know about weakrefs -- someone who didn't know about weakrefs wouldn't necessarily make the same deductive assumption by seeing weak in the name. Misleading/confusing with an API name is, IMHO, worse than less implementation-self-descriptive naming. --Kyle ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
Why constrain WeakMap to object keys, but not Map and Set ? I think it is because Weak only makes sense for object keys. However, if we base the distinction on iterability rather than weakness as David suggested, then we do not have to include an object key constraint anywhere. We could have: Map - current WeakMap minus object key constraint IterableMap - current Map Set - a WeakSet (David's above use case) minus object key constraint IterableSet - current Set This would also encourage use of the non-leaky abstractions where iterability is not a requirement. Also, what are the iteration order semantics ? Consider the following: let s = new Set // i.e. IterableSet s.add(0); s.add(1); // clearly [0,1] here s.add(0); // [1, 0] now ? s.delete(0); s.add(0); // clearly [1, 0] here let m = new Map; // i.e. IterableMap m.set(0, 2); m.set(1, 2); // clearly [0,1] here m.set(0, 2); // set to existing value // [1, 0] now ? m.set(0, 3); // actually change value // [1, 0] now ? m.delete(0); m.set(0, 2); // clearly [1, 0] here Also, for the iteration API of Map (i.e. IterableMap) and Set (i.e. IterableSet), why not integrate with iterators [1] : let m = new Map, s = new Set; ... for(i of m.iterator()) { ... } for(i of s.iterator()) { ... } [1] http://wiki.ecmascript.org/doku.php?id=harmony:iterators On Thu, Sep 15, 2011 at 2:10 AM, Brendan Eich bren...@mozilla.com wrote: On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. People who know a bit about GC also confuse WeakMap with WeakRef/WeakPtr, which we have only in the strawman space: http://wiki.ecmascript.org/doku.php?id=strawman:weak_references /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Thanks, Sean Eagan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
Hi Kyle, It would be great if we found a name that suggested the full meaning of the abstraction by itself. WeakMap is certainly not that. Sometimes we find something like this. Also important is one that avoids suggesting any misunderstandings. I agree that ObjectMap beats WeakMap on those grounds. As to the importance of naming for purpose, which is the contrary argument here, I have a question for you. You say and you're searching for them in JS (as I was). Had the abstraction been called ObjectMap or ObjectRegistry, would you have found it? As it was, you found the right thing to look at and think about, but you needed to read more before you understood whether it serves your actual purpose. Was this a better outcome than not finding it? Other alternate names that were discussed in that thread, listed from my least to most favorite: * NonLeakyObjectMap // accurate and suggestive, but a mouthful * WeakKeyMap // inaccurate, less so than the conclusion Kyle lept to * EphemeralMap // accurate and suggestive, and far enough from weak to avoid quick misunderstandings The reason WeakKeyMap is technically inaccurate is that in var wkm = WeakKeyMap(); var k = {}; wkm.set(k, [k]); k = null; the k - [k] association is no longer reachable. However, because weak key maps are built on the use of a weak reference to point at the key, and to receive notification of the key's demise, no weak key map can collect the above cyclic garbage association.[1] That's what's so important about ephemerons: the collector knows about such associations, rather than knowing about the key separately from knowing about the value. That's why I like WeakMap best -- it is the mapping that is weak, not the keys or the values. Nevertheless, given the magnitude of misunderstandings people are worried about here, perhaps this technical inaccuracy is the lesser evil. But my own preference remains WeakMap first and then EphemeralMap. [1] wkm holds onto each value strongly until it notices the corresponding key's demise. In this case, the value holds onto the key strongly, so wkm has no demise to notice. On Thu, Sep 15, 2011 at 7:56 AM, Kyle Simpson get...@gmail.com wrote: If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. But if you're actually aware of weakrefs (as I am), and you're searching for them in JS (as I was), and you see WeakMap (as I did), and you make the conclusion that Weak in the name means in fact weak references (as I did), then you probably also (as I did) assume that *all* the refs are weak. That's a failed conclusion, because only the keyrefs are weak. The name doesn't do anything to enlighten you that it only offers weak keyrefs and not weak valuerefs -- in fact, by your discovery line of reasoning, the name is almost a landmine that traps/misleads someone who does in fact know about weakrefs -- someone who didn't know about weakrefs wouldn't necessarily make the same deductive assumption by seeing weak in the name. Misleading/confusing with an API name is, IMHO, worse than less implementation-self-**descriptive naming. --Kyle -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Sep 15, 2011, at 6:49 AM, Andreas Rossberg wrote: On 15 September 2011 09:10, Brendan Eich bren...@mozilla.com wrote: On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. I don't. :) It is true to some extent that WeakMap is GC jargon -- but as Mark points out, the normal use case for weak maps _is_ to ensure a certain space behaviour closely related to GC. No the normal use case for WeakMaps is simply to make associations between objects and arbitrary values. The special GC behavior is necessary to avoid memory leaks, but that is a quality of implementation issue, not a use case. The typical JS programmer who wants to form such associations is not going to be thinking about the possibility of a leaky map unless they have already been burnt by them in some other language. So why obfuscate the very intent by purposely avoiding what is more or less standard terminology for it (if slightly ambiguous)? If I was a programmer looking for something like weak referencing in JS for the first time, weak is what I'd be searching for. ObjectMap would be too generic a name to catch my immediate attention. Because, the majority of JS programmers will simply be looking for a way to map objects to values and will not be thinking about GC consequences. We want them to find this thing we are currently trying to name. We don't want them to miss it because it has weak in its name and they don't know what weak means. We need to design first for the 95% (ass generated number) of JS programmers who don't understand GC. Finally, none are good exemplars for typical JS programmers. We (and our friends) know too much and in general have a level of PL expertise that far exceeds that of the typical JS programmer. In cases such as this our expectations may be the exact opposite of a typical JS programmer. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Thu, Sep 15, 2011 at 8:41 AM, Sean Eagan seaneag...@gmail.com wrote: Why constrain WeakMap to object keys, but not Map and Set ? I think it is because Weak only makes sense for object keys. However, if we base the distinction on iterability rather than weakness as David suggested, then we do not have to include an object key constraint anywhere. Hi Sean, that is a perfect example of how quickly we could go from de-emphasizing the purpose to losing the purpose. With this restriction relaxed, I can well imagine programmers using large numbers or strings as keys, thinking the corresponding association would be collected when those numbers or strings no longer otherwise exist in their program. Programmers coming from languages where boxed large numbers or strings have an observable unique identity will be especially prone to fall into this trap. The result is that their program has a memory leak that remains silent until they stress their program enough to run out of memory. At which point, they may have great difficultly tracking down the cause -- especially if this misuse of *Map is buried in some library written by someone else. Given the normal invisibility of the symptom, this is quite likely. Better to error early with a clear diagnostic, so no one is confused about what keys can be usefully used. Which btw, does bring up one way in which the FF implementation of WeakMaps is too strict. By the above reasoning, we should reject non-objects in the key position of a .set(). We need not reject it in the key position of a .get(), .has(), or .delete(). All all cases, we know that a non-object key cannot correspond to any stored association, so .get(), .has(), and .delete() can respond as if for any other not-found key. We could have: Map - current WeakMap minus object key constraint IterableMap - current Map Set - a WeakSet (David's above use case) minus object key constraint IterableSet - current Set This would also encourage use of the non-leaky abstractions where iterability is not a requirement. Also, what are the iteration order semantics ? Consider the following: let s = new Set // i.e. IterableSet s.add(0); s.add(1); // clearly [0,1] here s.add(0); // [1, 0] now ? s.delete(0); s.add(0); // clearly [1, 0] here let m = new Map; // i.e. IterableMap m.set(0, 2); m.set(1, 2); // clearly [0,1] here m.set(0, 2); // set to existing value // [1, 0] now ? m.set(0, 3); // actually change value // [1, 0] now ? m.delete(0); m.set(0, 2); // clearly [1, 0] here Also, for the iteration API of Map (i.e. IterableMap) and Set (i.e. IterableSet), why not integrate with iterators [1] : let m = new Map, s = new Set; ... for(i of m.iterator()) { ... } for(i of s.iterator()) { ... } [1] http://wiki.ecmascript.org/doku.php?id=harmony:iterators On Thu, Sep 15, 2011 at 2:10 AM, Brendan Eich bren...@mozilla.com wrote: On Sep 14, 2011, at 11:09 PM, Allen Wirfs-Brock wrote: I would prefer ObjectMap (the keys are restricted to objects). Now that you point it out (again), I agree. People who know a bit about GC also confuse WeakMap with WeakRef/WeakPtr, which we have only in the strawman space: http://wiki.ecmascript.org/doku.php?id=strawman:weak_references /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Thanks, Sean Eagan -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Thu, Sep 15, 2011 at 8:47 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: [...] No the normal use case for WeakMaps is simply to make associations between objects and arbitrary values. The special GC behavior is necessary to avoid memory leaks, but that is a quality of implementation issue, not a use case. The typical JS programmer who wants to form such associations is not going to be thinking about the possibility of a leaky map unless they have already been burnt by them in some other language. I do not know of a non-leak-association-map in *any* other language or library whose name does not suggest its GC role. Do you know of a counter-example? If not, then let's say ...burnt by them in every other language A programmer approaching ES6 wanting simply to make associations and not thinking about GC issues will probably reach for the (iteratable) Map anyway, which is how it should be. For them, the iterability of these maps will often be seen as a virtue. If they are unconcerned about storage, they will usually see little reason to give up on this iterability. Because, the majority of JS programmers will simply be looking for a way to map objects to values and will not be thinking about GC consequences. We want them to find this thing we are currently trying to name. We don't want them to miss it because it has weak in its name and they don't know what weak means. We need to design first for the 95% (ass generated number) of JS programmers who don't understand GC. Those programmers *should* find our interatable maps, not our weak-association maps. Finally, none are good exemplars for typical JS programmers. We (and our friends) know too much and in general have a level of PL expertise that far exceeds that of the typical JS programmer. In cases such as this our expectations may be the exact opposite of a typical JS programmer. There are many kinds and levels of programmers. For the typical programmers you talk about, I'd just point them at our current iteratable Maps and Sets. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Thu, Sep 15, 2011 at 8:41 AM, Sean Eagan seaneag...@gmail.com wrote: Also, for the iteration API of Map (i.e. IterableMap) and Set (i.e. IterableSet), why not integrate with iterators [1] : let m = new Map, s = new Set; ... for(i of m.iterator()) { ... } for(i of s.iterator()) { ... } That is the intention -- it's what that mysterious // todo: iteration note is about at http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets. At the time this was written, iterators hadn't yet settled down. Your suggestion about iteration semantics and order is helpful. Thanks. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On 15 September 2011 17:47, Allen Wirfs-Brock al...@wirfs-brock.com wrote: No the normal use case for WeakMaps is simply to make associations between objects and arbitrary values. The special GC behavior is necessary to avoid memory leaks, but that is a quality of implementation issue, not a use case. Just like with tail calls, certain space optimizations are semantically relevant, because code will rely on them and potentially break if they are not performed. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
You say and you're searching for them in JS (as I was). Had the abstraction been called ObjectMap or ObjectRegistry, would you have found it? I don't think the API name is the only way someone can discover what they're looking for. Proper documentation for ObjectMap which said keyrefs are held weakly or something to that respect would probably have ended up on my search radar. Of course, if the WeakMap really was both weak-key and weak-value, then I'd absolutely expect the name to be WeakMap (I think weak in this case is a useful and non-trivial part of the behavior). So my complaint is not Weak, but that Weak implies something more comprehensive than is actually the case. It over-promises and under-delivers, so to speak. I should also clarify my process for how I found this API (I over-simplified in my previous email). I actually started out with both the weakref need AND the object-as-key (map) need. For the object-as-key need, I had already constructed a dual-numerically-indexed-array solution to associating an object with a value. But then, realizing that this was not only clunky, but also was going to make manual GC (that is, cleaning up the entries if the object is removed) also more awkward/less performant, I started looking for an API that would do both: Map (object-as-key) and automatically clean up the entries in the Map if either the key-object or the value-object (in my case, both DOM objects) were GC'd. In that context (and in support of Allen's early assertions), Map in the name was most important to focus me into a (theoretical) class of APIs (if there were indeed several different kinds of maps). Then I would have searched through the documentation to see if any of the Maps had the weak behavior I was looking for. OTOH, had I *only* been looking for pure Weak References, and not a Map structure, then I'd have been looking for some API like WeakRef, and actually Map probably would have been confusing or ignorable noise. As it was, you found the right thing to look at and think about, but you needed to read more before you understood whether it serves your actual purpose. I found it because a fellow Mozilla dev said hey, that sounds like WeakMaps and I thought awesome, ask and ye shall find. Of course, the devil was in the details, because it wasn't actually what I needed completely. This was compounded by the fact that the MDN documentation (at least at the time) was ambiguous and didn't make it clear that only keys were weak. So a well-experienced co-worker and the documentation BOTH were confused (as were several others through various IRC chats) as to exactly what was and was not weak in the WeakMap. How did I figure it out? By writing it into my code, and then seeing mem-leak tests fail. Thankfully, I eventually found some IRC people who clarified that what I was seeing was not a bug but was in fact by-design. But, that's a hard way to learn the lesson. Would a more accurate name have helped? Perhaps. WeakKeyMap certainly would have made it obvious that the Map was not fully weak. Would more accurate documentation have helped? Absolutely. Would naming *and* documentation have helped other co-workers not be misled and consequently point me in the wrong path? I hope so. That's why I like WeakMap best -- it is the mapping that is weak, not the keys or the values. I understand what you're saying here. But as I mentioned before, the way my (far less informed) brain thinks about it, the map or link between two objects should in fact be weak and ephemeral enough that either side going away (being GC'd) should be enough to cause the link between the two to be cleaned up. I think it's because I tend to think of Map as more 2-way than one-way, though I understand it's technically only 1-way. Saying it a different way... if the focus is on the map or link itself, and the RHS thing the map/link is pointing to is no longer valid/defined, then what use is there keeping a link that points to something now undefined? It just seems a little unfortunate/misleading to me that from an implementation perspective, creating the map/link is sufficient to prevent the RHS value in question from ever getting to that undefined state. When I create a reference using variables/properties, I *expect* a hard reference that behaves like that. But when I use a specialized API with Weak in the name, I definitely expect the opposite. --Kyle ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Sep 15, 2011, at 9:07 AM, Mark S. Miller wrote: On Thu, Sep 15, 2011 at 8:47 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: [...] No the normal use case for WeakMaps is simply to make associations between objects and arbitrary values. The special GC behavior is necessary to avoid memory leaks, but that is a quality of implementation issue, not a use case. The typical JS programmer who wants to form such associations is not going to be thinking about the possibility of a leaky map unless they have already been burnt by them in some other language. I do not know of a non-leak-association-map in *any* other language or library whose name does not suggest its GC role. Do you know of a counter-example? If not, then let's say ...burnt by them in every other language Probably not, but in most (if not all cases) those other languages what already used up the good names on leaky versions and needed to define more explicit names for the non-leaky versions that were later additions. We don't have that heritage. We can do our naming starting from a clean slate. My speculation is that over the long run, many more programmers will be first introduced to these data structures via JS than will come to it after already being corrupted by some other broken language. A programmer approaching ES6 wanting simply to make associations and not thinking about GC issues will probably reach for the (iteratable) Map anyway, which is how it should be. For them, the iterability of these maps will often be seen as a virtue. If they are unconcerned about storage, they will usually see little reason to give up on this iterability. iterability makes Map inherently leaky from an application logic perspective. If you place a key in a Map you must manually delete if you don't want to retain it for the full life of the map. For this reason, the fact that a map is iteratable should probably be featured in its name. Using Map as the name of iteratable associative maps is probably an attractive nuance. From that perspective, the names I suggest are: IteratableMap -- currently Map, iteratatble associations between arbitrary valued keys and values ObjectMap - currently WeakMap, non-iteratable associations between object valued keys and arbitrary values It might be even better to even further increate the conceptual distance between to two abstractions by not using map in both names. In that case, ObjectRegistry might be better than ObjectMap. Because, the majority of JS programmers will simply be looking for a way to map objects to values and will not be thinking about GC consequences. We want them to find this thing we are currently trying to name. We don't want them to miss it because it has weak in its name and they don't know what weak means. We need to design first for the 95% (ass generated number) of JS programmers who don't understand GC. Those programmers *should* find our interatable maps, not our weak-association maps. Only if they need to iterate over them. If not, the weak association maps is what they should find. (with the caveat, that I still have concerns about the potential impact of heavy use of ephemeron based maps upon GC performance.) Finally, none are good exemplars for typical JS programmers. We (and our friends) know too much and in general have a level of PL expertise that far exceeds that of the typical JS programmer. In cases such as this our expectations may be the exact opposite of a typical JS programmer. There are many kinds and levels of programmers. For the typical programmers you talk about, I'd just point them at our current iteratable Maps and Sets. However, for them, application level leaks are often a problem. Except for situations where they actually need to iterate they are better served by being pointed towards WeakMap. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
{Weak|}{Map|Set}
Hi, I have come across use cases where i didn't need a Weak/Map/, but rather a Weak/Set/ which is that I didn't need to set a value. Usually, i set true but feel like I'm doing something useless. The API I actually need is: * .add(obj) (add an element to the set which is one in WeakMaps with .set) * .delete(obj) Even if i haven't had the need for it, a .has(obj) method would be relevant as well for WeakSets. Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.comwrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree. Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking I need a non-enumerable table. Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
I noticed that these class definitions declare private names within the class body but not the constructor. My latest read of the class proposal was that private could only be declared within the constructor. Have I interpreted the BNF incorrectly? On Sep 14, 2011, at 6:20 PM, Mark S. Miller erig...@google.com wrote: On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree. Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking I need a non-enumerable table. Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ 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: {Weak|}{Map|Set}
I too have been confused by the name "weakmap"...partially because the name is misleading, and partially because documentation on it is ambiguous/misleading. Specifically, "weakmap" really means "weakkeymap", because only the key is weak, not the value. But then again, "weakkeymap" would be even more implementation-instead-of-semantics naming.To me, the name "weakmap" means weakkey *and* weakref (weak value), and that is what I'd like: to be able to create a link (map) between two arbitrary objects, where the link only exists if both sides are still valid, and is killed (GC'd) if either or both go away. This type of functionality is useful for a system like a generalized event triggering mechanism, for instance. It's also useful for a devtool like an HTML inspector which needs to link a main-page DOM object to a representation DOM object in the tool. When I brought up this idea in IRC awhile back I suggested the name "ReallyWeakMap". :)Yes, I'm aware of the reasons why weakrefs aren't in JSI just still think it's a shame that we can't figure out a way for GC of weakrefs not to "leak" info to separate security sandboxes.Anyway, why couldn't we just call it "Map" or "KeyMap" and drop any mention of "weak"?--KyleOn Sep 14, 2011 6:20 PM, Mark S. Miller erig...@google.com wrote: On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of "weak" references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference.In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree.Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking "I need a non-enumerable table". Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss