13:17
<dminor>
I have an appointment immediately before the meeting today, and Eemeli is out as well, so there'll be no Mozilla representative for the first half hour or so. From the agenda, I don't think there's anything that needs our feedback, but please ping me if something comes up.
14:47
<bakkot>
aww the decimal item got removed
14:47
<bakkot>
I would not have added my async iterators item if I'd thought it would be the only thing on the fourth day
14:47
<littledan>
the presenter is sick, unfortunately. I'm looking forward to it next meeting!
14:47
<bakkot>
I guess we have other stuff now though
14:47
<littledan>
also source maps overflow is today
14:48
<littledan>
if anyone has decimal feedback, it'd be good to take that asynchronously
14:57
<ryzokuken>
@room 3 mins to go!
14:58
<Rick Markins>
Morning conflict, be there after.
15:12
<Michael Ficarra>
.bufferAhead(Infinity) sounds like someone wanted .toArray()
15:15
<HE Shi-Jun>
aww the decimal item got removed
why removed?
15:15
<littledan>
because the presenter is sick today
15:15
<HE Shi-Jun>
the presenter is sick, unfortunately. I'm looking forward to it next meeting!
oh ...
15:16
<HE Shi-Jun>
if anyone has decimal feedback, it'd be good to take that asynchronously
The current plan is decimal128 or bigdecimal?
15:17
<Michael Ficarra>
HE Shi-Jun: we don't have that decided yet
15:17
<littledan>
The champion proposed decimal128, and using objects with methods rather than primitives with operator overloading
15:18
<littledan>
(last meeting)
15:18
<littledan>
but nothing is decided
15:18
<littledan>
this choice was based on feedback from implementers about R&T
15:18
<littledan>
it'd be great to hear feedback on these proposals between now and the next meeting
15:20
<HE Shi-Jun>
When we discussed it in wechat group, it seems people would prefer decimal128, with the assumption that it might have hardware support in the future. And if BigDecimal, some people might prefer Rational because it could cover more cases (at least theoretically? )
15:20
<littledan>
(I never understood why the conversation died down in the WeChat group I started for this outreach, and then there's this other group that I wasn't invited to...)
15:21
<littledan>
(when we make subgroups of TC39, the general principle is that they're open to anyone in the committee who wants to join them)
15:22
<HE Shi-Jun>
It's just my personal chat groups...
15:22
<littledan>
who is "we" then?
15:22
<littledan>
is it JSCIG or just your personal contacts?
15:23
<HE Shi-Jun>
Many chinese programmers , some are also in JSCIG group, but last JSCIG meeting we don't have enough time to cover decimal topic.
15:23
<Andreu Botella>
It seems like the transcriptionist is lagging far behind – and while the transcription seems accurate, it's far enough behind that it's very hard for me as a note-takers to keep track of what was said
15:24
<littledan>
yes I'm seeing that as well (I refreshed the notes a couple times to check if the error was on my side)
15:24
<littledan>
I wonder if it's that the presentation is too fast
15:29
<HE Shi-Jun>
(when we make subgroups of TC39, the general principle is that they're open to anyone in the committee who wants to join them)
JSCIG meetings are open to anyone (check github.com/JSCIG/es-discuss/issues for meeting schedule). The only problem might be, we use only chinese in the meeting :-)
15:29
<littledan>
heh, I definitely won't be able to participate in a meeting, but I can participate in a text chat
15:30
<littledan>
but if it's a personal group that's fine, I don't need to be involved.
15:32
<HE Shi-Jun>
littledan: I don't think there is any official TC39 wechat group... do we have such wechat group?
15:33
<littledan>
well, I formed one in 2019 but I wasn't really able to generate much conversation (and now WeChat won't really let me log in). You were in it.
15:34
<littledan>
maybe because I was writing in English? but I would've been fine if people chatted in Chinese there
15:35
<HE Shi-Jun>
Oh, I find it. It's not have messages from March 2020.
15:36
<littledan>
Never mind, this isn't so important; we can discuss it after plenary
15:37
<Michael Ficarra>
I think that's just the ordered semantics that Kevin is proposing?
15:37
<Michael Ficarra>
we don't need some extra method to have these semantics
15:40
<peetk>
did i miss how you opt in/out of concurrency overall? is there an options bag or something?
15:40
<Michael Ficarra>
littledan: in response to your topic, yes, this is all going to have to abandon the async generator mental model
15:40
<littledan>
littledan: in response to your topic, yes, this is all going to have to abandon the async generator mental model
I do not see this as a bad thing for iterator helpers
15:41
<Michael Ficarra>
littledan: me either
15:41
<Michael Ficarra>
peetk: you just pull more than you need, and bufferAhead is a helper to do that for you
15:48
<Justin Ridgewell>
Maybe I'm not thinking of a complex enough test case, but I think something like ints.map(subtractTwo).map(timesFour)
15:48
<Michael Ficarra>
bakkot: yes it can, let me explain
15:49
<Justin Ridgewell>
If the returned promises settle in any order, we can add cap and capOOO methods to fix the settlement order, and rearrange the resolutions
15:51
<Michael Ficarra>
the queue doesn't seem to be advancing properly for me
15:53
<Michael Ficarra>
refreshing fixed it 🤷‍♂️
15:55
<peetk>
so -- just to clarify -- bufferAhead is the way to opt into concurrency?
15:55
<Michael Ficarra>
a limited form, yes
15:56
<Michael Ficarra>
the out-of-order bit is what we're talking about to enable it completely unrestricted
15:57
<Michael Ficarra>
you can also just call next as much as you want for unlimited concurrency manually
15:57
<peetk>
right
15:57
<peetk>
ok thank you!
15:57
<Michael Ficarra>
no problem
15:59
<Michael Ficarra>
async iterators in particular really don't feel like they need to be sequential to me
16:00
<Michael Ficarra>
when people do async stuff, they know that the default state of things is out-of-order and that there needs to be explicit coordination to bring order back
16:00
<bakkot>
idk Promise.all() keeps order
16:00
<Justin Ridgewell>
I think it's a bit of a refactoring hazard if I have to change something to be async because I add a new call
16:00
<pipobscure>
@Michael That’s not really true though.
16:02
<Michael Ficarra>
yeah it's doing coordination, that's its job
16:03
<shu>
the "values being lost" thing is a core implication of anything concurrent or parallel i think, don't think there's another choice
16:06
<shu>
like, you try to improve throughput or whatever by doing a larger-than-necessary amount of work at a time, so if you want to impose some kind of serialization of results after the fact you'll have to discard stuff
16:08
<Michael Ficarra>
yeah but we have effects and exceptions and you can't just roll those back
16:11
<Justin Ridgewell>
Happy to join an async-iterator call
16:11
<Michael Ficarra>
same
16:12
<Willian Martins>
I’m willing to be part of the call as well.
16:13
<bakkot>
like, you try to improve throughput or whatever by doing a larger-than-necessary amount of work at a time, so if you want to impose some kind of serialization of results after the fact you'll have to discard stuff
only if you are going to stop consuming results conditionally - if you want to consume everything you don't have to lose anything, e.g. let results = Promise.allSettled(array.map(asyncMapper)) doesn't lose anything
16:14
<shu>
bakkot: yes, right, but i thought your point was that filter and reduce are fundamentally conditional consumption
16:15
<shu>
which i agree with, we shouldn't just do the embarrassingly parallel things
16:15
<bakkot>
iterator helpers are fundamentally conditional yeah
16:15
<bakkot>
but we could decide that this problem is bad enough that iterator helpers should not be the place for concurrency, and just make these work like generators
16:16
<bakkot>
and say you have to do something else for concurrency so that you don't lose values
16:16
<shu>
right, fair, and that's not my position
16:16
<bakkot>
not my preferred option but it is an option
16:16
<shu>
because i think losing-values is just a core part of the bargain for general concurrency
16:16
<ljharb>
(in an exception case)
16:30
<bakkot>

to elaborate on why filter is weird:

let's say you do

let it = [1, 2].toAsync().filter(pred);
it.next().then(console.log);
it.next().then(console.log);

and let's say your predicate returns true for the second call instantly, but takes a minute to finish for the first call.

if you are trying to preserve order at all, you can't resolve either promise until the first call settles, because if the first call settles with true then the first promise needs to get { done: false, value: 1 } and if it settles with false then the first promise needs to get { done: false, value: 2 }.

the only way to get things earlier than that is to give up on order entirely, so that in the case your predicate returns false for 1 then the first line prints { done: true } and the second prints { done: false, value: 2 }.

16:31
<shu>
yes, good example, the done-ness signal further reinforces my mental model of iterators being inherently ordered things
16:32
<HE Shi-Jun>
It seems done should be also a promise 😅
16:33
<Michael Ficarra>
shu: I still don't think so. It doesn't mean that any iterator derived from this one will be done. It's just used as a signal to the consumer to not pull anymore.
16:34
<shu>
that strikes me as not the prevalent intuition
16:35
<shu>
and will be confusing for the majority programmer if we adopted it
16:36
<bakkot>
RxJS can make observables from async iterators, and also is async iterable
16:36
<bakkot>
and has map etc helpers which are out of order
16:36
<bakkot>
I wonder how they handle this case
16:37
<shu>
anyway my understanding of async iterator helpers right now is to provide "data concurrent" algorithms on generic collections, via the iterator interface
16:37
<shu>
but in general, data parallel algorithms require chunking and need to know the collection size ahead of time to chunk
16:37
<bakkot>
I'm kind of inclined to say that if you want to give up on preserving order you should switch to a different thing which is not inherently ordered, i.e. observables
16:37
<Michael Ficarra>
I think having two sets of methods with an opt-in that moves you from in-order to out-of-order is a fair compromise here
16:37
<shu>
thus my suggestion for bufferAheadOOO(N) method to recover the collection size
16:38
<shu>
and lets you do full OOO concurrency
16:38
<Michael Ficarra>
yeah I think we're in agreement
16:38
<bakkot>
If we're going to have to sets of methods I would be inclined to just have differently-named methods on the same prototype
16:38
<Michael Ficarra>
now question: should the OoO prototype have a similar-named method that's a no-op?
16:39
<bakkot>
I don't know how the proposed bufferAheadOOO would work
16:39
<Michael Ficarra>
bakkot: no, switching is better, since you don't have to add OOO to 10 method calls in a chain, and you don't accidentally in-order after some OOO method
16:40
<Michael Ficarra>
bakkot: we should pair on a prototype impl to see if it would work
16:40
<bakkot>
yeah but if you're reading it you have to notice the call at the the start of the chain to see that this .filter is unlike other .filters
16:40
<bakkot>
and if it gets passed around first that might be lost entirely
16:40
<bakkot>
seems bad
16:40
<Michael Ficarra>
that's the case for all data structures?
16:41
<Michael Ficarra>
virtual dispatch baby
16:41
<bakkot>
"async iterator" and "async iterator but the methods are unordered" doesn't seem like really a different data structure
16:41
<bakkot>
hm. so. also, how do you consume one of these out-of-order things?
16:41
<bakkot>
like in my filter example
16:41
<bakkot>
what's the thing you actually do with it
16:41
<Michael Ficarra>
it's a different monad
16:41
<bakkot>
you can't for-await over it because for-await stops at the first done
16:42
<bakkot>
ditto forEach etc
16:42
<Rob Palmer>
Confidence in the ability to use the alternative license affects Ecma's ability to attract work and expand scope - even though we know informally it's highly likely to be approved. It's a matter for Ecma's organizational development. I guess this is best discussed in the GA or ExeCom since it's not a TC39-specific thing.
16:43
<bakkot>
any explanation which requires the use of the word "monad" is inherently not suitable for actual users
16:43
<Ashley Claymore>
and has map etc helpers which are obviously out of order
For rxjs flatMap is out of order, concatMap preserves order
16:44
<bakkot>
they renamed flatMap to mergeMap IIRC
16:44
<bakkot>
to make that clearer
16:44
<bakkot>
there is also switchMap
16:45
<Ashley Claymore>
Yeah which was flatMapLatest
16:45
<bakkot>
but yes there are several different notions of "out of order" for flatMap
16:47
<bakkot>
chairs: we need to revisit decorator metadata as well
16:48
<bakkot>
sorry I didn't notice it was not on the draft schedule
16:48
<bakkot>
should only take 5 minutes
16:48
<ljharb>
https://github.com/tc39/proposal-array-grouping/pull/47/files
16:48
<Michael Ficarra>
hold back done: true until all underlying iterator yields settle?
16:49
<Michael Ficarra>
again, we should try to actually implement this to tease out these details
16:52
<bakkot>
peetk: https://github.com/tc39/proposal-array-grouping/issues/51#issuecomment-1372786948
16:52
<bakkot>
(sorry if that's the wrong handle to ping)
16:52
<Michael Ficarra>
(he means contiguous)
16:58
<bakkot>
you can't hold back anything without giving up on out-of-order entirely
16:58
<bakkot>
well, maybe you can hold back done but not worry about exceptions?
16:58
<bakkot>
anyway yes we can pair on it
17:00
<bakkot>
wait the holding back doesn't fix anything in my example
17:00
<bakkot>
with filter
17:01
<bakkot>
giving up on order in that case means: that the first promise settles second, and it settles with { done: true }. that means for-await is never going to see the second promise at all.
17:01
<bakkot>
i.e. in my example it's already settling last, so there's nothing to hold back
17:03
<littledan>
Who was the first Stage 3 reviewer?
17:04
<littledan>
We had someone who MS will recruit from Safari, and someone else
17:05
<Michael Ficarra>
littledan: shu
17:05
<shu>
yes?
17:06
<shu>
oh
17:06
<shu>
yes, i'm the first reviewer
17:09
<bakkot>
Justin Ridgewell: you should open an issue on the repo just in case though
17:10
<Justin Ridgewell>
Will do
17:11
<Michael Ficarra>
I read your comment like 10 times and I still don't get the issue. Did you mistype something?
17:13
<shu>
a question for practitioners who want to use decorators natively in browsers: do you want metadata to ship at the same time as the rest of the decorators proposal?
17:14
<bakkot>
pzuraq: metadata is now stage 3
17:15
<shu>
maybe a different question: who wants to use decorators natively in browsers?
17:15
<HE Shi-Jun>
Does creating a new metadata object really cause perf issue?
17:16
<bakkot>
HE Shi-Jun: doing it on every single class when most of them won't have any decorators seems like it would be a pretty high cost, yeah?
17:16
<bakkot>
I don't think it would be an actual perf issue by itself, but it wouldn't be free, and the benefit doesn't seem worth it
17:16
<littledan>
Someone clicked past queue items; who expressed support?
17:16
<littledan>
I think Shu was expressing support?
17:16
<littledan>
or maybe this was the previous topic
17:16
<ryzokuken>
yeah
17:16
<ryzokuken>
it was for the last item
17:16
<littledan>
ah thanks
17:17
<ljharb>
a question for practitioners who want to use decorators natively in browsers: do you want metadata to ship at the same time as the rest of the decorators proposal?
in general, anything that minimizes the support matrix for any set of features is a nicety
17:17
<bakkot>
shu: : typescript can generate decorators with runttime type information and people write libraries which use that at runtime
17:17
<bakkot>
for some reason
17:17
<shu>
shu: : typescript can generate decorators with runttime type information and people write libraries which use that at runtime
not sure i follow
17:17
<bakkot>
oh
17:17
<bakkot>
sorry
17:17
<bakkot>
I did not read the question correctly
17:18
<bakkot>
ignore me
17:18
<shu>
ah
17:19
<Michael Ficarra>
I wish Natalie from Chrome security was still attending
17:20
<Justin Ridgewell>
https://github.com/tc39/proposal-decorator-metadata/issues/15
17:31
<littledan>
Great meeting everyone!
17:33
<bakkot>
let it = [1, 2].toAsync().ooo().filter(pred);
it.next().then(console.log);
it.next().then(console.log);

Suppose the first call to pred returns false, but takes longer than the second call, and the second call returns true. What behavior do you imagine for the two prints?

17:38
<Chris de Almeida>
https://github.com/tc39/Reflector/issues/450 looking for nominations for one or more individuals for TG3 Convenors/Chairs
19:07
<Michael Ficarra>
{ done: false, value: 2 } then { done: true, value: undefined }? I don't see what's challenging about this case