Re: private name objects confusion

2011-07-28 Thread David Herman
> Yep. Sorry, editing snafu -- I'd started to call it a non-issue when it 
> occurred to me that proxy authors would still have to know not to string 
> coerce keys. No big deal -- proxy authors should know better than to rely on 
> es5 invariants.

Agreed.

> Throw at the point where a unique name from a getOPN array is coerced to a 
> string. AFAICT this will always indicate a logic bug. One way to enforce this 
> would be to have getOPN (and enumerate?) hand out public objects with special 
> toStrings that throw. Meh. That's why I said there's "sane" way :)

Yikes. :)

> 
> Another alternative for unique-but-public names is simply to have a unique 
> string generator. It trivially maintains the invariants of getOPN and 
> for...in while still having the same user experience for getting and setting. 
> The downsides are that the string will probably be ugly and unpleasant for 
> debugging, and that there's no efficient way to ensure that the string 
> generated won't be one that's *never* been observed by the program so far. 
> You'd probably have to use UUIDs, which are ugly.
> 
> Yes, this is precisely what I meant when I said a unique string could be 
> used. But again, I wonder if worth it. If a producer of unique name objects 
> can provide the internal string it's trivial to generate UUIDs (or any other 
> type of unique string) should they so choose.

Right, this is already something you can express in the language. I sense YAGNI.

> But from a spec standpoint is it a good idea to actively encourage the 
> toStringing of getOPN keys?

What I meant was that we could not provide the visibility flag -- i.e., not 
have a notion of "unique names" at all -- but simply provide a makeUUID() 
function that produces a string which can be used directly as a property name.

> A bigger problem: what happens when you have two unique name objects where 
> both have a "foo" internal string and you toString the result of getOPN? Bad 
> things, right?

Right. This issue is why I suggested using UUID strings instead. It wouldn't be 
possible to have two properties with different unique names that produce the 
same UUID result of toString().

> Another alternative would be to explicitly disallow custom internal strings 
> for unique name objects, and give them a consistent toString behavior (e.g. 
> always generate unique strings). But this smells too, partly for the reasons 
> you pointed out, and also because the semantics of the two name types start 
> to diverge.

Agreed.

> So I wonder: what does this particular reflection buy you that you can't just 
> as easily attain by explicitly exposing your "visible" private name objects?

The only thing is that you can't introspect on them conveniently. If you have 
access to a private name, it'd be nice to have a simple way of saying "give me 
all of the names, including the private names I know about." But I don't see a 
simple way of doing that other than something like a variant of getOPN:

Object.getOwnPropertyNames(o, p) : function(Object, WeakMap?) -> 
[string | name]

This version would produce an array of all property names including any private 
names that are in the given table. (This is technically a conservative 
extension of the existing ES5 getOPN but it could alternatively be provided as 
a different function.)

Again, this would be implementable without providing it as a core API, so I'm 
not sure if it's worth it. Standardizing on this use of a map seems like it 
might be premature; you might want any number of different ways of representing 
"these are the private names I know about."

Dave

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


Re: private name objects confusion

2011-07-27 Thread Dean Landolt
On Wed, Jul 27, 2011 at 7:21 PM, David Herman  wrote:

> > Understood WRT the forgeability of strings -- I was more concerned with
> the potential hazard of toStringing the values of an own-names array, only
> to find out you have several keys with the string value "undefined". Sure
> you're doing it wrong, but string keys are an es5 invariant -- it's bound to
> happen, as you hinted at in your reply.
>
> Yeah, this has come up several times in discussions. It's currently an
> invariant that for...in and getOPN produce a sequence of strings with no
> duplicates (though not in fully specified order), and exposing name objects
> to these operations would break that invariant.
>
> > But now that you've clarified the reflection semantics it's clear that
> this is not much of an non-issue for non-reflective "private" names,
>
> ITYM "not much of an issue", right?
>

Yep. Sorry, editing snafu -- I'd started to call it a non-issue when it
occurred to me that proxy authors would still have to know not to string
coerce keys. No big deal -- proxy authors should know better than to rely on
es5 invariants.


>
> > just another note for proxy authors. Of course, if the visibility flag
> becomes harmonious (and I really hope it does!) it's still a bit of a
> problem for these "unique" names. There's no need for unforgeability here so
> a unique string could be used, but it's probably too much magical and too
> little help -- if unintentionally used (the result of an own-names string
> coercion) it papers over a deeper semantic bug. Better would be to throw,
> but there's no sane way to do that.
>
> Throw where, exactly? I don't quite follow you.
>

Throw at the point where a unique name from a getOPN array is coerced to a
string. AFAICT this will always indicate a logic bug. One way to enforce
this would be to have getOPN (and enumerate?) hand out public objects with
special toStrings that throw. Meh. That's why I said there's "sane" way :)

Another alternative for unique-but-public names is simply to have a unique
> string generator. It trivially maintains the invariants of getOPN and
> for...in while still having the same user experience for getting and
> setting. The downsides are that the string will probably be ugly and
> unpleasant for debugging, and that there's no efficient way to ensure that
> the string generated won't be one that's *never* been observed by the
> program so far. You'd probably have to use UUIDs, which are ugly.
>

Yes, this is precisely what I meant when I said a unique string could be
used. But again, I wonder if worth it. If a producer of unique name objects
can provide the internal string it's trivial to generate UUIDs (or any other
type of unique string) should they so choose. But from a spec standpoint is
it a good idea to actively encourage the toStringing of getOPN keys? A
bigger problem: what happens when you have two unique name objects where
both have a "foo" internal string and you toString the result of getOPN? Bad
things, right?

Another alternative would be to explicitly disallow custom internal strings
for unique name objects, and give them a consistent toString behavior (e.g.
always generate unique strings). But this smells too, partly for the reasons
you pointed out, and also because the semantics of the two name types start
to diverge.

So I wonder: what does this particular reflection buy you that you can't
just as easily attain by explicitly exposing your "visible" private name
objects?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: private name objects confusion

2011-07-27 Thread David Herman
> Understood WRT the forgeability of strings -- I was more concerned with the 
> potential hazard of toStringing the values of an own-names array, only to 
> find out you have several keys with the string value "undefined". Sure you're 
> doing it wrong, but string keys are an es5 invariant -- it's bound to happen, 
> as you hinted at in your reply.

Yeah, this has come up several times in discussions. It's currently an 
invariant that for...in and getOPN produce a sequence of strings with no 
duplicates (though not in fully specified order), and exposing name objects to 
these operations would break that invariant.

> But now that you've clarified the reflection semantics it's clear that this 
> is not much of an non-issue for non-reflective "private" names,

ITYM "not much of an issue", right?

> just another note for proxy authors. Of course, if the visibility flag 
> becomes harmonious (and I really hope it does!) it's still a bit of a problem 
> for these "unique" names. There's no need for unforgeability here so a unique 
> string could be used, but it's probably too much magical and too little help 
> -- if unintentionally used (the result of an own-names string coercion) it 
> papers over a deeper semantic bug. Better would be to throw, but there's no 
> sane way to do that.

Throw where, exactly? I don't quite follow you.

Another alternative for unique-but-public names is simply to have a unique 
string generator. It trivially maintains the invariants of getOPN and for...in 
while still having the same user experience for getting and setting. The 
downsides are that the string will probably be ugly and unpleasant for 
debugging, and that there's no efficient way to ensure that the string 
generated won't be one that's *never* been observed by the program so far. 
You'd probably have to use UUIDs, which are ugly.

> Ah well, this is great stuff. Thanks again, Dave...

Glad to hear it!

Dave

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


Re: private name objects confusion

2011-07-27 Thread Dean Landolt
On Wed, Jul 27, 2011 at 5:02 PM, David Herman  wrote:

> > I've been exploring private name objects [1] and I'm a bit confused by a
> few things in the proposal, especially the Reflection example...
>
> The page was out of date, sorry. I've updated the page to reflect the
> agreement we came to in the last face-to-face, which was that private names
> should not be reflected anywhere except to proxy traps. This leaks less
> information than what was on the wiki. In particular, now you can't figure
> out how many private names an object is carrying around.
>

Perfect! This is exactly what I was hoping for.

[snip]

I've separated this out on the wiki page as a remaining open issue. I'm not
> sure if we've come to consensus about this case. (One concern was that
> Object.getOwnPropertyNames() and for...in no longer are guaranteed to
> produce strings, although this is mitigated by the toString() coercion of
> the name objects.)
>
> > I also see no mention of what `str` should default to in Name.create,
> even though it's defined as optional and is quite significant as the
> name.public.toString return value. Is there something like a unique string
> value planned for this? At the very least the proposal should hint at what
> Name.create().public.toString() should return (assuming it's not undefined).
>
> This hasn't been settled yet. IMO, I don't think it needs to be guaranteed
> to be unique. The uniqueness guarantee is about the *identity* of the
> object, and strings are forgeable, even if they're unique at the time they
> are created.
>


Understood WRT the forgeability of strings -- I was more concerned with the
potential hazard of toStringing the values of an own-names array, only to
find out you have several keys with the string value "undefined". Sure
you're doing it wrong, but string keys are an es5 invariant -- it's bound to
happen, as you hinted at in your reply.

But now that you've clarified the reflection semantics it's clear that this
is not much of an non-issue for non-reflective "private" names, just another
note for proxy authors. Of course, if the visibility flag becomes harmonious
(and I really hope it does!) it's still a bit of a problem for these
"unique" names. There's no need for unforgeability here so a unique string
could be used, but it's probably too much magical and too little help -- if
unintentionally used (the result of an own-names string coercion) it papers
over a deeper semantic bug. Better would be to throw, but there's no sane
way to do that.

Ah well, this is great stuff. Thanks again, Dave...

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


Re: private name objects confusion

2011-07-27 Thread David Herman
> I've been exploring private name objects [1] and I'm a bit confused by a few 
> things in the proposal, especially the Reflection example...

The page was out of date, sorry. I've updated the page to reflect the agreement 
we came to in the last face-to-face, which was that private names should not be 
reflected anywhere except to proxy traps. This leaks less information than what 
was on the wiki. In particular, now you can't figure out how many private names 
an object is carrying around.

> Should this statement return ["foo", fooName.public] or ["foo", fooName]? If 
> the latter interpretation is correct, what advantage does a visible private 
> name have over a plain old non-enumerable property?

Guaranteed uniqueness. For example, multiple separately developed libraries can 
monkey-patch the same shared prototype object with new unique names and they're 
guaranteed not to conflict.

I've separated this out on the wiki page as a remaining open issue. I'm not 
sure if we've come to consensus about this case. (One concern was that 
Object.getOwnPropertyNames() and for...in no longer are guaranteed to produce 
strings, although this is mitigated by the toString() coercion of the name 
objects.)

> I also see no mention of what `str` should default to in Name.create, even 
> though it's defined as optional and is quite significant as the 
> name.public.toString return value. Is there something like a unique string 
> value planned for this? At the very least the proposal should hint at what 
> Name.create().public.toString() should return (assuming it's not undefined).

This hasn't been settled yet. IMO, I don't think it needs to be guaranteed to 
be unique. The uniqueness guarantee is about the *identity* of the object, and 
strings are forgeable, even if they're unique at the time they are created.

> My apologies if some of this has been discussed

Not at all; thanks for the feedback.

Dave

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


private name objects confusion

2011-07-27 Thread Dean Landolt
I've been exploring private name objects [1] and I'm a bit confused by a few
things in the proposal, especially the Reflection example...

module Name = require "@name";
let o = { };
let name = Name.create("foo");
o[name] = "secret!";
...let a = Object.getOwnPropertyNames(o);for (let i = 0; i < a.length; i++) {
if (a[i] === name.public)
...
else
...}


The proposal defaults Name.create's visibility to false, so my first
assumption was it's not supposed to show up at all in
Object.getOwnPropertyNames(o) and it was just an oversight. But after
rereading it a few times this line keeps throwing me (emphasis added):

The visible argument determines whether the name is made *directly* visible
to reflection API‘s.

Another possible interpretation is that if the name is set to visible then
getOwnPropertyNames would contain the name object, otherwise it would
contain name.public. Another way to ask this, modifying the example
slightly:

module Name = require "@name";
let o = { foo: "public!" };
let fooName = Name.create("foo");
o[fooName] = "secret!";
Object.getOwnPropertyNames(o);


Should this statement return ["foo"] or ["foo", fooName.public]? And if
visibility were true:

module Name = require "@name";
let o = { foo: "public!" };
let name = Name.create("foo", true);
o[name] = "secret!";
Object.getOwnPropertyNames(o);


Should this statement return ["foo", fooName.public] or ["foo", fooName]? If
the latter interpretation is correct, what advantage does a visible private
name have over a plain old non-enumerable property?

I also see no mention of what `str` should default to in Name.create, even
though it's defined as optional and is quite significant as the
name.public.toString return value. Is there something like a unique string
value planned for this? At the very least the proposal should hint at what
Name.create().public.toString() should return (assuming it's not undefined).

My apologies if some of this has been discussed -- the last I can find was
in the TC39 meeting notes from May:

Advanced to Harmony, with the big open issue of reflecting on private names.
>


[1] http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss