17:34
<shu>
isn't "barely used" an argument against the demand of decimals? i'm confused
17:35
<littledan>
the database driver needs to support decimals, but then not all clients use it
17:35
<ljharb>
tbf i think in that context it's that the one library barely uses them and has to bear the cost of an impl for everyone
17:36
<shu>
who is the one bearing the cost there? the package size?
17:36
<littledan>
there's package size, there's friction if you do use decimals and integrate with another library that happened to choose a different decimal type
17:38
<littledan>
there's a conservative way through, which is to make your own wrapper around strings that doesn't have any functionality and holds a decimal but makes it so that it doesn't randomly get cast to a number. That doesn't take much package size, but it's even more frustrating to use, and might not be so broadly adopted. We use this strategy in some parts of Bloomberg.
17:40
<kriskowal>
string is the best solution for interop today, for sure. and it could be worse: “decimables”.
17:41
<ljharb>
or all the decimal libraries could introduce a global symbol protocol to coordinate with.
17:41
<nicolo-ribaudo>
ljharb: I believe "qunatum" as a name is spec-internal and not exposed to JS devs
17:41
<snek>
will we allow decimables on Object.prototype
17:41
<ljharb>
ljharb: I believe "qunatum" as a name is spec-internal and not exposed to JS devs
that's good :-)
17:41
<nicolo-ribaudo>
The exposed name is "precision"
17:41
<littledan>
string is the best solution for interop today, for sure. and it could be worse: “decimables”.
the problem with string is all the places in the language where it "just works" as a Number. It's a dangerous choice, hence the annoying wrapper (if you can get people to use it)
17:49
<Ben>
I'll be stepping out in ~5 minutes, so we may need another person in on the notes
17:57
<Chris de Almeida>
https://github.com/MikeMcl/big.js/issues/45#issuecomment-104211175
17:58
<Ben>
I'll be stepping out in ~5 minutes, so we may need another person in on the notes
stepping out!
17:58
<Rezvan>
I can help with the notes
17:58
<ryzokuken>
I can help with the notes
Thanks a lot!
18:06
<Chris de Almeida>
there's a lack of decimal in many languages?
18:09
<snek>
i think the only ones that really lack it are ones where its possible to write high performance stand-ins
18:10
<Chris de Almeida>
e.g. c and rust, I presume
18:11
<ljharb>
php?
18:12
<Chris de Almeida>
php has bcmath
18:12
<Chris de Almeida>
similar to python where it's not technically built in, but has a standard lib
18:13
<littledan>
bcmath is compiled in all the time, right?
18:13
<shu>
there's a lack of decimal in many languages?
a primitive decimal, yes
18:13
<littledan>
I think of PHP and Python as languages with built-in decimal
18:13
<Chris de Almeida>
bcmath is compiled in all the time, right?
you have to enable the extension.. so.. maybe?
18:13
<shu>
standard libraries, less so, but JS doesn't have the same kind of stdlib culture that other languages do
18:14
<littledan>
standard libraries, less so, but JS doesn't have the same kind of stdlib culture that other languages do
it's true that we don't have built-in decimal. what does that say about what we should do?
18:14
<Chris de Almeida>
standard libraries, less so, but JS doesn't have the same kind of stdlib culture that other languages do
a common criticism, to be fair
18:15
<littledan>
yeah, we could take the decision as the committee to not try to build out a standard library, but I think it's quite a useful direction we've been going in, with things like Object.groupBy and Temporal
18:15
<shu>
that says to me that the collective demand of a built-in decimals is not high, given that an interchange format standard (IEEE) exists and libraries can all do that
18:16
<shu>
oh sorry i responded to the wrong thing
18:16
<shu>
the lack of a JS stdlib culture like other languages says to me that we are prioritizing stdlib things against core expressivity things, while they are different workstreams, but if i am forced to choose, i am just not going to prioritize stdlib things
18:18
<shu>
ljharb: your position IIRC was that this isn't worth it without syntax or primitives. you've been convinced since then?
18:19
<ljharb>
i have not, no
18:19
<shu>
ah
18:28
<littledan>
yes let's use the 15 minutes after lunch
18:29
<dminor>
Does this discussion need to happen in committee?
18:29
<dminor>
It sounds like it could happen offline, when more time is available.
18:29
<shu>
i often butt heads with jordan but i feel like i heard his reasons? you can disagree with the reasons but he stated them -- it's the same door closing one
18:30
<shu>
you have tried to counterargue the door closing concern by showing a technically way to thread the needle
18:30
<littledan>
We have tried to have this conversation over time. Sorry that I didn't reach out before this week, but I think Jesse did try to discuss this week with Jordan
18:30
<shu>
and while some of that concern is about technical decisions, what jordan said was the ecosystem / adoption patterns / "sucking the wind out of it" kind of thing
18:30
<Chris de Almeida>
I think Jordan was detailed last time -- I don't know what more you are looking for
18:31
<littledan>
There were a bunch of particular points that he made which have very general implications for TC39, and I would like to discuss them with the group. For example, Jordan said he'd like a universal numeric type which just works for everything. I think we have concrete reasons why this doesn't make sense and can never happen. Jordan also made a lot of statements about what does and doesn't make sense for our standard library. We should think about how this relates to our work in general.
18:32
<ljharb>
it's great to consider my, and anyone's general thoughts on the language, like we did with those "vision talks"
18:32
<littledan>
Overall, it seems like Jordan is doing this in a way of "negotiating" with browsers to get operator overloading eventually. If browsers are present, we could engage more directly with that, and characterize what could be possible in the future. We didn't hear from browsers about that.
18:32
<littledan>
I really think this discussion needs to happen at least partly in plenary, and I don't believe it makes sense for the committee to sign onto the limitations that this block implies
18:33
<Chris de Almeida>
I recall at least one browser rep saying that they could be convinced to add a new primitive, but that they were not convinced heretofore
18:33
<ljharb>
(i'm not trying to "negotiate" but) "operator overloading" to me is a term about userland objects; i want decimals as a new primitive (which has operator-specific behavior)
18:33
<littledan>
(i'm not trying to "negotiate" but) "operator overloading" to me is a term about userland objects; i want decimals as a new primitive (which has operator-specific behavior)
sure but this was also blocked
18:34
<ljharb>
so far that is true
18:34
<ljharb>
but if a block means we should permanently give up on a direction then a lot of proposals wouldn't exist or have existed
18:34
<dminor>
Our perspective is not "no new primitives" but that there is a very high bar for adding new primitives, and we are unconvinced that Decimal meets that bar.
18:35
<ljharb>
to restate, i think it's far more important for JS to avoid eternal mistakes than to make progress for progress' sake, and it is ok - if not extremely desirable - to have "nothing" rather than "the wrong thing"
18:35
<littledan>
but if a block means we should permanently give up on a direction then a lot of proposals wouldn't exist or have existed
yes but we really need to engage with this block in particular and its reasons to make progress. I think it is important for the plenary to analyze those reasons together.
18:36
<eemeli>

It would be nice if we could find a way to support something like

import Decimal from 'std:decimal/v1'

As in, a versioned standard library that doesn't necessarily communicate native implementation speeds to all users. With something like that, I at least would find it much easier to positively support e.g. Decimal.

18:36
<Andreu Botella>
I need to step away for a second, could someone help with the notes?
18:37
<ljharb>
the builtin modules proposal's years-long discussion imo covers why globals are a better approach than an arbitrary module specifier that Scripts can't access synchronously
18:37
<Chris de Almeida>
it seems like we are asking the same question of Jordan over again because we don't like the answer and are expecting a different answer if we ask enough times. if we can have a productive discussion and it must happen during plenary, then so be it, but it should not be interrogative
18:37
<ljharb>
either way my argument would be the same whether it's a global or not; it's about it being in 262 or not.
18:39
<shu>
Our perspective is not "no new primitives" but that there is a very high bar for adding new primitives, and we are unconvinced that Decimal meets that bar.
chrome's is similar. might be different in the line drawing exercise for the bar, etc
18:39
<dminor>
From my point of view, Jordan has expressed his reasons for blocking clearly, at the last plenary and again this time.
18:44
<littledan>
In the future, I want to discuss (1) what is the future of numerics [which is linked to operators] (2) what are our criteria for adding things to the standard library [independent of operators]. I'll discuss more with ljharb offline first, sorry. Both of those points were pretty core to the objection and I didn't get a chance to understand Jordan's intentions about how this reasoning applies generally.
18:55
<waldemar>
The slide show for the last agenda item of the day is inaccessible.
18:55
<waldemar>
I'd like to see it before the presentation.
18:57
<littledan>
huh? seems linked from the agenda https://onedrive.live.com/?authkey=%21ANzaoMgiLDZwOCw&id=5D3264BDC1CB4F5B%216170&cid=5D3264BDC1CB4F5B&parId=root&parQt=sharedby&o=OneUp
18:57
<ryzokuken>
waldemar retry a couple of times maybe
18:57
<Chris de Almeida>
yeah I can view it fine
18:57
<ryzokuken>
it took me a few times
18:57
<Chris de Almeida>
waldemar: can you double check?
18:58
<waldemar>
Now I can view it. Took a few tries.
18:58
<shu>
i don't know what the deal with my webex is
18:58
<shu>
the audio/video don't lag but the slides do
18:58
<littledan>
that says to me that the collective demand of a built-in decimals is not high, given that an interchange format standard (IEEE) exists and libraries can all do that
IEEE isn't a JS interchange format, in the sense that it's not a JS value that can be returned from an API
19:40
<nicolo-ribaudo>
ryzokuken / Chris de Almeida I don't see on the agenda on TCQ the second half for Chengzhong Wu's topic, since it was split in 15 minutes for presentation + 15 minutes for discussion to be re-scheduled after my topic. Is it intentional?
20:08
<ptomato>
ok, joining the notes now
20:23
<Michael Ficarra>
today's captioner is SO much better than day 1
20:24
<leobalter>

nicolo-ribaudo: I missed the timing for the TC39 meeting earlier today. I was looking at your indirect eval proposal and one thing that might be great is the parity with shadowRealms functionality on the import and evaluate methods. IIRC they follow their respective realm origin rather than the script where they are called. You can't really make the new instantiated realm aware of the incubating realm calling it. Your change makes import() a bit similar where it respects the origin.

For clarity, all I'm saying is a mean for feature parity, because you can't really use the indirect eval from another shadowrealm other than a wrapped function or evalute/import methods.

20:26
<leobalter>
FWIW, I need to remove myself from the shadowrealms proposal, I can't champion it anymore.
20:26
<ljharb>
shu: Error.isError is a slot check which is always cross-realm
20:26
<shu>
that's the mechanism of how it works
20:26
<ljharb>
"same realm" never comes up but i'm not sure why it did here and not everywhere else
20:26
<shu>
if mark cares about realm-ness for this, why not also for errors?
20:26
<ljharb>
ah k, good question i guess
20:27
<bakkot>
didn't he specifically address that yesterday? though I forget what he said
20:27
<snek>
aren't reflect methods supposed to mirror MOP ops
20:27
<bakkot>
or whichever day isError was
20:27
<shu>
did he? i also forget
20:27
<ljharb>
yesterday he talked about membranes which isn't necessarily cross-realm, but can be
20:28
<ljharb>
the context there was, having a method check slots on an argument means you can't make a fake error that the method will blindly report as an error
20:28
<shu>
oh the thing mark said yesterday was, for practical membrane implementations Errors are recreated across the membrane instead of wrapped
20:29
<shu>
but i don't think "objects that in practical membranes are copied" to be a design principle i can work with if that's what governs what needs per-realm or realm-ful brand checks
20:31
<hax (HE Shi-Jun)>
Why not Object.isTemplateObject ?
20:31
<snek>
same reason as Array i would guess
20:31
<bakkot>
do people actually go looking for stuff on the global? it's already got a bunch of random junk on it
20:31
<ljharb>
but moreso
20:32
<bakkot>
personalbar
20:32
<snek>
console.log(global) in a browser is not human readable
20:32
<snek>
barely readable in node
20:34
<bakkot>
is anyone aware of any use of trusted types outside of Google properties?
20:34
<bakkot>
a lot of CSP stuff is unusable if you are not Google
20:34
<bakkot>
like, because it's badly designed, not that it's actually not available
20:36
<leobalter>
plenty of usage at Salesforce before I left in February, I can't say about the status today.
20:36
<snek>
i have literally never seen any code use it
20:36
<snek>
i would imagine its usage is pretty much only in random proprietary stuff like the aforementioned
20:37
<bakkot>
I spend a decent amount of my time at my job looking at actual websites (retailers, banks, etc) and have never seen it
20:38
<leobalter>
I'd defer to a Salesforce rep to talk more about it, maybe Caridy?
20:38
<leobalter>
caridy: ^^
20:39
<mgaudet>
Dumb Q: isTemplateTag(eval("foo\bar-")) presumably returns true?
20:39
<mgaudet>
oof. matrix
20:40
<ljharb>
leobalter: fwiw we've previously agreed that Reflect is no longer restricted to proxy traps, in the getintrinsic discussions
20:43
<leobalter>
Thanks, this may be the precedent I was looking for.
20:45
<nicolo-ribaudo>
Dumb Q: isTemplateTag(eval("foo\bar-")) presumably returns true?
Yes, but the idea is that you use this to gate access to eval. If you already have access to eval, then you are already "compromised"
20:45
<ljharb>
leobalter: still ok to prefer the global ofc :-)
20:46
<leobalter>
my preference is over a pet peeve to keep Reflect and Proxies in sync
20:47
<ljharb>
that was indeed the constraint, prior, which is why Reflect.enumerate (sp?) was removed
20:47
<leobalter>
exactly
20:48
<leobalter>
I'd expect all Reflect functions to also have equivalents in Proxies.
20:49
<bakkot>
littledan: when you say "people" are doing this thing where they compile all the strings, who are you talking about?
20:49
<nicolo-ribaudo>
I'm logging off now -- I will still seem online because there is my PC on where I forgot to close the webex tab, but the monitor is not turning on for some reason so I cannot close it and I'm too tired to figure it out. If anybody can, please kick me out :)
21:02
<littledan>
littledan: when you say "people" are doing this thing where they compile all the strings, who are you talking about?
yeah I think I hallucinated this (maybe I'm an LLM!). Here's the thread where I proposed using templates for this, where Closure-level checks are explained https://github.com/w3c/trusted-types/issues/96 and here's a thread with a bunch of people attesting to its utility https://github.com/w3c/trusted-types/issues/398
21:05
<snek>
surprisingly i did not have that question
21:14
<bakkot>
littledan: thanks for the links. from what I can tell that thread is mostly just the one google person; it would be nice to hear about the need for this from other people.
21:15
<littledan>
https://github.com/w3c/trusted-types/issues/398#issuecomment-1910771081
21:15
<bakkot>
I guess edge is technically not google, yes
21:16
<bakkot>
also, do you happen to know offhand if some problem with using just making hashes work for eval and friends, instead of this?
21:16
<littledan>
I think Salesforce's case is different, with their membrane-based security model, testing for literalness might not be the thing
21:16
<littledan>
also, do you happen to know offhand if some problem with using just making hashes work for eval and friends, instead of this?
sorry what is the counterproposal?
21:17
<bakkot>
CSP allows you to allowlist scripts by a hash of their contents. this does not allow you to eval things by a hash of their contents. but it could! does that solve the problem this is setting out to solve? if not, in what way?
21:17
<bakkot>
hashes do require updating the CSP itself, which is certainly annoying; is that the concern?
21:18
<littledan>
well yeah that was the idea behind dynamic-strict right? also this is for stuff like HTML too.
21:19
<littledan>
but also there might be a lot of these, and you'd need a compile step to bring them all together into the header
21:20
<bakkot>
is that the only primary problem with the approach?
21:21
<littledan>
that it's probably too difficult to deploy? yes, that's what trusted types is getting at in general.
21:22
<bakkot>
ok, cool. from my experience working with integrating with CSPs at a few dozen customers, I think hashes would be substantially easier to deploy than TTs
21:23
<Michael Ficarra>
lmao this is nowhere near a minor editorial point
21:23
<bakkot>
TTs require updating each script, whereas with hashes you can leave the scripts alone and just add their necessary hashes to the CSP
21:25
<Michael Ficarra>
spirit and scope are stage 1
21:25
<danielrosenwasser>
I may have to leave strictly at 3
21:26
<Michael Ficarra>
apologies for opening this can of worms @danielrosenwasser
21:27
<Rob Palmer>
Unobservable worms
21:28
<Rob Palmer>
I'm really pleased that TS folk are discussing new TS syntax here in TC39 before landing it in the TS language. This helps keep JS and TS coordinated and aligned.
21:29
<Rob Palmer>
There's a lot of expertise here to be leveraged, as well as knowledge of potential future JS syntax growth paths. Obviously there is no procedural requirement for upcoming TS features to be discussed in TC39 first (or at all), so I hope the committee provides valuable/constructive feedback to make it a worthwhile activity to repeat in future.
21:44
<hax (HE Shi-Jun)>
I watched original issue in TS repo, happy to see the solution in the meeting.
21:47
<hax (HE Shi-Jun)>
Some language also have the modifier/annotation to denote how many times the function will be executed. Not sure TS need such much powerful information...
21:49
<snek>
full dependent types pls
21:50
<snek>
Luca Casonato: immediate is a property of the caller, not the callee, right?
21:51
<snek>
(wrt immediate () => void)
21:51
<Luca Casonato>
maybe - but i don't think that is necessarily important for most users. it would be a much simpler thing to adopt if we didn't have to add another ts only keyword
21:52
<Luca Casonato>
specifically it'd be a completely new type modifier position for closures - currently only constructors have this type keyword position
21:53
<hax (HE Shi-Jun)>
I think put keyword after colon is bad, it's not the type of the callback.
21:55
<ljharb>
i have a hard stop at the hour so hopefully we don't run late
21:55
<snek>
can you write type x = immediate () => void 😄
21:56
<hax (HE Shi-Jun)>
Consider parameter decorator @immediate, it even could wrap the function so if it's not called immediately, just throw.
22:03
<snek>
2/2 on unmuted deno delegates
22:03
<snek>
i'm hearing that we have an entire day to discuss tail calls
22:04
<ljharb>
or NaN canonicalization maybe
22:04
<shu>
that's not that contentious is it
22:04
<shu>
NaN may or may not be canonicalized, ez
22:05
<snek>
we designed a joke by committee?
22:06
<Justin Ridgewell>
@danielrosenwasser: Do both. If only one is chosen (eg, immediate), then I always have to wonder whether unmarked callbacks are really deferred or just haven't been marked as immediate yet.
22:08
<ljharb>
danielrosenwasser: mine was, 1) awesome, this solves a huge problem for me; 2) please ensure jsdoc support is first-class; 3) please only add new TS syntax inside existing syntax carveouts
22:09
<Rob Palmer>
ljharb: are the existing syntax carveouts well-defined?
22:10
<ljharb>
the : one is, lots of existing TS ones probably aren't, i just don't want to further poison the TC39 proposal syntax space
22:12
<Luca Casonato>

danielrosenwasser: I think it would be very useful if TS could enforce immediate callbacks are actually called immediately. It would make them even more useful. Specifically TS errors on the following cases:

  • User passes immediate function to a function as a parameter where that callback param is not marked as immediate:
function x(foo: immediate () => void) {
  y(foo); // error here, immediate function escapes from immediate body
}

function y(bar: () => void) {
  bar();
}
  • An immediate callback is captured by non immediate closure.
function x(foo: immediate () => void) {
  delay(100).then(() => foo()); // error because `immediate` callback is called from a `deferred` callback
}
  • An immediate callback is assigned to a variable outside the "immediate" body:
let cb: () => void;

function x(foo: immediate () => void) {
  cb = foo; // error because `immediate` callback is assigned to a variable outside of the immediate scope
}
22:15
<Luca Casonato>
I think if TypeScript were to do analysis like described above, it would make immediate more like a type modifier. And then placing it in type annotation space would maybe be less confusing. I very much agree with Jordan that it'd be great if TS could stick to the existing TS syntax space, rather than carving out new syntax space.
22:15
<hax (HE Shi-Jun)>
what about await/async?
22:17
<Rob Palmer>
My interpretation of Daniel's explanation of why deferred is not a "type" is that, from an implementer's perspective they are different things inside the checker. So I wonder if a user needs to care. Maybe it would be ok to put it on the right of the :. I don't have strong feelings.
22:19
<ljharb>
imo a "type" of X is any type-space information about X. in this case it's part of the type of the caller.
22:19
<snek>
what is type space information
22:20
<Justin Ridgewell>
I’m not sure they’re different from the user’s point of view.
22:30
<waldemar>

danielrosenwasser: I think it would be very useful if TS could enforce immediate callbacks are actually called immediately. It would make them even more useful. Specifically TS errors on the following cases:

  • User passes immediate function to a function as a parameter where that callback param is not marked as immediate:
function x(foo: immediate () => void) {
  y(foo); // error here, immediate function escapes from immediate body
}

function y(bar: () => void) {
  bar();
}
  • An immediate callback is captured by non immediate closure.
function x(foo: immediate () => void) {
  delay(100).then(() => foo()); // error because `immediate` callback is called from a `deferred` callback
}
  • An immediate callback is assigned to a variable outside the "immediate" body:
let cb: () => void;

function x(foo: immediate () => void) {
  cb = foo; // error because `immediate` callback is assigned to a variable outside of the immediate scope
}

We should come to an agreement of what "immediate" means. Consider the following cases of a function Foo that takes an immediate callback f:
A. Foo returns without doing anything.
B. Foo might call f immediately.
C. Foo always calls f immediately.
D. Foo might save f to be called later.
E. Foo might call f immediately and might save f to call later.
F. Foo always calls f immediately and might save f to call later.
G. Foo always saves f to call later.
H. Foo might call f immediately and always saves f to call later.
I. Foo always calls f immediately and always saves f to call later.

Which ones of these would be properly annotated with the "immediate" keyword?
Bonus question: What if Foo is an async function?

22:39
<Luca Casonato>
I think as follows: ABC are the only immediate ones, as f could escape in all other cases. If it’s async immediate means statically known to occur before the returned promise resolves (so roughly the same as for sync functions, await points do not affect this at all). Call sites would only do this immediate CFA if the returned promise is directly awaited (no Promise.all or assignment to a var first)
22:44
<snek>
does immediate imply a lack of deferred
22:44
<snek>
can you annotate it as immediate deferred