Re: {Weak|}{Map|Set}

2011-09-15 Thread Allen Wirfs-Brock
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}

2011-09-15 Thread Kam Kasravi
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}

2011-09-15 Thread Mark S. Miller
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}

2011-09-15 Thread Brendan Eich
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}

2011-09-15 Thread Andreas Rossberg
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}

2011-09-15 Thread Kyle Simpson

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}

2011-09-15 Thread Sean Eagan
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}

2011-09-15 Thread Mark S. Miller
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}

2011-09-15 Thread Allen Wirfs-Brock

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: IDE support?

2011-09-15 Thread Andreas Rossberg
On 13 September 2011 16:48, Brendan Eich bren...@mozilla.com wrote:
 On Sep 13, 2011, at 5:33 AM, Andreas Rossberg wrote:

 * There are extra costs in space and time to doing the runtime analysis.
 * Compile time is runtime, so there are severe limits to how smart you
 can afford to get in a compiler.

 These are bearable apples to trade against the moldy oranges you'd make the 
 world eat by introducing type annotations to JS. Millions of programmers 
 would start annotating for performance, i.e., gratuitously, making a 
 brittle world at high aggregate cost.

 The costs born in browsers by implementors and (this can hit users, but it's 
 marginal) at runtime when evaluating code are less, I claim.

Depends on how good you want to optimize. Aggressive compilers can be
really slow. There are limits to what you can bear at runtime.
Especially, when you have to iterate the process.


 * The massive complexity that comes with implementing all this affects
 stability.

 This one I'm less sympathetic to, since we won't get rid of untyped JS up 
 front. A sunk cost fallacy? If we could make a clean break (ahem), sure. 
 Otherwise this cost must be paid.

Well, the counter-argument would be that you wouldn't need to care
about optimising untyped code as much, if the user had the option to
switch to a typed sublanguage for performance.


 * Wrt limits, even in the ideal case, you can only approximate the
 performance of typed code -- e.g. for property access you have at
 least two memory accesses (type and slot) plus a comparison and
 branch, where a typed language would only do 1 memory access.

 That's *not* the ideal case. Brian Hackett's type inference work in 
 SpiderMonkey can eliminate the overhead here. Check it out.

I'm actually pretty excited about that, and hope to see more on that
front. Cool stuff.

However, that ideal case is achieved in a relatively small percentage
of cases only. Otherwise we should probably not see a (already
impressive) 20-40% speed-up (IIRC), but rather something closer to
200-400%.


 * Type inference might mitigate some more of these cases, but will be
 limited to fairly local knowledge.

 s/might/does/ -- why did you put type inference in a subjunctive mood? Type 
 inference in SpiderMonkey (Firefox nightlies) is not local.

Fair enough re the subjunctive. Still, there are principal limitations
to what type inference can do. Especially for OO. You hit on
undecidable territory very quickly. You also have to give up at
boundaries such as native bindings, calls to eval, or (in ES6) to the
module loader, unless you're given extra information by the programmer
(this is basically the separate compilation problem).

So the inferencer has to work with approximations and fallbacks. For a
language like JS, where a lot of conceptual polymorphism, potential
mutation, and untypable operations are going on, those
approximations will remain omnipresent, except, mostly, in
sufficiently local contexts.

Not to say that it is not worth extending the boundaries -- it
definitely is. But it will only get you that far.


 * Omnipresent mutability is another big performance problem in itself,
 because most knowledge is never stable.

 Type annotations or (let's say) guards as for-all-time monotonic bounds on 
 mutation are useful to programmers too, for more robust 
 programming-in-the-large. That's a separate (and better IMHO) argument than 
 performance. It's why they are on the Harmony agenda.

Of course I'd never object to the statement that there are far better
reasons to have typy features than performance. :) I just didn't
mention it because it wasn't the topic of the discussion.


 So despite all the cool technology we use these days, it is safe to
 assume that we will never play in the performance league of typed
 languages. Unless we introduce real types into JS, of course. :)

 Does JS need to be as fast as Java? Would half as fast be enough?

No, it doesn't have to be as fast. Not yet, at least... I estimate we
have another 3 years. ;)

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


Re: {Weak|}{Map|Set}

2011-09-15 Thread Mark S. Miller
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: IDE support?

2011-09-15 Thread Andreas Rossberg
On 13 September 2011 21:32, Wes Garland w...@page.ca wrote:

 When I write shell programs, and JS programs, I keep an extra terminal
 window open to a spare shell or a JS REPL.  I try stuff. Stuff that works, I
 copy into my program.  Then I run my program - which happens quickly,
 because the compiler is super-fast and the program is a contained entity
 which probably runs in a dynamically configured environment.

REPLs and quasi-instant compile turn-arounds are indeed great
features, but by no means exclusive to untyped languages, and never
have been. It just happens that the typed languages dominating the
mainstream suck badly in this area.

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


Re: IDE support?

2011-09-15 Thread Andreas Rossberg
On 14 September 2011 00:00, Brendan Eich bren...@mozilla.com wrote:

 So, static+dynamic. The static side has some powerful algorithms to bring to 
 bear. Dynamic is necessary due to eval and kin, and gives strictly more 
 information (and more relevant information!).

Nitpick: I believe you are mistaken about the strictly more bit.
There is information that _only_ static analysis can derive. Consider
e.g. aliasing or escape analysis, or other kinds of global properties.

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


Re: {Weak|}{Map|Set}

2011-09-15 Thread Mark S. Miller
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}

2011-09-15 Thread Mark S. Miller
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}

2011-09-15 Thread Andreas Rossberg
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}

2011-09-15 Thread Kyle Simpson
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}

2011-09-15 Thread Allen Wirfs-Brock

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


WeakPair primitive ?

2011-09-15 Thread Sean Eagan
Would a WeakPair primitive be useful...

let wp = new WeakPair(key, value);
...
if(wp.hasKey(key)) {
  foo(wp.value());
}

WeakMap could be built on top of this primitive:

class WeakMap {
  constructor() {
private pairs = new Set;
private getPair = function(key) {
  for(i of private(this).pairs.iterator()) {
if(i.hasKey(key)) return i;
  }
  return undefined;
}
  }
  get(key) {
let pair = private(this).getPair(key);
return pair ? pair.value() : undefined;
  }
  has(key) {
return !!private(this).getPair(key);
  }
  set(key, val) {
if(!isObject(key)) throw new Error;
let pair = private(this).getPair(key);
let pairs = private(this).pairs;
if(pair) {
  pairs.delete(pair);
}
pairs.add(new WeakPair(key, value));
  }
  delete(key) {
let pair = private(this).getPair(key);
if(pair) {
  let pairs = private(this).pairs;
  pairs.delete(pair);
}
  }
}

Are there other useful abstractions that could be built on top of
WeakPair, beyond WeakMap ?

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: WeakPair primitive ?

2011-09-15 Thread Allen Wirfs-Brock

On Sep 15, 2011, at 10:21 AM, Sean Eagan wrote:

 Would a WeakPair primitive be useful...
 
 let wp = new WeakPair(key, value);
 ...
 if(wp.hasKey(key)) {
  foo(wp.value());
 }
 
 WeakMap could be built on top of this primitive:

It's not that easy.  Read 
http://www.arnetminer.org/dev.do?m=downloadpdfurl=http://arnetminer.org/pdf/PDFFiles/--g---g-Index1247931776950/Ephemerons
 A New Finalization Mechanism1247944577286.pdf

You need Ephemeron pairs to build such abstractions

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


Re: IDE support?

2011-09-15 Thread Mike Shaver
On Thu, Sep 15, 2011 at 9:02 AM, Andreas Rossberg rossb...@google.com wrote:
 On 14 September 2011 00:00, Brendan Eich bren...@mozilla.com wrote:

 So, static+dynamic. The static side has some powerful algorithms to bring to 
 bear. Dynamic is necessary due to eval and kin, and gives strictly more 
 information (and more relevant information!).

 Nitpick: I believe you are mistaken about the strictly more bit.
 There is information that _only_ static analysis can derive. Consider
 e.g. aliasing or escape analysis, or other kinds of global properties.

There are systems that handle escape analysis cases via write
barriers, no?  Alias detection (or more importantly non-alias
determinations) seem amenable to the assume-and-guard model used for
PICs and trace selection and other code specialization patterns seen
all over modern JS engines.

The TraceMonkey engine tracks many global properties (including the
properties of globals) to deoptimize as needed and optimize where
possible; our TI and IonMonkey work goes even further.

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


Re: WeakPair primitive ?

2011-09-15 Thread Rick Waldron
WeakMap is in Harmony...
http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps

On Thu, Sep 15, 2011 at 1:47 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Sep 15, 2011, at 10:21 AM, Sean Eagan wrote:

 Would a WeakPair primitive be useful...

 let wp = new WeakPair(key, value);
 ...
 if(wp.hasKey(key)) {
  foo(wp.value());
 }

 WeakMap could be built on top of this primitive:


 It's not that easy.  Read 
 http://www.arnetminer.org/dev.do?m=downloadpdfurl=http://arnetminer.org/pdf/PDFFiles/--g---g-Index1247931776950/Ephemerons
 A New Finalization Mechanism1247944577286.pdf

 You need Ephemeron pairs to build such abstractions


 ___
 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