00:01
<ljharb>
like thenability is forgeable, instanceof is forgeable, brand checks are not
00:04
<ljharb>
iow identity is indeed unforgeable for objects and symbols, but forgeability goes way beyond just identity to me
00:04
<Bakkot>
webidl has a definition of "unforgeable", which applies to attributes: https://heycam.github.io/webidl/#dfn-unforgeable-on-an-interface
00:14
<devsnek>
ljharb: hm I guess it applies in a lot of situations
00:16
<devsnek>
in regard to values, it means you can't create a value with the same identity, you have to have the actual value to have the same identity
00:17
<devsnek>
which is the distinction we're using for weak collection keys
00:21
<Bakkot>
devsnek except the current proposal allows `Symbol.for` symbols, I think
00:21
<devsnek>
those are still unforgeable
00:22
<Bakkot>
not any more unforgeable than string literals, surely?
00:22
<devsnek>
symbol.for doesn't create new values, there's a cache
00:22
<Bakkot>
I don't understand the distinction between Symbol.for symbols and strings
00:22
<Bakkot>
what is the relevant distinction here?
00:22
<devsnek>
you can create caches of objects too
00:23
<Bakkot>
... so?
00:23
<devsnek>
I mean from some level of abstraction nothing is unforgeable because you can store it in something keyed by strings
00:23
<Bakkot>
neither Symbol.for symbols nor strings are objects
00:23
<Bakkot>
I don't see what the distinction between those two things is
00:24
<Bakkot>
I get splitting out objects from non-Symbol.for symbols: there if you don't already have access to the thing, possibly transitively (via a cache or whatever), you cannot get it
00:24
<Bakkot>
but this is not true for Symbol.for symbols or for strings
00:24
<Bakkot>
those you can synthesize in a new realm without access to anything outside of the realm
00:25
<devsnek>
but the symbols in the agent cache aren't being forged, they're just normal symbols
00:25
<Bakkot>
I don't know what you mean by forged
00:25
<Bakkot>
the point of this conversation is to try to get at what you mean by forged
00:26
<devsnek>
a new value is created with the identity of some other value
00:26
<Bakkot>
I don't know what it means to be a "new value" but have the identity of another value
00:26
<Bakkot>
that seems like it is tautologically impossible
00:26
<devsnek>
like two strings both containing the same characters in the same order
00:27
<Bakkot>
how is that any more of a new value than a Symbol.for symbol is?
00:28
<devsnek>
because symbol.for doesn't always return a new symbol
00:28
<Bakkot>
neither does writing a string literal
00:28
<devsnek>
it definitely does
00:29
<Bakkot>
maybe in your implementation, not in mine
00:29
<Bakkot>
the difference is not observable to user code
00:29
<devsnek>
I'm not sure what optimization has to do with this
00:29
<Bakkot>
you're the one who brought it up?
00:30
<devsnek>
no I didn't
00:30
<Bakkot>
you said "symbol.for doesn't always return a new symbol". this is exactly as true as "writing a string literal doesn't always return a new string".
00:31
<devsnek>
no symbol.for is specified to not always return a new symbol
00:31
<Bakkot>
string literals are not specified to return new values either
00:31
<Bakkot>
the spec in fact speaks of "the" empty string
00:32
<devsnek>
I'm not sure what we're talking about anymore
00:32
<devsnek>
my point was being able to cache a type doesn't make it a forgeable type
00:33
<Bakkot>
I'm trying to understand what distinction you see between Symbol.for symbols and string literals, from the perspective of, only the former is "forgeable"
00:33
<devsnek>
symbol.for symbols are symbols
00:33
<devsnek>
we only have one kind of symbol in js
00:34
<Bakkot>
depending on what you mean by "kind", sure
00:34
<Bakkot>
but this does not help me understand what you mean by "forgeable"
00:35
<Bakkot>
all objects, and symbols not created by Symbol.for, have the property that code running in a fresh realm cannot get access to them. but this is not true of symbols created by Symbol.for, just as it is not true of string literals. so clearly this cannot be the definition of "forgeable".
00:35
<devsnek>
forgeable = you can create a value that has the identity of another value without having access to the original value
00:36
<Bakkot>
ok, so, in what way are Symbol.for symbols not forgeable?
00:36
<devsnek>
you have to look up the original value using Symbol.for
00:37
<devsnek>
you can't produce it out of thin air
00:37
<Bakkot>
Symbol.for is thin air
00:37
<Bakkot>
it exists in fresh realms; it does not need to be passed in
00:37
<devsnek>
that's what i meant above
00:37
<devsnek>
"I mean from some level of abstraction nothing is unforgeable because you can store it in something keyed by strings"
00:39
<Bakkot>
you can't store it in a way which will be available to code with which you share no communication channel
00:39
<Bakkot>
i.e. you have to actually pass the value, or a thing which has access to the value, to the new code
00:39
<Bakkot>
i.e. it can't make it itself
00:39
<Bakkot>
this is not true of Symbol.for symbols
00:39
<devsnek>
for mark's definition of communication channel sure
00:41
<Bakkot>
for any definition of communication channel
00:42
<devsnek>
sure
00:43
<devsnek>
i would just say the globals are passed to the realm and therefore the symbol is passed to the realm
00:47
<bradleymeck>
Bakkot: i think the crux of this is just that you cannot recreate the value with undeniable computation / primitive computation
00:49
<bradleymeck>
basically the idea is since you can censor `.for` using APIs but cannot censor things like 'it'+'erator'
07:02
<bendtherules>
Hi all!
07:02
<bendtherules>
I am having a little problem understanding why - AssignmentRestProperty doesn't allow Array or Object Literal inside it, but AssignmentRestElement allows them
07:02
<bendtherules>
So, I can write `[a, ...{0: b, length: c}] = [1,2,3,4,5]` but not `({a, ...{b}} = {a: 1, b: 2})`
07:02
<bendtherules>
What is the reason for allowing destructuring after ... in array destructuring, but not in object dest.?
07:04
<bendtherules>
This is the relevant spec link - https://tc39.es/ecma262/#sec-destructuring-assignment-static-semantics-early-errors
07:04
<ljharb>
bendtherules: the former is gathering the first item in `a` and the rest in an array, that you're destructuring
07:04
<ljharb>
bendtherules: i can see why you'd think the latter is allowed, but it seems nonsensical to me since you can just remove the `...{ }`
07:05
<bendtherules>
True, but then what is the rational behind allowing `[a, ...[b, c]] = []`?
07:06
<bendtherules>
Array literals seem to allow both obj. and array dest, after ...
07:06
<ljharb>
i'm not really sure
07:06
<ljharb>
but `...{b}` is 100% redundant for `b`
07:06
<ljharb>
further destructuring the rest array in an array destructuring isn't always 1:1
07:07
<bendtherules>
not 1:1 as in?
07:08
<bendtherules>
It will still take values out of the iterator in the same way, right?
07:08
<ljharb>
yeah, i suppose the nested array destructuring inside rest doesn't make much sense
07:09
<ljharb>
ie `[a, ...[b, ...c]] =` is the same as `[a, b, ...c]`
07:09
<bendtherules>
I can only think of one thing. correct me if i am wrong
07:09
<bendtherules>
the second one will still take out all values of all the iterator
07:09
<bendtherules>
*value out of the iterator
07:09
<ljharb>
so will the first one
07:10
<bendtherules>
i mean `[a, b]` vs `[a, ...[b]]`
07:10
<bendtherules>
Yes, in your example it will be the same thing
07:14
<bendtherules>
About `...{b}` being same as `b` - Is it exactly the same thing (if it was allowed)?
07:15
<bendtherules>
`...{b}` would still GET all the remaining enumerable properties, right?
07:15
<bendtherules>
Can that have a side effect?
07:18
<ljharb>
yes, i suppose that could
07:21
<bendtherules>
Was this willingly left out for some reason?
07:21
<bendtherules>
Looking through the early errors, i see that AssignmentRestProperty is restricted, but AssignmentRestElement is not
07:26
<bendtherules>
Also about the `[a, ...{length: b}]` case - what are the usecases?
07:27
<bendtherules>
Because the ... part is always a new array, it will have just numeric indexes and length property. What i can think of - get a random index value, or get length of remaining elements.
07:27
<ljharb>
i don't honestly know the history
07:27
<ljharb>
your thinking seems reasonable to me tho
07:28
<bendtherules>
got it. Last question - can i somehow track the discussions of this proposal (because it is already merged, i suppose)?
07:29
<ljharb>
destructuring was in ES2015, so it's long since shipped, and never went through the current proposal process.
07:30
<ljharb>
any discussions would be in the notes, not likely on github
07:34
<bendtherules>
👍 Makes sense. Thanks for the help @ljharb.
15:49
<Bakkot>
ljharb / bendtherules: object rest/spread was not in ES2015 and was a "modern" proposal
15:50
<Bakkot>
its repo is at https://github.com/tc39/proposal-object-rest-spread
16:15
<ljharb>
right sorry, object destructuring was but not rest, that was later
16:16
<Bakkot>
I actually recall talking about this specific question at the time but I can't find it in the notes
16:48
<bendtherules>
I just found this - https://github.com/tc39/notes/blob/015f9392787bd9cb86f172af3d55d0475e87db26/meetings/2017-05/may-23.md
16:49
<bendtherules>
Which seems like when rest in obj dest. was decided to be not allowed
16:49
<Bakkot>
aha, yes, that's the conversation I was thinking of
16:50
<bendtherules>
@Bakkot: do you remember if there was similar discussion within array dest.?
16:50
<Bakkot>
bendtherules: that's before my time, alas
16:50
<Bakkot>
array rest/spread was in ES2015, so it was discussed earlier
16:51
<bendtherules>
Ok, I'll try to search later
16:51
<Bakkot>
https://github.com/tc39/notes/blob/8e8bfcbddcb29c09a10b0845a55af2e0d31b6f49/meetings/2015-07/july-28.md#66-bindingrestelement-should-allow-a-bindingpattern-ala-assignmentrestelement
16:52
<bendtherules>
And @ljharb - seems like there is a diff between `{a, ...{b} } ` and the basic form - because it only takes from own props
17:24
<bendtherules>
@Bakkot: hmm, so binding was made similar to assignment in array rest case. Wondering if the assignment case was decided on purpose or discussed earlier.
17:37
<bendtherules>
Ok, so some more discussions are here - https://github.com/tc39/proposal-object-rest-spread/issues/43#issuecomment-307957597
17:39
<bendtherules>
In conclusion, it feels like there wasn't a strong case for obj destructuring within obj, but the array stuff was already there by that time. That wasn't removed as such.
18:33
<ljharb>
bendtherules: ah true