05:39
<bakkot>
given that both '\u{1F468}\u{1F3FE}' and '\u{1F468}\u{1F3FE}\u200D\u2695\uFE0F' are RGI_Emoji, does /\p{RGI_Emoji}.../u match '\u{1F468}\u{1F3FE}\u200D\u2695\uFE0F'?
15:16
<Rob Palmer>
Hey all, yesterday's plenary went faster than planned. As a result there is now 25min of spare time at the end of today's session. So HE Shi-Jun could choose to bring back Class brand checks, or we could just end the meeting early.
16:22
<shu>
as it is a PT-time meeting this time, either is fine with me
16:23
<shu>
you may get stronger opinions from EMEA or APAC folks
16:23
<shu>
3pm PT is like 7am or something China time? guess if folks are pulling all nighters for this...
17:31
<msaboff>
When I join the meeting, I'm in a room by myself. I have tried several times.
17:31
<TabAtkins>
If we have some leftover time I wouldn't mind giving a pattern-matching update; I can prepare quick slides with the latest form of the proposal. Happy to yield for anyone with more important needs tho.
17:32
<TabAtkins>
msaboff: There shouldn't be anyone in the room yet, the meeting doesn't start until the next hour.
17:35
<Rick Waldron>
Is it still appropriate practice to correct notes?
17:36
<Rick Waldron>
Nevermind, I see that it is.
17:44
<TabAtkins>
yup, please do so liberally
17:46
<msaboff>
msaboff: There shouldn't be anyone in the room yet, the meeting doesn't start until the next hour.
I figured there may have been people early. Guess not.
17:51
<nicolo-ribaudo>
msaboff I'm in now, if you want to see if it actually put you in a different room
17:59
<Rob Palmer>
we are starting the meeting in 1 minutes
17:59
<Rob Palmer>
11 attendees so far
18:03
<Rob Palmer>
31 attendees - we are starting with Record & Tuple
18:20
<Michael Ficarra>
maybe this invariant (and its importance to us) would be a good short topic for a TG3 meeting
18:24
<shu>
copying over what i said from TDZ: not a fan of membranes being design constraints for JS in perpetuity
18:25
<shu>
my recollection is most features contorted specifically to accommodate membranes have not been well received at large
18:25
<Michael Ficarra>
okay maybe it would be a long topic
18:25
<shu>
and i count Proxies under that umbrella
18:26
<jschoi>
The debate over this invariant will block how to work with mutable objects in records/tuples, but should it block records/tuples themselves?
18:26
<shu>
up to the champions to remove support for this use case
18:27
<shu>
if they want to not support mutable objects to start, then that seems to sidestep this issue?
18:29
<Robin Ricard>
to be clear this is not about mutability only but the ability to reference things mutable or not
18:29
<jschoi>
Yes, sorry, that’s what I mean.
18:29
<jschoi>
Is that needed for the minimal viable product of records/tuples? What’s the risk of punting?
18:29
<Robin Ricard>
main use cases for OPs are fn handlers and host objects I like to think
18:30
<Robin Ricard>
We've been told those use cases are very important and would virtually make this proposal uselss without a way to reference
18:31
<jschoi>
Records and tuples would still be useful for me, but I guess I’m used to working with immutable data all the time, heh.
18:32
<Robin Ricard>
(originally the proposal did not let you ref, because we kinda had that vision as well!)
18:32
<jschoi>
Things like Clojure tend to promote putting large globs of immutable data structures in single root references and isolating external mutability to separate structures. Although there are styles in which references are embedded within immutable structures, I’ve never had to do that.
18:33
<Robin Ricard>
to your point, we had clojure devs tell us they need to be able to reference because clojure can do it
18:34
<jschoi>
Heh, I wonder how often they really need to embed references (atoms, etc. in Clojure) deeply in immutable structures rather than at the top level.
18:36
<jschoi>
Anyways, having no external-object references yet would make this proposal useless to many people, but not all people (certainly not me). I wonder if this issue really should be considered a blocker for the MVP, given the controversy over fundamental cross-cutting invariants.
18:42
<yulia>
to be completely clear: the invariants we write down are subject to consensus of the committee
18:44
<shu>
i was going to object that usage of "invariant"
18:44
<ljharb>

when writing them down, we should definitely differentiate for each invariant which:

  • are true at the moment
  • were intentionally held vs accidentally held
  • has committee consensus to be held moving forward
18:44
<shu>
my contention is that it sounds like the "invariants" that some of these membrane libraries depend on are just "properties"
18:44
<shu>
yeah, what ljharb said
18:44
<ljharb>
we have many invariants that are true now, were accidentally held, and have no consensus to be held moving forward.
18:45
<bakkot>
tbf this is a property which mark has been carefully ensuring continues to hold
18:45
<ljharb>
it's important that we get explicit consensus, or note explicit lack of, for that third point for all the invariants we write down
18:45
<bakkot>
which is like being an invariant, kind of
18:45
<ljharb>
right - that makes it intentional, but doesn't necessarily have consensus
18:45
<shu>
bakkot: i think my disagreement is that the actual property is only in mark's head
18:45
<shu>
and how he has been ensuring it to hold is to give targeted pushback
18:45
<bakkot>
again tbf he has said he'd like to write it down
18:46
<shu>
so it has not been a part of the larger design lexicon except very vaguely, in terms of "is mark going to object"
18:46
<shu>
fair
18:46
<waldemar>
Did someone rearrange the queue?
18:46
<ljharb>
i think so; my topic is now a reply
18:46
<Rob Palmer>
Brian rearranged to group topics, waldemar
18:50
<shu>
ObjectPlaceholder is just not a good primitive
18:50
<yulia>
bterlson: my two topics are on this subject as well, should i wait or directly respond?
18:51
<shu>
the fact it ticks all the right boxes for a particular scenario is not convincing if i don't find the scenario convincing
18:52
<bakkot>
can we just make object(tuple) === tuple, then declare that the invariant is specifically in terms of "things for which object(x) !== x"?
18:52
<bakkot>
I guess I should ask mark that question
18:52
<ljharb>
Object(x) === x is already an invariant for any object, and it also must be false or any primitive
18:53
<bakkot>
right, so this amounts to a proposal that records/tuples be somewhere between objects and primitives, not either thing in particular
18:53
<shu>
cf waldemar's "there is a continuum between primitives and objects"
18:53
<bakkot>
which I trust we will get to someday
18:54
<bakkot>
at least I hope we do
18:54
<shu>
i think i agree
18:55
<ljharb>
i would object to any proposal that adds a third category to "objects, primitives" - nothing should be in between if avoidable. (obv i have to be flexible for R&T, since they always blur the lines somewhat)
18:55
<bakkot>
ok, then this amounts to a proposal that "it must be false for any primitive" stop being true for these primitives
18:55
<bakkot>
that is a property which current holds, not an invariant which is written in stone
18:56
<ljharb>
that would break far more code than any membrane breakage.
18:56
<bakkot>
would it though
18:56
<bakkot>
and what level of 'break' are we talking here
18:56
<ljharb>
i mean i can pull out my list of npm packages and download counts and audit it if you want, but i'm pretty confident
18:56
<bakkot>
a lot of code breaks when we add a new typeof value, in the sense of "no longer interoperates with new code"
18:56
<ljharb>
"what level" i can't really say without actually looking at the code, to be fair
18:56
<bakkot>
but that is fine
18:57
<bakkot>
don't use new code without updating
18:57
<shu>
we need clarity on evolution
18:57
<ljharb>
"don't use new code without updating" is just not practical. browsers update things all the time
18:57
<yulia>
i would really like to get to my comments, they were related to this topic but were not moved up. I would like a timebox extension
18:57
<bakkot>
browsers do not start injecting new javascript onto the page
18:57
<shu>
because it increasingly sounds like there are some folks who have interpreted "don't break the web" to not evolve the language?
18:57
<ljharb>
since basically nobody's code is entirely first party, there's never just one author involved
18:58
<ljharb>
which does mean that new app code will exist with old libraries often
18:58
<bakkot>
yeah, but that app has not already shipped
18:58
<bakkot>
so it isn't an existing thing we can break
18:58
<bakkot>
if the user tries to write the new feature, they'll discover it doesn't work with the old library
18:58
<bakkot>
and that's fine
18:58
<bakkot>
the existing page will work
18:58
<ljharb>
i see what you're saying and i completely agree there's many scenarios where the breakage isn't a problem. i think the object/primitive thing is not one of those scenarios.
18:59
<bakkot>
i am open to being convinced, but nothing said so far has convinced me
19:00
<shu>
things that have been said have convinced me less, if anyhing!
19:00
<ljharb>
bakkot: i'll check some libraries. so to be clear, you're suggesting that tuple be a primitive but Object(tuple) === tuple and the same for Record?
19:02
<waldemar>
Is the slide on the screen coming through jitsi as unreadable low-res for others as well?
19:02
<rickbutton>
yes low res
19:02
<ryzokuken>
yeah
19:02
<rickbutton>
the slides link is in the doc and schedule i believe
19:03
<waldemar>
I don't know what's special about this one, because in other presentations jitsi was showing full resolution
19:03
<ryzokuken>
I think it dropped the quality on Nicolo's side?
19:03
<ryzokuken>
maybe weak connection?
19:05
<yulia>
My feeling is that we should use symbols for the objectPlaceholder -- i don't see what objectplaceholder as a new primitive would do that we cannot do with symbol
19:06
<yulia>
I would also say that we can introduce a light syntax sugar on records to make the pattern easy for developers -- this is what i heard as the main objection to the weakmap solution
19:06
<waldemar>
I tend to agree with yulia here
19:07
<shu>
i think ObjectPlaceholders are needless complexity and might bite us later
19:07
<yulia>
for example x = #{... y: Symbol.tie("symName", objRef) }
19:07
<Justin Ridgewell>
Is the conclusion for R&T that no conclusion was made?
19:08
<yulia>
this also alleviates the issue of the memory leak, as we can specify Symbol.tie as we like
19:09
<yulia>
cc nicolo-ribaudo Robin Ricard ^
19:09
<rickbutton>
Symbol.tie would be interesting but hits the same realm/membrane invariant
19:09
<yulia>
it would respond the same way as the weakmap
19:09
<rickbutton>
but +1 on all of this, I can sign on to symbols in WM on the argument that it is much simpler
19:09
<yulia>
symbol.tie is just sugar for that pattern
19:10
<rickbutton>
well, where is the weakmap?
19:10
<ljharb>
bakkot: so here's an example, admittedly in the es5-shim for bind (first lib i checked), where new of a bound function would fail in the presence of a shimmed bind function and a bound constructor that returns an R/T: https://github.com/es-shims/es5-shim/blob/master/es5-shim.js#L254
19:15
<yulia>
rickbutton: this is something we decide -- i would say it is in the realm that creates it (if i understood the slides -- this is to be in line with the goals of the champions, apologies if i got it wrong)
19:16
<yulia>
obviously this needs to be fully fleshed out -- for example the retreival, but this is fundamentally sugar
19:16
<rickbutton>
no that makes sense, but my point is that it runs into the exact problem that some folks have with ObjectPlaceholders across realms, the symbol lookup on the other side of a realm needs to have that weakmap, so either it is shared across all realms or per-realm
19:16
<bakkot>
ljharb: right, so that library will not interoperate with new code written with this feature, but no existing pages will break
19:16
<bakkot>
seems fine
19:17
<rickbutton>
ultimately the problem is "who owns the weakmap", some don't want the realm itself to own a weakmap per realm
19:17
<yulia>
rickbutton: that can be addressed, but the requirements need to be clearer about what the SES group wants. this isn't something that R&T should be beholden to
19:17
<rickbutton>
rickbutton: that can be addressed, but the requirements need to be clearer about what the SES group wants. this isn't something that R&T should be beholden to
I certainly agree.
19:20
<ljharb>
bakkot: existing pages would break when they try to use the new types in that manner tho, which is not fine
19:20
<ljharb>
"don't break the web" doesn't just mean "don't break pages that are never touched"
19:20
<bakkot>
how is that not fine
19:21
<bakkot>
yes it does
19:21
<bakkot>
that's what that means
19:21
<bakkot>
"if your page currently works, it keeps working", not "if you start writing new code, it will keep working"
19:21
<bakkot>
we cannot make that promise
19:21
<shu>
+5
19:21
<ljharb>
i do see your argument and largely agree
19:21
<shu>
SML/NJ is there if you want an ossified language
19:21
<ljharb>
but i think that pre-existing invariants should not be casually broken
19:22
<ljharb>
and Object(x) === x meaning "is an object" is an ancient one that tons of code relies on
19:22
<ljharb>
especially since ES6, when everything using a list of typeof values for that concept switched to using Object(x) === x to avoid future additions breaking them like symbol did (and bigint)
19:23
<bakkot>
I'm not being casual about it
19:23
<bakkot>
I just think that tuples are genuinely something between primitives and objects
19:23
<bakkot>
and it's ok for them to behave like primitives in some ways and objects in others
19:24
<ljharb>
in a general sense i don't agree that that is ok
19:24
<bakkot>
well, they do: like objects, they contain other values; like primitives, they are forgeable
19:24
<ljharb>
i'm sure there's some specific ways that i'll agree it's fine, but in a general sense, objects need to behave like objects and primitives like primitives, and i don't want that line blurred
19:24
<ljharb>
forgeability isn't a primitive property; non-global symbols aren't.
19:25
<bakkot>
"like primitives they can't be used in a map", then
19:25
<bakkot>
or "like primitives they compare by value"
19:25
<bakkot>
or whatever
19:25
<ljharb>
weakmap, sure
19:25
<ljharb>
and how do i write my code to branch on whether it'll throw or not? by using Object(x) === x
19:25
<bakkot>
that won't work if we let you put symbols in weakmaps
19:26
<bakkot>
and that's fine
19:26
<jschoi>
well, they do: like objects, they contain other values; like primitives, they are forgeable
Insofar that strings can be considered to “contain” other strings, I don’t think that “containing” values is a unique feature of non-primitives.
19:26
<ljharb>
give me an actual "is an object" or "is a primitive" predicate, and time to migrate everything to use it, and i think there'll be a much stronger case to break those invariants
19:26
<bakkot>
jschoi I do not regard strings as containing other strings
19:26
<ljharb>
sure it'll work - it'll avoid the throwing. it just won't use the ideal path, and the symbol will go in the fallback Map
19:26
<jschoi>
jschoi I do not regard strings as containing other strings
I mean like my own mental model is that sometimes you can compose primitives into primitives.
19:26
<rickbutton>
fallback Map?
19:27
<ljharb>
rickbutton: in my code where i want to key on any value, and i use a weakmap for objects and a Map for everything else, so i can provide a maximally weak unified collection interface
19:27
<bakkot>
yoru code is now going down the wrong branch. just because it happens to still work doesn't mean Object(x) === x is actually the check you wanted.
19:27
<ljharb>
it's not wrong - my code still functions properly. it's just putting the symbol in a Map instead of a WeakMap
19:27
<ljharb>
and i agree, that in that case the Object comparison isn't the check i want - but that check doesn't exist yet
19:28
<bakkot>
let canBePlacedInWeakMap = x => object(x) === x is certainly wrong.
19:28
<ljharb>
when a semantic lacks a first-class predicate, code will and does abuse an existing property to provide that semantic.
19:28
<ljharb>
it's not wrong right now. it just may become wrong in the future.
19:28
<bakkot>
it will become wrong if we put symbols in weakmaps
19:28
<bakkot>
and that is ok
19:29
<ljharb>
whether it's OK or not depends heavily on the context that predicate is used in
19:29
<ljharb>
as a builtin predicate tho, then it would be updated in sync with the engine, and then it's always OK
19:30
<bakkot>
it's just unconditionally OK. there is no promise that old code continues to behave identically when provided with new values.
19:30
<ljharb>
it is a very broad spectrum
19:30
<rickbutton>
will your old code not do the exact same thing in this case? it will put the symbol into a map, the old behavior
19:30
<rickbutton>
i'm misunderstanding the actual problem here
19:31
<ljharb>
rickbutton: yes, this is a use case where it's fine, when i have the fallback map
19:31
<bakkot>
the question is whether it is acceptable for object(x) === x to hold for tuples
19:31
<ljharb>
i'm talking generally about that axiom being relied on in a myriad of ways
19:31
<bakkot>
I think it's fine
19:31
<bakkot>
jordan thinks otherwise
19:32
<rickbutton>
I have no opinion on this, I think
19:32
<rickbutton>
(the best opinion :) )
19:34
<shu>
wait, is the decorator presenter here?
19:34
<shu>
did i hear right that static field initializers aren't symmetric with instance field initializers?
19:35
<shu>
static field initializers have addInitializer but instance fields can only do replacement?
19:35
<shu>
(no opinion, just clarifying)
19:35
<ptomato>
pzuraq: I've been meaning to examine in more detail how the current version of the proposal interacts with how GNOME would like to use decorators. hence the question about static fields. if you plan to go to stage 3 soon I'll make sure I do that in January
19:35
<bterlson>
strong font game on this preso
19:36
<waldemar>
I see corruption on the top right of the slides. Anyone else?
19:36
<shu>
agree, game gotta respect game
19:36
<yulia>
best font since shu's presentations
19:36
<yulia>
waldemar: me too
19:39
<jschoi>
The slide corruption changed…
19:39
<Mathieu Hofman>
for example x = #{... y: Symbol.tie("symName", objRef) }
How would you retrieve objRef from y when consuming the record? If you have an equivalent Symbol.fromTie(y), then what you have is effectively ObjectPlaceholder. Or did I miss something ?
19:40
<yulia>
Mathieu Hofman: its kind of my point actually
19:41
<Michael Ficarra>
I look forward to never using Kahan's summation again
19:41
<jschoi>
I once read one of Kahan’s papers on why IEEE floats are designed the way they are. It was illuminating albeit confusing.
19:43
<Michael Ficarra>
jschoi: if you liked that, I highly recommend https://www.amazon.com/End-Error-Computing-Chapman-Computational/dp/1482239868
19:44
<jschoi>
What I remember from Kahan: We should have had many distinguishable NaN values. Heh.
19:44
<jschoi>
This book looks cool.
19:45
<shu>
many indistiguishable NaN values is responsible for your iphone's web engine being fast yo
19:45
<Michael Ficarra>
jschoi: there's some shorter papers that pretty much sum it up, with lots of great figures, if you want me to dig those links up for you
19:45
<TabAtkins>
Okay, a five minute slide deck for updating on Pattern Matching: https://docs.google.com/presentation/d/1D6rJzRRxf235sQH6JUXeKdJk5QLnYu66_gH5lpvcbwI/edit
19:45
<bakkot>
instead of the book, start with https://en.wikipedia.org/wiki/Unum_(number_format)
19:45
<jschoi>
many indistiguishable NaN values is responsible for your iphone's web engine being fast yo
I imagine Kahan shedding a tear at this. 🥲
19:46
<jschoi>
instead of the book, start with https://en.wikipedia.org/wiki/Unum_(number_format)
Oh, I heard about this too. I remember seeing a debate on YouTube between the creator of this and Kahan, in fact…
19:46
<Michael Ficarra>
nah, that wikipedia article isn't great
19:48
<ljharb>
i'm confused; is it harder to reason about code using BigInt than integer Numbers, due to the lack of finite precision?
19:49
<ljharb>
or wait, that's bit size, not decimal precision, so maybe that's an unrelated question
19:49
<shu>
well, yes, it is
19:49
<Michael Ficarra>
to be clear, I think there's probably too much buy-in to IEEE-754 to ever replace it with Unums, but I have been convinced they are better in every way, and it would have been a better alternative timeline if we had had them instead
19:49
<jschoi>
Imagine hardware accelerated unums.
19:50
<Michael Ficarra>
shu: yes I am completely lost whenever I don't run into overflow/underflow
19:50
<Michael Ficarra>
jschoi: people have done it! just not mass produced
19:51
<yulia>
Is anyone else having issues with matrix?
19:51
<shu>
i mean i think using numbers qua numbers is fairly rare in what i do?
19:51
<shu>
i'm tagging stuff, composing it with other stuff
19:51
<bakkot>
yulia: no. I suspect it's an issue with the federation with mozilla's homeserver?
19:51
<TabAtkins>
yeah precision blow-up from repeated mults is non-obvious if you're not paying attention.
19:53
<Michael Ficarra>
:-( sad to hear that bigints are mostly only used for crypto fraud
19:53
<bakkot>
unsurprised though
19:53
<jschoi>
I use BigInts in my work. 🥲 Though most recently it was with Node’s high-resolution performance API…
19:54
<bakkot>
but hey, the fact that bigints are mostly used for cryptominers does mean their usage probably went up 10x in the five days or so!
19:54
<TabAtkins>
i suspect it's just because they need 128bit ints?
19:55
<jschoi>
Probably. Either way, it needs to be beyond MAX_SAFE_INTEGER.
19:55
<ljharb>
imo the reason bigints suck to use is that they don't interoperate with numbers well, so libraries don't support both, and don't bother to switch wholesale
19:55
<ljharb>
my hope would be that Decimal would make a better decision there
19:55
<bakkot>
fwiw I would naively expect bigint usage to vastly exceed decimal usage
19:56
<bakkot>
it's true that lots of code needs to deal with money, but that doesn't mean it needs decimal
19:56
<bakkot>
code which needs decimal to deal with money is relatively obscure in my experience
19:57
<shu>
not if web3 takes off! /s
19:58
<rkirsling>
oof
19:58
<ljharb>
Justin Ridgewell: you need like 3-6 digits to handle all fiat currencies iirc, you need many more than that to handle crypto
19:58
<rickbutton>
gonna need infinite precision numbers to track how much money I lose from gambling on a sha of a png
19:58
<shu>
what if we simply lobbied central banks to _un_decimalize their financial system
19:58
<ljharb>
Twitter Ads used "microdollars" (1e-9) everywhere to avoid floating point issues in all global fiat currencies
19:58
<bakkot>
web3 money is specified in floats, not to worry
19:59
<shu>
lol
19:59
<yulia>
I do believe we are shitposting ?
19:59
<danielrosenwasser>
Bring web3 back to the gold standard!
19:59
<danielrosenwasser>
uh might be
19:59
<Michael Ficarra>
yeah this kinda devolved into #tdz
20:00
<bakkot>
whoops sorry
20:00
<Mathieu Hofman>
yulia: sorry I was catching up on all the earlier discussions. My point is that you have the same problems with Symbol.tie of a global implicit WeakMap and are still subject to primitives-dont-give-you-direct-access-to-objects assumptions by deployed code. From what I understand, the only difference you have with ObjectPlaceholder is a different typeof. Is there a concern with introducing a different typeof primitive? It feels weird to overload even more symbols.
20:00
<Michael Ficarra>
I do believe we are shitposting ?
btw that's the most Yulia way to moderate a channel
20:01
<yulia>
It’s true
20:05
<yulia>
Mathieu Hofman: im on my phone and can’t type fully. But: in terms of what was presented, the concept of objectplaceholder is not independently useful as a primitive. It is functionally a variable name with restrictions. This is nicely represented as a symbol in a weak map relation. We have the building blocks for that, we don’t need to invent a new primitive. It aligns with other independent use cases for symbols in a weak map. A new primitive should be something that justifies the implementation complexity of adding it.
20:12
<Mathieu Hofman>
I suppose I don't understand where the complexity is, as what I'm basically arguing for is explicitly identifying with a new typeof a primitive which can be used in WeakMap, and has the same properties of a direct mapping between an Object and values of this new primitive like Symbol.for has for a string/number.
20:13
<bakkot>
new primitives are a lot of complexity even for language users, much less engines
20:13
<Mathieu Hofman>
I believe that overloading Symbol further is a lot of complexity for user having to wonder which kind of symbol they're holding
20:14
<Mathieu Hofman>
is it a forgeable value, a unique value, a value representing some object?
20:14
<yulia>
I would say that the symbol is a normal symbol. The tie just puts it in a weak map
20:14
<yulia>
There is no overloading
20:15
<Mathieu Hofman>
But the intent of using that symbol is different
20:15
<yulia>
New primitives are a sizable implementation burden
20:16
<yulia>
Don’t think I agree about the intent
20:17
<rickbutton>
strings can be used as keys and as values, that intent is not expressed in a typeof
20:17
<rickbutton>
typeof seems a bit strong on only the "it expresses additional intent" argument
20:19
<sarahghp>
Thank you for shitposting. It makes me feel good. 😆
20:21
<Justin Ridgewell>
Re the earlier Promise.prototype.finally discussion, I mixed up .then and thenable access.
20:21
<Justin Ridgewell>
But the same power still holds
20:21
<Justin Ridgewell>
var iframe = document.createElement('iframe');
iframe.src = location.href;
document.body.appendChild(iframe)

var final = iframe.contentWindow.eval('(onThen, onCatch) => { window.data = {onThen, onCatch}; }')

var thenFinally, catchFinally;
Promise.prototype.finally.call({
  then(thenFinally_, catchFinally_) {
    thenFinally = thenFinally_;
    catchFinally = catchFinally_;
  }
}, final);

console.log('thenFinally', thenFinally.constructor === Function);
console.log('catchFinally', catchFinally.constructor === Function);

Promise.resolve({
  then: final
});
Promise.resolve().then(() => {
  console.log('onThen', iframe.contentWindow.data.onThen.constructor === Function);
  console.log('onCatch', iframe.contentWindow.data.onCatch.constructor === Function);
});
20:22
<Mathieu Hofman>

One thing I didn't get into is how having an explicit intent for an ObjectPlaceholder being an exit from the immutable structure is that it allows predicates that compare the immutable shape of a record/tuple oblivious of the exits, without running into the collision issues that strings have (and for which unique symbols were created in the first place):

const eventHandlerTag = Symbol('EventHandler');
const domElementTag = Symbol('Element');
const rec1 = #{type: eventHandlerTag, ref: ObjectPlaceholder(() => {})};
const rec2 = #{type: eventHandlerTag, ref: ObjectPlaceholder(() => {})};
const rec3 = #{type: domElementTag, ref: ObjectPlaceholder(document)};
assert(rec1 !== rec2);
assert(sameShape(rec1, rec2) === true);
assert(sameShape(rec1, rec3) === false);
20:22
<shu>
Mathieu Hofman: that is why the proposal is symbols, instead of strings
20:22
<rickbutton>
assuming that there was a predicate like Symbol.isTie you could do the same
20:23
<rickbutton>
or just try to unwrap every symbol
20:24
<Mathieu Hofman>
Unwrapping test wouldn't work in the no-unwrap-if-different realm case
20:24
<Mathieu Hofman>
which is still relevant for both approaches
20:25
<rickbutton>
well sure, but we are ignoring that because symbols in weakmaps doesn't have this problem, that problem would need to be solve if/when Symbol.tie was a thing, or a proposal attempted to add ObjectPlaceholder
20:26
<rickbutton>
(in this theoretical example of symbols as weakmap keys)
20:26
<yulia>
I would see this restriction as a benefit. In the absence of use cases that need this, weakmap symbols remove the objection on security grounds
20:27
<rickbutton>
and I think the general sense after the update is that the worse ergonomics of symbols in weakmaps > the general complexity of objectplaceholders, at least that was voiced by several people
20:27
<Mathieu Hofman>
I think we lost the fact that Symbol.tie was explicitely mentioned to help user-land solve the re-invent the wheel issue, and to improve debuggability.
20:27
<yulia>
And object placeholder is unnecessary to achieve the goals of records and Tupfes
20:27
<yulia>
No, we don’t need it for either case
20:27
<rickbutton>
I don't think Symbol.tie would be needed for debuggabilitry
20:28
<yulia>
It is a nice shorthand in the language but the same is achievable with a library
20:28
<Mathieu Hofman>
I would see this restriction as a benefit. In the absence of use cases that need this, weakmap symbols remove the objection on security grounds
I believe this would make the implementation of transparent membrane a lot more complicated
20:29
<yulia>
That is a concern for a membranes proposal
20:29
<rickbutton>
how so? symbols as weakmap keys are transparent to the membrane, if you need access to the weakmap on the other side, wrap it with the membranea
20:29
<rickbutton>
if anything, zero work needs to be done to fit symbols as weakmap keys into current membranes, it would just work
20:29
<Mathieu Hofman>
It is a nice shorthand in the language but the same is achievable with a library
A library that all users of records/tuples have to agree on using
20:30
<rickbutton>
the lack of a built-in coordination point is certainly a downside sure
20:30
<rickbutton>
but imo not fatal
20:31
<Mathieu Hofman>
If the weakmap holder is explicit, sure, if it's implicit and hidden within Symbol.tie then no
20:31
<yulia>
They don’t need to all agree on using it to be fair
20:31
<rickbutton>
If the weakmap holder is explicit, sure, if it's implicit and hidden within Symbol.tie then no
any restrictions around implicit maps would need to be handled in that proposal
20:31
<rickbutton>
we aren't suggesting implcit maps as a part of R&T, simply as a strawman for a possible followon proposal
20:32
<rickbutton>
%s/we/yulia/gc and feel free to correct me
20:32
<yulia>
Yep, you got it right
20:33
<yulia>
I would say there is much more motivation for a syntax sugar on symbols in weakmap than object placeholder. They are functionally the same. If you like we can even call it the same.
20:33
<Mathieu Hofman>
Again, I repeat my use case earlier, if you allow all unique symbols as weakmap keys, you can't build a generic predicate that test the shape of a record/tuple for mutable exits while still allowing other unique symbols as unique value, unless that predicate synchronizes with the weakmap
20:34
<rickbutton>
making that predicate sync with the weakmap in the case where the map is explicit seems perfect fine to me
20:34
<rickbutton>
WeakMap.prototype.has, in fact
20:34
<Mathieu Hofman>
you put the burden of synchronization for a generic concept (mutable data referenced by immutable structure) on the user land
20:35
<rickbutton>
you need the WeakMap to get the values in any case anyway, seems fine to also need the WeakMap to find out which ones are values
20:35
<yulia>
Can you show me a library on npm with a ton of downloads that does this?
20:35
<Mathieu Hofman>
I'm deriving this use case from questions that were asked on Discourse and github issues
20:36
<Mathieu Hofman>
One of them is https://es.discourse.group/t/tagged-records-and-variants/1058
20:36
<rickbutton>
something else important to note: symbols as weakmap keys does not preclude the future addition of ObjectPlaceholder in a future proposal that has all of these concerns ironed out
20:38
<yulia>
I don’t think this is a good example for objectplaceholder
20:38
<yulia>
It is making use of the ability to box objects for something else: brandchecking
20:39
<Mathieu Hofman>
There is some of these requests sprinkled around https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-947115796, mostly around the use case of vdom referencing user data
20:40
<rickbutton>
there is already an extremely well developed pattern for branding values, I use WeakMaps all the time for this
20:41
<yulia>
I am more and more convinced that expanding on symbols in weakmap is the way to go here
20:41
<rbuckton>
I am due to present after the break, but there is a significant amount of noise outside my house at the moment. While I'm not specifically asking to be rescheduled, I apologize in advance if the noise makes it difficult to hear. I have some background noise removal running for my microphone right now which I hope will help.
20:41
<yulia>
Like, even for the cases you are presenting now
20:41
<Mathieu Hofman>
The idea here is to have the unique brand information be part of the shape test of the record.
20:42
<Mathieu Hofman>
symbols are unique values that can participate in shape tests.
20:43
<shu>
as an aside v8 continues to have the opinion the vdom use case should not be overindexed on
20:43
<Mathieu Hofman>
if symbols are also unique values that can represent an exit, which should be ignored by the shape test, the shape test needs to be coupled to the weakmap that can differentiate the 2
20:43
<shu>
symbols in weakmaps are literally more expressive than ObjectPlaceholder
20:43
<yulia>
Which hasn’t yet been established as a need that should be integrated into engines as a primitive
20:43
<rbuckton>
Regarding debuggability and symbols as weakmap keys vs object placeholder: Some debuggers allow you to control watch window behavior to overcome this. Notably, VS Code has customDescriptionGenerator and customPropertiesGenerator configuration settings you can specify in launch.json that allows you to run custom code to generate your own descriptions and property expansion in watch/locals. Its a bit of extra work for the user, but it does allow you to work around the debug concerns.
20:44
<shu>
what is a "shape test" in that context?
20:45
<rickbutton>
"are these two records the same ignoring the object placholders"
20:45
<shu>
like what is the actual consequence, you have to type a bit more in some use cases?
20:45
<rickbutton>
is what i understand it as
20:46
<shu>
i mean, seems like a safe simplifying assumption to make that, if you use symbols, that symbols-as-object-placeholders are globally unique. if it ain't, and you have to couple it to a weakmap, that's a choice you can make as a framework too
20:46
<Mathieu Hofman>
I think it all boils down to whether the synchronization point is a user library that everyone agrees to use, or if the platform provides this synchronization point in some way
20:47
<shu>
that comes back to a point raised from the last meeting
20:47
<yulia>
Not everyone uses the same membrane implementation. This seems fine
20:47
<rickbutton>
well, it would be very simple for the platform to provide the coordination point, except that some don't want that coordination point to be cross realm
20:48
<bakkot>
easy to provide a per-realm coordination point if we want that
20:49
<rickbutton>
yes but others -dont- want that, therein lies the problem
20:49
<bakkot>
a per-realm WeakMap.sharedMap which is just a new WeakMap
20:49
<bakkot>
e.g.
20:50
<shu>
let me zoom out even more. like, what are you hoping to get out of immutable data structures? if it's mutable exit points, the main use case is templates. is it for easier reasoning of templates? if so, just do it in your framework, seems fine to me, not like you can compare templates across frameworks anyway. is it for faster performance of templates? we (V8) still don't think we can use R&T to make that use case fast anyway
20:51
<rbuckton>

We also could consider introducing something like a debugger.meta meta-property to facilitate debuggability, i.e.:

// assumes `debugger.meta` is ECMA262-defined, but a debugger can add their own methods to it

const placeholders = new WeakMap();
export function box(value) {
  const sym = Symbol();
  placeholders.set(sym, value);
  return sym;
}
debugger.meta?.addCustomDescriptionGenerator((value, describe) => {
  if (typeof value === "symbol" && placeholders) {
    return `Placeholder (${describe(placeholders.get(value))})`;
  }
});
20:52
<yulia>
There is a debugger working grou
20:52
<shu>
is a chair around to say what's up next after lunch? wondering if i have time to actually have lunch
20:52
<yulia>
As part of wasm but the goal was both wasm and js
20:53
<ljharb>
shu: looks like "regexp modifiers for stage 2"
20:54
<shu>
perfect. no offense meant to regexp abyss gazers, i've just chosen a different pit
20:56
<rickbutton>
we all need something to scare us to sleep at night
20:56
<rickbutton>
some chose regex, others ieee
20:57
<bakkot>
module loading... unicode...
20:57
<bakkot>
there are many options here
20:58
<ljharb>
prototype pollution, ohno.jpg
20:59
<yulia>
Module loading indeed…
21:00
<yulia>
Promises and proxies
21:00
<Rob Palmer>
We are starting the meeting!
21:06
<Michael Ficarra>
I appreciate that Ron has individually justified each modifier, and I am now convinced that each one in the proposal is useful
21:07
<bakkot>
ljharb: he is about to answer your question, but see also https://github.com/tc39/proposal-regexp-modifiers/issues/2
21:07
<ljharb>
i read that too and still wasn't sure i understood :-)
21:07
<bakkot>
the justification given is a.) he thinks it's simpler and b.) it's very widely precedented
21:08
<bakkot>
though I guess I should just wait for the next slide
21:11
<Michael Ficarra>
for regexp proposals, I do not respect precedent very much
21:11
<Michael Ficarra>
most regexp engines are an insane grab bag of any features someone thought to add
21:12
<bakkot>
in support of ^, I invite anyone to peruse https://github.com/kkos/oniguruma/blob/master/doc/RE
21:21
<bakkot>
oh backrefs are a good question
21:21
<bakkot>
I agree with rbuckton's intuition though, that it has to be an exact match
21:25
<bakkot>
re: yulia, ignorecase is definitely the one I expect to use, but given that we're doing that it seems worth adding the other reasonable ones as well
21:29
<TabAtkins>
Yeah backrefs are abso a match for the exact substring, you never reevaluate the pattern. /(...)\1/ doesn't match any random six character, only things like "foofoo"
21:31
<Justin Ridgewell>
/(...)\1/i.exec('abcABC') matches
21:31
<Justin Ridgewell>
It's not exact
21:33
<bakkot>
TIL
21:34
<TabAtkins>
oh huh, that's weird
21:34
<TabAtkins>
only allowing x in regex strings is a good idea
21:34
<Justin Ridgewell>
I would think /(...)(?i:\1)/.exec('abcABC') would also match
21:35
<Justin Ridgewell>
But /(?i:(...))\1/.exec('abcABC') wouldn't.
21:35
<TabAtkins>
given the above, i guess so sure
21:35
<Justin Ridgewell>
Eg, the backreference controls the case sensitivity, not the match
21:38
<ljharb>
just curious - has anyone actually explored what would happen to the web if we changed non-u-mode regexes so that invalid character escapes threw?
21:38
<Justin Ridgewell>
There are regex escapers which escape everything
21:38
<bakkot>
i have written code that would break
21:38
<ljharb>
ok
21:39
<ljharb>
there's been an autofixing eslint rule in most styleguides for many years that removes any invalid escapes' backslash, so i was wondering if there was any chance it'd be viable
21:39
<bakkot>
gotta remember runtime too, though
21:42
<ljharb>
true
21:45
<bakkot>
I wonder what fraction of shipped JS follows one of the top three styleguides
21:45
<bakkot>
10%, maybe?
21:45
<ljharb>
it's probably way lower than i assume, and way higher than anyone expects
21:45
<bakkot>
depends on how you count bundled dependencies, I assume
21:49
<sarahghp>
I wonder what fraction of shipped JS follows one of the top three styleguides
It would be interesting to see how it breaks down by project type. I assume "active corporate JS" is more like 99%.
21:49
<sarahghp>
Academic, 1%.
21:50
<sarahghp>
generative art NFTs ...
21:50
<sarahghp>
first three days of advent of code before quitting ...
21:50
<ljharb>
that last one, ouch, true TDZ material
21:53
<rbuckton>
"use regexp u" /s
21:54
<bakkot>
sarahghp: view-source on amazon.com sometime
21:55
<Michael Ficarra>
"currently-developed enterprise JS" which follows a style guide is definitely closer to 0% than to 99%
21:59
<sarahghp>
Hm maybe enterprise goes into the other side of the horseshoe. My previous milieux have all been very strict, but I guess that's mid-size.
21:59
<bakkot>
i think those teams which members of tc39 end up on are unusually likely to follow such practices
22:00
<bakkot>
as part of my actual job I spend a lot of time looking at websites shipped by businesses
22:00
<bakkot>
things are... not... good
22:00
<sarahghp>
maybe I'm just too optimstic
22:00
<sarahghp>
:D
22:26
<shu>
i missed the shape of Miles's concern, it's about houdini?
22:27
<jschoi>
i missed the shape of Miles's concern, it's about houdini?
Basically that people who care about line breaking usually care about text layout in general, which Houdini is already trying to solve.
22:27
<shu>
thank you
22:27
<jschoi>
I personally think that it is reasonable to put it in Intl, rather than Houdini, because plain-text line breaking in a plain-text grid, without other graphical text layout being involved, is a concern of many CLI apps.
22:40
<Michael Ficarra>
are those all jschoi proposals?
22:41
<jschoi>
are those all jschoi proposals?
Oof, yes, they are.
22:41
<Michael Ficarra>
nice
22:41
<jschoi>
See also https://github.com/tc39/incubator-agendas/issues/21
22:42
<shu>
i'm glad jschoi is taking advantage of the sanctioned time
22:43
<Michael Ficarra>
thank you, note-takers!