01:06
<nicolo-ribaudo>
Chairs, is the decorators update still happening? I believe that there is new information that would be great for the committee to hear, even if Jacob is not here
01:13
<Aki>
Reminder that if you presented, you need a summary of the presentation/conversation, and to record any conclusions that were reached. Here's some ongoing tracking https://kdrive.infomaniak.com/app/office/1777368/13
01:14
<waldemar>
What's the "Unable to load event that was replied to, it either does not exist or you do not have permission to view it." that this is replying to?
01:15
<bakkot>
https://matrixlogs.bakkot.com/TC39_Delegates/2025-11-19#L525
01:15
<bakkot>

<Justin Ridgewell> Does take() close immediately, or during the next .next() (that returns { done: true })

01:15
<Chris de Almeida>
hmmm.. with the continuations we have, the schedule is now full again. but we could do it if time allows
01:16
<nicolo-ribaudo>
Nevermind, I misunderstood and there is much less information at the moment that what I was thinking, sorry 😅
01:19
<Chengzhong Wu>
the afternoon second part schedule confuses me. there are two 20min continuations, but the schedule says it's full 1h40m? no, actually, it's only 40min this afternoon after break today. Today ends at 16:00 instead of 17:00
01:22
<Chengzhong Wu>
maybe the topic should be moved to the overflown section, instead of being "discussed" yesterday
01:30
<Rob Palmer>
For Decorators, is there anyone who would like to volunteer to lead the discussion in the likely case that Jacob cannot do it?
01:30
<nicolo-ribaudo>
I retracted my suggestion to do it anyway, in case you are asking because of my suggestion
01:30
<waldemar>
Measuring height of person: https://xkcd.com/3164/
01:58
<eemeli>
waldemar: Could you coment here on what you would've said with your "disagree" reply?
02:08
<mgaudet>
(I'm confused. Isn't Watt an SI unit for Power, and Joule for Energy?)
02:14
<Richard Gibson>
indeed: https://www.bipm.org/documents/20126/41483022/SI-Brochure-9-EN.pdf#page=23
02:14
<snek>
kwh is my favorite si unit
02:19
<waldemar>
The summary included an incorrect assertion that no one wanted an Amount that only does precision with no units. That's what I disagreed with.
02:20
<waldemar>
I had earlier stated in the conversation that I would support such a thing.
02:20
<eemeli>
Would you prefer an Amount that initially did not support unit conversion?
02:21
<Rob Palmer>
"Paving desire paths" - making existing usage easier and robust
02:21
<waldemar>
Precision of a decimal number and unit conversion are two very different things. There are plentiful use cases of one without the other.
02:23
<waldemar>
There exist use cases for both simultaneously, but that doesn't mean that all decimal number precision should be tied to unit conversions and vice versa.
02:23
<rkirsling>
https://www.w3.org/TR/html-design-principles/#pave-the-cowpaths
02:24
<Olivier Flückiger>
Relatedly, do we have some connection to stateofjs?
02:25
<eemeli>
I agree. Do I understand right that you would not be opposed to an initial Amount that also supported unit conversion, provided that we find agreement on the details thereof?
02:25
<ljharb>
i think the survey owner is in the general channel
02:27
<bakkot>
not afaik but the person usually solicitcs feedback in #tc39-general:matrix.org before launching
02:28
<keith_miller>
Olivier Flückiger: Does V8 cache the result of the internal equivalent to getNonIndexStringProperties?
02:29
<Olivier Flückiger>
Ok, just came to mind re. "surveys are hard". We noticed that in the "pick 3 items" sections the distribution follows almost exactly the order of questions asked.
02:29
<Olivier Flückiger>
No, we cache a list of enumerable properties in the order of enumeration.
02:30
<keith_miller>
I have some concerns that each of the new getXYZPropreties will be expected to be cached but that will induce memory overhead in all cases without non-trivial effort
02:31
<keith_miller>
Is that a concern that other engines share? It's not super strong opinion FWIW
02:32
<keith_miller>
I also don't necessarily mean the actual cached data itself I mean the pointer to the possibly cached data
02:32
<Olivier Flückiger>
Yeah, that is a good point. We would not plan to add a cache. I recently added a fast-path for getOwnPropertySymbols without a cache. That gave about 30% speedup, but same copmlexity class.
02:32
<Olivier Flückiger>
But I think anything else than enumeration would not be critical enough to warrant a cache
02:33
<nicolo-ribaudo>
If this is not cached and requires iterating through the properties, is it actually going to be meaningfully faster than iterating in JS?
02:34
<Olivier Flückiger>
Well, same as with counting keys, we would not create the keys array.
02:34
<Olivier Flückiger>
and also no regex, but an internal test.
02:35
<mgaudet>
I think it would be faster for us, because we can just walk a shape-lineage
02:35
<Christian Ulbrich>
In https://github.com/BridgeAR/array-get-non-index-string-properties I do not see any real use case. We are now talking about "errors", "logging", there is no mentioning of "logging" neither "errors" on the proposal so far.
02:35
<James M Snell>
Node.js' use of this doesn't require caching. I wouldn't expect that at all
02:36
<ljharb>
fwiw console.log is a universal use case for exactly "describing every kind of thing", and the committee spent a TON of effort in ES6 trying to make web behavior implementable in JS
02:37
<jkup>
I do think it's interesting hearing from Jordan/Mathieu/Ruben on use cases but the current examples on the proposal repo itself seem a bit contentious to me
02:39
<keith_miller>
Aren't they different big-O with the caching? I don't think one can say either way.
02:40
<keith_miller>
As in if you have 1M indexed properties and one named property, even with caching that's gonna be slower than this. But if you have 1 indexed property and 1M named properties the cached array is going to be faster in JS
02:41
<snek>
what if property descriptors had boolean getters telling you all the different categories and whether the property fit that category
02:43
<nicolo-ribaudo>
Also, does this actually requires a regexp when running in userland? Or can it do String(Number(d)) === d && d|0 === Number(d)?
02:43
<rbuckton>
Internal descriptors or JS materialized descriptors? materializing a JS descriptor for that case seems fairly expensive. Why not just a isIntegerIndexKey(text) that does the complex test against a key name?
02:43
<nicolo-ribaudo>
And could it use for-in to avoid allocating the keys array?
02:43
<snek>
materialized js descriptors. could also be %PropertyDescriptorPrototype% :>
02:44
<Christian Ulbrich>
Ruben: I think, would really help here, if there are actual use cases, either in some existing packages or at least in a way of some pseudo-code that would give me more perspective on, what you are trying to solve. For me this is a different language mechanisms like Object.entries for example. But feel free to ask me off plenary about that.
02:44
<snek>
the logging case needs property descriptors anyway so idk if the overhead would actually be that much in practice
02:45
<Olivier Flückiger>
Getting descriptors is not super fast. Pretty big allocation and unrelated information.
02:45
<nicolo-ribaudo>
I think this is about having a fast-path to not get descriptors when the TA is not weird
02:45
<Olivier Flückiger>
Since what you get as the descriptor datastructure is not what the engines will have internally.
02:46
<ljharb>
logging doesn't always need descriptors
02:46
<Olivier Flückiger>
However all of these discussions make me wonder if there would be an alternative proposal route that involves giving a more performance oriented api to descriptors.
02:46
<ljharb>
the existence of keys is typically the most valuable information, not a key's enumerability or configurability etc
02:47
<snek>
its just very likely in e.g. node's logger that a property descriptor will be materialized for any (non-exotic) properties
02:47
<waldemar>
That's correct. My worry is about the complexity and details of combining them, but if we can figure that out, that would be a fine outcome.
02:51
<rkirsling>
uhh wait
02:51
<rkirsling>
doesn't that mean it should be retroactively lowered to 2.7?
02:51
<rkirsling>
should I put that on queue
02:52
<nicolo-ribaudo>
I have replies if it gets on the queue
02:56
<Rob Palmer>
I agree with keeping Decorators at Stage 3 to reflect the main message that this proposal is in the implementation phase. TS shipped a while ago. We've done a few stage regressions for much more meaningful reasons.
02:56
<Justin Ridgewell>
Are any implementers actually excited for this feature?
02:56
<Justin Ridgewell>
Are any delegates?
02:57
<Mathieu Hofman>
I would love this feature
02:57
<Justin Ridgewell>
I’m certainly not…
02:57
<snek>
i'm excited for decorators on bare functions
02:57
<rkirsling>
this feature only scares me, if I'm honest
02:57
<Mathieu Hofman>
I definitely would like decorators on bare functions, possibly on bindings too
02:57
<rbuckton>
A fair amount of the developer community is.
02:57
<Mathieu Hofman>
more than classes TBH
02:57
<Chengzhong Wu>
would this be a kind of implementation feedback, which counts for stage 3 feedback?
02:57
<Chris de Almeida>
browser vendors be like
02:58
<Justin Ridgewell>
Yes. But I think we’re getting that feedback now.
02:59
<James M Snell>
Server runtime implementors be like...
02:59
<Justin Ridgewell>
I think Frameworks shipping this was a huge mistake, and that’s now influenced the users of those frameworks.
02:59
<Rob Palmer>
There is a bunch of folk in Node ecosystem waiting for decorators.
02:59
<Christian Ulbrich>
While of course decorators depend on your preference for meta-programming or not, those that do meta-programming are really yearning for this feature!
03:00
<Christian Ulbrich>
They are used in quite some big frameworks for that matter.
03:00
<Justin Ridgewell>
I particularlly hate Java annotations, and this is exactly the same meta programming that makes the codebase impossible to reason about.
03:00
<bakkot>
I do lots of meta programming and am the opposite of yearning for this feature
03:01
<Christian Ulbrich>
Justin Ridgewell: With great power comes, great responsibility, but I'd rather use power wisingly, than having no power at all.
03:01
<snek>
society if meme for if v8 had accepted the edge and deno plan to ship decorators
03:01
<Justin Ridgewell>
Great power hides the massive performance impact this’ll have on classes.
03:01
<Ashley Claymore>
I find the JS decorators proposal very different to Java annotations
03:02
<snek>
james is typing but he's not even at his computer, incredible
03:02
Chengzhong Wu
is typing
03:02
<Christian Ulbrich>
You can do so much more, than meta-programming with them! I for example use them as tagging decorators (basically Java's) annotation, i.e. those are decorators that have no function body, you can use them to get them easily in the AST.
03:03
<Ashley Claymore>
JS Decorators are functions that you can jump to like any function call and see what it does. Java Decorators were not like that at all
03:03
<Christian Ulbrich>
Justin Ridgewell: Proxies also have performance implications, yet teams decide to use them, for better maintainability / clearer architecture / etc.
03:04
<Chris de Almeida>
I was just complaining about this sort of Java 'magic' to Lea last night
03:04
<Christian Ulbrich>
Ashley Claymore: I know that Java annotations are laughable, but with JS decorators of course you can do the same thing.
03:04
<Ashley Claymore>
absolutely
03:05
<Ashley Claymore>
people can always do bad things
03:05
<rbuckton>
If you looked at Decorators as used in TypeScript/Babel as an experiment, they are a proven success in the ecosystem. They reduce boilerplate and open up numerous possibilities that often reduce the need for new syntax proposals
03:26
<Jake Archibald>
If anyone's interested, here's the bit of the observables design that I found particularly surprising https://github.com/WICG/observable/issues/216. Seems like I'm not the only one?
03:28
<Aki>
Reminder to add your summaries and conclusions to the notes. And links to proposals/PRs/slides if they're missing.
03:29
<jkup>
thank you for writing this up, I think this is extremely surprising too
03:57
<Chris de Almeida>
it puts the summary and conclusion in the doc or else it gets Aki's wrath again
04:09
<Aki>
Ecma language spotted!
04:11
<Jack Works>
hello spec writers I'm here to sell my ecmarkup language service extension, have a try! It provides code highlight, completion, go to definition, etc... https://marketplace.visualstudio.com/items?itemName=MagicWorks.ecmarkup
04:11
<Christian Ulbrich>
Without having looked at the Babel example, I bet it that a class is used as a namespace, this is a valid pattern and we will never get rid of it, by not enabling future class composition features.
04:12
<rbuckton>
"really big anything" is an antipattern, but at some point the rubber hits the road and you end up with big classes or big modules or big functions.
04:13
<ljharb>
nicolo-ribaudo: wouldn't "having a separate class for comparison stuff", for example, make it easier for users to find things too, as well as babel maintainers?
04:13
<bakkot>
classes as a bag of extension points often need to be large
04:13
<nicolo-ribaudo>
Well then you need to create that class. That class that was on screen is kind of like Node on the web, which has a bunch of utilities all for dealing with nodes
04:14
<bakkot>
like we have https://github.com/shapesecurity/shift-reducer-js/blob/es2019/gen/monoidal-reducer.js
04:14
<bakkot>
with, what, 99 method?
04:14
<nicolo-ribaudo>
The plugin author is handled one thing that contains all the utilities on its prototype
04:14
<bakkot>
but consumers just have like 4 or 5 https://github.com/shapesecurity/shift-reducer-js/blob/es2019/examples/contains-this.js
04:15
<rbuckton>
At one point I was considering proposing something like partial class to JS as a more standardized way of patching/augmenting existing classes w/o resorting to manual prototype patching.
04:15
<Justin Ridgewell>
If only we had pipeline and module-level functions…
04:16
<rbuckton>
In TS you could always reopen the static side of a class with namespace. Reopening the instance side of a class required an interface augmentation and prototype patching, unfortunately.
04:17
<rbuckton>
It's possible to emulate multiple inheritance in JS using Proxy but its very slow.
04:17
<Michael Ficarra>
Haskell type classes are just Rust traits but with a better type system (HKTs)
04:19
<Ashley Claymore>
Not saying I agree with everything, but I found this talk really interesting: https://youtu.be/Gz7Or9C0TpM
04:19
<Michael Ficarra>
I think Haskell also allows orphan instances but you shouldn't do that
04:19
<Ashley Claymore>
lots in relation to this
04:20
<Ashley Claymore>
the talk covers their current direction for handling ambiguity/clashes when extending a type
04:20
<Chris de Almeida>
this is awesome 👏👏👏
04:21
<ljharb>
+1, i use it
04:21
<rbuckton>
I wish I'd had more time to keep working on my ecmarkup extension :(
04:22
<ljharb>
fwiw i am strongly anti-interested in using web components as a design inspiration for anything
04:22
<nicolo-ribaudo>
This "custom form controls" example could be done with decorators too
04:22
<nicolo-ribaudo>
With a class decorator
04:23
<rbuckton>
I think that might have been the original idea. There was a lot of interest in decorators from the web components authors years ago. It informed some of the design of the proposal, including .addInitializer, IIRC
04:24
<snek>
you know traits.js is good because it has a download button
04:38
<danielrosenwasser>
I removed myself from the queue because I'm afraid we are running out of time
04:40
<nicolo-ribaudo>
We don't adopt it right?
04:40
<nicolo-ribaudo>
Some of us do
04:40
<nicolo-ribaudo>
But not as a committee
04:40
<danielrosenwasser>
(just clarifying that I'm not trying to abuse the queue to throw a point out)
04:40
<rkirsling>
oh man a third overload for PoC
04:43
<mgaudet>
I don't really understand the 'stateful sub-instance' phrase -- does anyone have a definition?
04:48
<mgaudet>
(There's so much confusion caused by talking about prototypical inheritance vs. C++ style/Java style inheritance)
04:48
<mgaudet>
(and class doesn't help alas)
04:48
<snek>
prototypial or prototypical 👀
04:49
<mgaudet>
erm.
04:49
<mgaudet>
yes
04:49
<ljharb>
prototypal?
04:49
<rbuckton>
prototypal
04:49
<rbuckton>
what ljharb said
04:49
<nicolo-ribaudo>
My proto-pal
04:49
<snek>
yeah typo'd that
04:49
<rkirsling>
prototypo
04:50
<rbuckton>
is prototypal/prototypial like aluminum/aluminium?
04:50
<Michael Ficarra>
👮 take it to TDZ!
04:55
<Michael Ficarra>
the tightly-coupled use cases are not all that motivated IMO, the whole value is in the loosely-coupled use cases
04:56
<Christian Ulbrich>
As I have said, if somebody is interested in composition of MixIns with CustomElements then give me a shoutout. Have a <make-blinking> structural mixin that you can compose with any CustomElement to make it blink. 😀
04:58
<bakkot>
sidebar: we need https://github.com/tc39/proposal-private-declarations
04:58
<bakkot>
this is the only syntax proposal I think we actually need in the language
04:58
<bakkot>
well, this and module declarations
04:58
<bakkot>
notably, neither of those are just sugar
05:00
<Chengzhong Wu>
isn't module declarations a sugar for multi-file modules?
05:01
<rbuckton>

Alternatively, Symbol.geti/Symbol.seti and WeakMap:

WeakMap.prototype[Symbol.geti] = function(key) { return this.get(key); };
WeakMap.prototype[Symbol.seti] = function(key, value) { this.set(key, value); };

const privateDecl = new WeakMap();
obj[privateDecl] = 1; // -> privateDecl[Symbol.seti](obj, 1);
obj[privateDecl]; // -> privateDecl[Symbol.geti](obj);
05:02
<ljharb>
oof, i wish that had been posted in tdz
05:02
<snek>
i can imagine implementations would love geti
05:02
<rbuckton>
plus Symbol.geti could work with Index and Range objects as first class ^1 and 0:1 for index-from-end and slice/splice syntax
05:03
<bakkot>
no, because multi-file modules have other observable effects (network access, e.g.), and you can't use them from a script such as an inline script
05:03
<ljharb>
you can do it with blob modules :-p
05:04
<snek>
mlobules
05:04
<rkirsling>
blobules
05:04
<bakkot>
nope, blob modules are still considered network access from the point of view of CSP
05:04
<ljharb>
oh weird
05:07
<bakkot>
they kind of have to be either network access or eval for CSP to work at all
05:07
<bakkot>
(possibly they should have been considered eval, but either way, same problem here)
05:07
<ljharb>
ah true, they're more like eval than network imo but either way
05:09
<rbuckton>

This is potentially an example of how a decorator could accomplish the same thing as new syntax:

@spreadClass(Foo)
class Bar { }

Not that I'm opposed to the syntax, per se, but decorators would allow for experimentation with this idea in userland before adoption as syntax.

05:09
<ljharb>
a useful read (or reread) for folks here might be https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
05:10
<Christian Ulbrich>
React is the site, that teaches you, that classes are hard to reason about, for machine and computers, so take that in consideration before reading that...
05:10
<jkup>
having flight.js flashbacks
05:11
<Satish>

How to specify Symbol.iterator methods in classes?

For example, like what we can do with array literals,

var obj = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
  }
};
var arr = [...obj];
arr.join(',')
05:11
<ljharb>
the same way (like, precisely the same syntax as concise object methods)
05:11
<Christian Ulbrich>
React is also the framework, that had stateless function components, before they changed them to functional components.
05:11
<ljharb>
(they're still stateless tho, useState isn't actually storing state on the component)
05:11
<snek>
according to a quick google search, react is also considered harmful
05:12
<ljharb>
note i suggested reading the article, not just the headline :-p
05:14
<Michael Ficarra>
just because something's possible doesn't mean it should be encouraged
05:15
<rbuckton>
I think I'd rather have something like class Foo extends Bar, Baz { } than class Foo extends Bar { ...Baz }
05:15
<ljharb>
not that i want either one of them, but i agree on the relative preference there
05:16
<Christian Ulbrich>
JS is multi-paradigm. It brings many tools to the table. Not all of them are equally "encouraged, everywhere, at once".
05:16
<Ashley Claymore>
some are less encouraged than others tho
05:17
<Christian Ulbrich>
Even without progressing the language any tiny bit further, you can build the very worst things, (wo)mankind can think of in terms of software design.
05:17
<rbuckton>
IMO, multi-argument extends would be sufficient for anything from multiple inheritance to mixins to protocols
05:18
<rbuckton>
Especially considering it's already somewhat feasible with a helper, e.g. class Foo extends f(Bar, Baz) {}
05:19
<snek>
what does f do there
05:19
<snek>
return a proxy?
05:19
<snek>
or do composition
05:19
<Christian Ulbrich>
Mixins are a reality.
05:19
<rbuckton>
I used f as a placeholder. It could be mixin(...) or something else, it doesn't matter.
05:19
<Michael Ficarra>
megamorphic functions will always be slow @ljharb, that's not gonna change
05:20
<ljharb>
so is eval. doesn't mean we should encourage it.
05:20
<rbuckton>
Some implementation of f could theoretically do any of those operations depending on the input it receives.
05:22
<Christian Ulbrich>
ljharb: eval() is a core feature of the language and it is - to me - something that every "interpreted" language has. It has the power to do everything, if you want to have a language, that disallows (i.e. "not encourage") things, go for a DSL that is non-turing-complete.
05:22
<ljharb>
sure, i'm not saying we shouldn't have it. i'm saying we shouldn't add affordances that encourages its increased use
05:23
<ljharb>
which is 1000% the case for mixins imo. it exists but it's bad and we shouldn't make it easier to do
05:23
<Christian Ulbrich>
Mixin or NotMixin is not a thing, a language, we as a multi-paradigm language should be encouraging / disencouraging.
05:24
<Michael Ficarra>
hard disagree @Christian Ulbrich
05:24
<ljharb>
that is entirely part of our job
05:24
<Christian Ulbrich>
Michael Ficarra: On what? Mixins specifically?
05:25
<Michael Ficarra>
all sorts of things are bad and we should be giving them better ways to do things to avoid doing the bad things
05:25
<ljharb>
people shouldn't omit semicolons either, and it's absolutely our place to tell them that. and the spec has a section on ASI hazards for that reason
05:25
<Christian Ulbrich>
Michael Ficarra: I agree. But I think, that there is no consensus on "mixins are bad", I am afraid.
05:25
<Michael Ficarra>
@Christian Ulbrich I don't need consensus
05:26
<ljharb>
we need consensus to advance. if mixins aren't considered bad by anyone then mixin features won't advance
05:26
<ljharb>
this was also made pretty clear i think in the plenary session that introduced the existing mixins proposal, back in 2019 or something
05:26
<Christian Ulbrich>
Of course it works both ways.
05:26
<Michael Ficarra>
hold up, I'm gonna pull out my slides that eviscerated the mixins proposal
05:27
<rbuckton>
mixins fill a gap in JS. I'm not personally opposed to mixins, but they do have a number of flaws. We can either address the flaws or find better way to fill the gap.
05:27
<rkirsling>
to be clear, this topic is just "freely talking about OOP" as opposed to proposing a specific direction, right
05:27
<ljharb>
the flaws are intrinsic, and i'm totally open to finding better solutions
05:27
<Jake Archibald>
For folks interested in changes to AbortController & AbortSignal, I've made a discussion-starter here https://github.com/whatwg/dom/pull/1425
05:27
<ljharb>
but i'm pretty sure the problem statement here isn't "let's talk about OOP"
05:27
<rbuckton>
This is now talking about a specific thing.
05:27
<Christian Ulbrich>
But still time changes. Mixin usage changes. Whether one has a preference for it or not, with for example - web components based on classes, mixins have become a very common pattern to apply common behavior between them.
05:28
<ljharb>
web component design is not something that we should be inspired by. that you have to use mixins with them is part of that
05:28
<rbuckton>
The "let's talk about OOP" was the previous item. both are in the same set of slides though.
05:28
<rkirsling>
oh what
05:28
<rkirsling>
I literally had no idea the topic changed
05:28
<rkirsling>
and wondered why it was already 2:30
05:29
<snek>
yeah it wasn't announced
05:29
<Christian Ulbrich>
Of course not. I gave it just as one example, of increased mixin usage. I am pretty certain - without having any data whatsoever - that mixin usage has increased since 2019 across the eco system.
05:29
<ljharb>
sure. but if you subtract any WC-related usage i do not think this is true
05:29
<Ashley Claymore>
it was but briefly
05:29
<Ashley Claymore>
same presenter and same slide deck made it very smooth
05:30
<Christian Ulbrich>
...and we can and should not ignore usage of patterns, idioms in the eco system. It certainly pushed us, to put things in the language. As Promise.withResolvers or Promise.try for that matter.
05:30
<rbuckton>
IMO, mixins and protocols both fill the same gap and neither are a perfect fit. Protocols feel like explicit interface implementations in C#. Mixins feel like implicit interface implementation in C#. C# warns you if you have a conflict and lets you pick and choose syntactically whether to use the implicit or explicit implementation.
05:31
<rkirsling>
same deck is fine but when I scrolled quickly through the deck there was no point at which it clearly indicated "and now here is a proposal"
05:31
<ljharb>
explicit > implicit
05:32
<Ashley Claymore>
the presented slides are different from the link
05:32
<Ashley Claymore>
localhost is being presented
05:33
<rbuckton>
explicit avoids conflicts but is unergonomic. implicit can have conflicts but is extremely ergonomic. I don't believe one is better than the other for every use case.
05:33
<nicolo-ribaudo>
The protocols proposal is also a solution to this stage 1 problem, right?
05:33
<ljharb>
that's ok, i do
05:33
<nicolo-ribaudo>
Which means we already decided that that's the rough solution to this problem
05:33
<nicolo-ribaudo>
As it's at stage 2
05:33
<rkirsling>
an abstract problem statement seems difficult here because it seems like spread is the proposal
05:33
<Steve Hicks>
I feel like there's something around the fact that it's currently impossible to put something in the body of a class to add a property whose value is not a fixed method body and have it end up on either the prototype or the constructor - only the instance (i.e. field = computeValue() but you can't for example wrap a method directly inline)
05:33
<snek>
i was curious about this as well
05:33
<rkirsling>
yeah
05:34
<Aki>
is there a replacement note-taker for jkup?
05:34
<rbuckton>
That is what decorators are for
05:34
<jkup>
I was going to say that as well but wasn't 100% sure
05:34
<rbuckton>
So its not impossible, its just waiting on implementation and test review
05:36
<Mathieu Hofman>
yeah I thought there was overlap with class protocols too
05:36
<Mathieu Hofman>
which means we already allowed multiple similar proposals
05:38
<hax (HE Shi-Jun)>
I think the motivation is clear. In ruby you can use include to compose somethings into a class easily, in mordern static languages, you have trait/protocol etc. In JS... you have nothing.
05:39
<rbuckton>
I do like protocols. I use a variant of them all over my @esfx/* packages. I think the ability to define default non-symbolic implementations is also important, however.
05:40
<ljharb>
i think that's a necessity yes
05:41
<bakkot>
no :(
05:41
<bakkot>
that's how you get shared global namespaces
05:41
<rbuckton>
IMO, if we could find a happy medium between mixins and protocols I think that would be the best solution.
05:41
<bakkot>
how are the words "shared global namespace" not sufficient in themselves to make you recoil from this concept
05:41
<snek>
implements EventTarget with strings
05:41
<ljharb>
methods can be strings, it already exists
05:41
<Chengzhong Wu>
IIUC, withdrawing proposals like mixin will also need to call for consensus
05:42
<ljharb>

one possibility that lightly encourages symbols but permits strings:

protocol X {
  x() { return 'symbol method'; }
  'x'() { return 'string method'; }
}
05:42
<Michael Ficarra>
I don't like it, but I think I've come around to being okay not nannying
05:42
<snek>
i'm actually feeling like this is probably the best approach
05:42
<snek>
modulo the precise syntax
05:42
<ljharb>
meaning the user, not the author, decides?
05:43
<snek>
the consumer decides how it augments their public interface yes
05:43
<snek>
i guess there are conflicting needs pulling in both directions here
05:44
<snek>
but i think the producer deciding is distinctly more class-inheritence like
05:44
<Justin Ridgewell>
That seems nice. Or if a conflict is found during mixing, throw an error
05:44
<snek>
deferring to something else vs saying you fulfill a certain contract
05:44
<Justin Ridgewell>
I’d prefer to use string names if possible, and use symbols when there’s a conflict
05:44
<Michael Ficarra>
definitely conflicts would need to be loud
05:44
<Justin Ridgewell>
Yes
05:46
<rbuckton>

In C#, an interface is by default implemented implicitly:

interface Stringable {
  string ToString();
}
class Foo : Stringable {
  string ToString() { ... }
}

But can be implemented explicitly:

class Foo : Stringable {
  string Stringable.ToString() { ... }
}

Whether something is implemented implicitly or explicitly is purely up to the consumer of the interface

05:47
<Justin Ridgewell>
^ Can we extend method names with . syntax to look up the lexical variable?
05:47
<rbuckton>
Wouldn't that just be []?
05:48
<Justin Ridgewell>
Without wrapping
05:49
<Mathieu Hofman>
can we advance the queue?
05:49
<rbuckton>
I'd rather just stick with []. without it you run into refactoring hazards
05:49
<Mathieu Hofman>
I'd like to reply
05:49
<Michael Ficarra>
it would've been great if all this excitement about protocols had been occurring on the issue tracker some time in the last 8 years
05:49
<Michael Ficarra>
better late than never, I guess
05:49
<hax (HE Shi-Jun)>
Extension proposal draft has syntax for that.
05:49
<snek>
i've always been excited about protocols
05:49
<Michael Ficarra>
not loudly enough!
05:50
<snek>
gus "snek" "protocols" caplan
05:50
<rbuckton>
I like protocols, though I'm not a fan of the post-hoc Proto.implement() approach.
05:51
<bakkot>
seems like this is an is/ought conflict
05:51
<rbuckton>
the upside of syntactic protocols is that there's the outside chance they can be statically optimized and you can have a self-contained class w/o depending on expression-level mutation
05:51
<bakkot>
ljharb is saying fields aren't the public shape
05:51
<Michael Ficarra>
protocols "gus" protocols "snek" protocols "caplan"
05:51
<bakkot>
lea is saying they should be
05:51
<Christian Ulbrich>
I find it a very special view on things, saying, that you could remove properties in a constructor, you could remove static fields too. Certainly in TypeScript nobody would expect this, because Classes or Interfaces are made up of public methods / fields.
05:52
<ljharb>
i'm 100% fine with a way to explicitly define the shape of an instance. but "the fields" are not the shape
05:52
<bakkot>
but like... why not
05:52
<bakkot>
it is true you can do dynamic stuff which makes the realized shape different from the list of fields
05:52
<ljharb>
because it's increasing the size of my API
05:52
<snek>
Michael Ficarra: do you see yourself having time to champion protocols these days? i may be down to co champion at least but i don't think i could individually spearhead it.
05:52
<bakkot>
ok, sure, that's a totally reasonable argument which is different from what was said just now, unless I missed it
05:53
<ljharb>
i did mention it briefly
05:53
<Michael Ficarra>
@rbuckton ^ there's declarative forms and dynamic/imperative forms for everything
05:53
<bakkot>
that is an "ought" argument rather than an "is" argument
05:53
<hax (HE Shi-Jun)>
I think it's actually already be public, for example d.ts must include that info.
05:53
<ljharb>
renaming a variable in my function shouldn't be a breaking change, nor should me moving between a public field and a constructor line
05:53
<bakkot>
in this context "public" means "to other code", not to build-time tooling
05:54
<ljharb>
right. through decorators is fine because that's something the class author has to explicitly opt in to
05:54
<bakkot>
again, totally reasonable position but I think lea has a fairly convincing case that (if we want this at all) making public fields part of the contract is the obvious way to do it
05:54
<ljharb>
and right now you can already make a class decorator that decorates your class with shape info if you like
05:55
<ljharb>
not implicitly imo. explicitly? maybe
05:55
<Mathieu Hofman>
I did not formulate my public field comment clearly apologies. I think I my next topic will clarify
05:55
<hax (HE Shi-Jun)>
To me (and many people) they are one thing, or at least should be consistent.
05:56
<bakkot>
how do you feel about the argument that moving something between the class prototype vs being added to each instance in the constructor should not be a breaking change? because that feels like exactly the same kind of thing, to me
05:56
<ljharb>
property placement is part of the API of an object
05:56
<ljharb>
the way the property got there is not
05:57
<bakkot>
why? I don't think users should think of property placement as being part of the API of objects, as a rule
05:57
<rbuckton>
IMO, public fields are part of the public API. IMO, doing this.x = in a constructor w/o some sort of public field declaration is bad practice
05:57
<bakkot>
if the documented way to use my objects is foo.bar(), it's on them if they were doing Foo.prototype.bar.call(foo) and that starts breaking
05:57
<Christian Ulbrich>
rbuckton: It certainly is in TypeScript. :)
05:58
<snek>
ron that opinion certainly applies to ts but has no observable (aside from override mistake) difference in js
05:59
<rkirsling>
yeah as somebody who's never used TS, that's a pretty foreign opinion to me 😅
05:59
<bakkot>
concretely: I don't think "is this property looked up on the instance vs the prototype" is any more obviously part of the API than "is this property declared in the class or dynamically added in the constructor"
05:59
<rbuckton>
Today engines have to manage shape transitions in a constructor/function when you do this.x = . A fair amount of the discussion around field decorators came from implementers who wanted classes to have a fixed shape.
05:59
<Christian Ulbrich>
What an API is made of, is described in its documentation. There is no direct relation between a public field and a public API, it could also be an implementation detail, but let's understand what we are talking about with public API - public API means, that it is "available".
05:59
<snek>
shape is not an observable property in js
06:00
<rbuckton>
Fixed shape also very strongly applies to structs. You won't be able to do this.x = in a struct w/o a field declaration.
06:00
<ljharb>
that's a fair stance to hold. but nobody documents public field usage on their class - at best they document the final shape (which might be the same) in a TS type
06:00
<ljharb>
that's not entirely true (although semver means that). it's also arguable that anything reachable/observable is the API.
06:00
<bakkot>
there is almost universal agreement that function.toString is not considered part of the public API. so "available" is certainly not what I mean by "public API"
06:01
<ljharb>
yeah [[SourceText]] is an exception, it doesn't count for anything
06:01
<rbuckton>
It is certainly observable when you hit a performance cliff due to IC cache misses
06:01
<rbuckton>
It's not directly observable in JS as a language, but it is a fact of life in most engines
06:02
<snek>
that has nothing to do with whether its a public api though
06:02
<snek>
you can make your class slow with internal code as well
06:02
<snek>
if our only working definition of public api is hyrum's law how are we supposed to ever model anything
06:03
<Ashley Claymore>
ES5 style constructors have decades of optimizations
06:03
<rbuckton>
Fixed shape is still an important performance characteristic, so much so that it's baked into the struct proposal
06:03
<Christian Ulbrich>

Maybe the discussion is a little bit too much into what is a "public API" and what not, the question is, whether the Introspection proposal has its usages or not. I think this is the question to answer:

"Is it worthwhile to let users introspect public fields" , regardless whether they are "public API" or not.

06:03
<ljharb>
and i would say no, not at all
06:03
<rbuckton>
Which are also often the cause of major performance issues.
06:04
<Christian Ulbrich>
Personally I do not find an answer to this question easy.
06:04
<ljharb>
it definitely might be worthwhile to have class authors explicitly document their instance shape tho
06:04
<rbuckton>
Arbitrary field ordering and partial field assignments are a whole class of performance issue.
06:05
<ljharb>
also, re the queue, to restate: function toString doesn't count for anything
06:05
<ljharb>
angular 1 learned that the hard way
06:05
<rbuckton>
constructor(x, y, z) {
  if (z) {
    this.x = x;
    this.y = y;
    this.z = z;
 } else {
    this.y = y;
    this.x = x;
 }
}

this is terrible for performance and happens everywhere

06:06
<Christian Ulbrich>
Yes, you can have toString() lie :).
06:06
<ljharb>
not Function.prototype.toString.call tho (unless you replace that method ofc)
06:06
<snek>
who is parsing function toString
06:06
<ljharb>
angular 1 did
06:06
<rbuckton>
The above produces a class that can have three completely different shapes at runtime, which causes a host of issues with inline caching
06:06
<ljharb>
nobody else tho, hopefully
06:07
<Christian Ulbrich>
@snek I have to for AOP with JavaScript :)
06:08
<snek>
what is AOP
06:08
<Christian Ulbrich>
snek: Aspect-oriented programming.
06:08
<ljharb>
i had to google it too
06:08
<bakkot>
... I kind of think we should a Class built-in, from which all class objects inherit (the classes themselves, not the instances)
06:08
<hax (HE Shi-Jun)>
Isn't that the signal that we miss the reflection ? I think public fields have the similar issue~
06:08
<rbuckton>
Kind of what decorators are for. And the Angular 1 toString debacle is why Angular 2 heavily relied on decorator syntax
06:08
<bakkot>
and then we could have Class.prototype.getFields or whatever
06:08
<Christian Ulbrich>
rbuckton: But not in functions.
06:09
<ljharb>
not yet at least
06:09
<rbuckton>
not yet, though I already have two stage 1 proposal for this (function decorators and parameter decorators)
06:09
<Christian Ulbrich>
real ™ AOP is also about preconditions etc. at runtime, what else? 😀
06:10
<Christian Ulbrich>
real real AOP also works on any kind of function anywhere in your source / function.
06:13
<Christian Ulbrich>
real real real AOP would create those dynamically. An AI could do that! Dynamic tracing of production code due to potentially identified threats without explicit instrumentation, why not? Of course the proper reaction would be, self-modifying code to alleviate problems!
06:17
<rbuckton>
👮
06:21
<rbuckton>

Do protocols support inheritance? like

protocol P1 { ... }
protocol P2 extends P1 { ... }
06:21
<ljharb>
i assume they'd support implements at least
06:22
<ljharb>
but yeah extends probably makes sense too, so you can still have required user fields
06:22
<bakkot>
yes https://github.com/tc39/proposal-first-class-protocols/blob/603c9ec53f134007d975654bbbec2a363aeae1e5/examples/monad-hierarchy.js#L11
06:22
<rbuckton>
If they do, then they may have the same problem as mixins due to the diamond dependency problem.
06:23
<bakkot>
... how so?
06:24
<rbuckton>
I may have misspoke? I need to consider it more.
06:29
<Michael Ficarra>
@rbuckton the example there is literally a diamond inheritance and it's not a problem for protocols because the names are always qualified by the protocol that defines them
06:30
<rbuckton>
Can you override a default method implementation from a protocol?
06:30
<rkirsling>
seems like it might be nice to temp check "who would block if it were / were not visible in the else"
06:30
<Michael Ficarra>
@rbuckton yes, and again, it's still qualified so still fine
06:31
<rbuckton>

And what happens if you do this:

protocol P1 {
  foo() { ... }
}
class C1 {
  implements P1;
  [P1.foo]() { ... }
}
class C2 extends C1 {
  implements P1;
}
06:31
<Michael Ficarra>
works
06:31
<rbuckton>
What does "works" mean? Which implementation is on C2?
06:31
<jkup>
snek: I guess it doesn't matter but I'm surprised by the var comment. I thought your issue was that if the check fails the binding shouldn't exist?
06:32
<snek>
yeah i just don't care what var does. no code i have touched in the last 10 years uses var.
06:32
<jkup>
ok thank you
06:32
<snek>
so i mentioned that since since i have a hard stance and it presents one (of many) paths to advancement
06:32
<Michael Ficarra>
let's take this to DMs
06:35
<ljharb>
Justin Ridgewell: my bad, you're right about eslint
06:35
<Christian Ulbrich>
bottom-left will not be picked up by a linter today. I'll bet a Sapporo on that. However, I think making a rule for that, should not be difficult.
06:35
<danielrosenwasser>

I actually don't know if it's that much of a pain?

if (let x = someResource; ...) {
  using _x = x; // ensure dispose
}
else {
  // ...
}
06:35
<rbuckton>
The ... leaves a gap between acquisition and registration
06:36
<ljharb>
let data = "outer";
if (true) {
  let data = 'if';
}

will definitely error on https://eslint.org/docs/latest/rules/no-shadow, which all the popular configs have enabled

06:36
<snek>
we gotta be making features that enforce correctness by default rather than saying the person writing the code has to enforce the correctness. there is a mountain of quantitative evidence that patterns like this cause bugs and security issues.
06:37
<Christian Ulbrich>
ljharb: Yes, but only because you re-declared it.
06:37
<ljharb>
the bottom left is redeclaring it
06:37
<ljharb>
there's two let data ='s
06:37
<Christian Ulbrich>
yes but in the condition. I doubt there will be support for that, already.
06:38
<ljharb>
oh. well sure, in that case every linter would syntax error on it
06:38
<rkirsling>
how you gonna negate a declaration
06:38
<ljharb>
so either way i'll take my beer later :-p
06:40
<Christian Ulbrich>
this is to be decided. I'd go for no syntax error and use an updated eslint rule :)
06:40
<danielrosenwasser>
I actually am okay with Stephen's solution here - restrict else when if (using )
06:40
<ljharb>
lol well yeah, obviously if the feature landed the rule would update to complain about the bottom left
06:40
<rkirsling>
excellent, Jake's question is exactly where we should focus
06:41
<Justin Ridgewell>
What was Jake’s question?
06:41
<rkirsling>
oh wait what
06:41
<rkirsling>
sadness
06:41
<bakkot>

ok so how am I supposed to write this in that case?

if (using resource = getResource(); resource.needsUpdate) {
  resource.update();
} else {
  await postMessage('no updates required');
}
06:41
<jkup>
did something get cleared?
06:41
<ljharb>
"is there still anyone who wants it visible in the else" was jake's question iirc
06:41
<rbuckton>
I'll be honest, I really disliked declarations in conditionals in Go, but I'll admit a lot of that ire comes from the lack of ternaries in Go.
06:42
<Devin Rousso>
maybe i shouldve done a temperature check lol
06:42
<Devin Rousso>
cause yeah getting an idea of how many are on each "side" would be great
06:42
<keith_miller>
Is the else problem also going to be essentially a blocker for pattern matching?
06:42
<Devin Rousso>
i do think the idea of disallowing else is really clever!
06:43
<keith_miller>
It seems like if we can't solve it here are we going to be able to solve it later?
06:43
<ljharb>
i don't think so
06:43
<Michael Ficarra>
how could you not know how many people are on each side at this point?
06:43
<rbuckton>
There's a bit of a difference though. Pattern matching doesn't currently treat if specially. It declares the bindings in the containing scope.
06:44
<bakkot>
you can't use pattern matching with using so my opinions are less strong
06:44
<rkirsling>
I thought temp check was super important there; I would be willing to let the meeting go an extra 2 minutes to get one in
06:44
<Devin Rousso>
i have a rough idea of who's who, but it would be nice to have confirmation
06:44
<Devin Rousso>
and frankly it was quite rapid at a few points
06:44
<ljharb>
we could make that usable but obv we'd have to make the usage of it work as you expect
06:45
<rbuckton>

Example of else visibility in C#:

int[] ar = [1, 2];

if (ar is [var x, var y]) {
  Console.WriteLine(x); // ok
} else {
  Console.WriteLine(x); // static error
}

// vs


if (ar is not [var x, var y]) {
  Console.WriteLine(x); // static error
} else {
  Console.WriteLine(x); // ok
}
06:47
<Michael Ficarra>
it's overwhelmingly disallow in the else because, well, duh
06:47
<Justin Ridgewell>
I have no idea what that program means
06:47
<Steve Hicks>
But that's really a pattern matching thing.
06:47
<Devin Rousso>
yeah that's what i feel as well, but it also seems like there are a few who very strongly want it in the else
06:47
<rkirsling>
yes but data is better than vibes
06:47
<Michael Ficarra>
then do the temp check to confirm
06:48
<rbuckton>
I still maintain that, aside from using, decls in conditionals is otherwise fully covered by pattern matching.
06:49
<mgaudet>
(Side note: I didn't get temp-checked despite having TCQ open.... Despite my implementation concerns, I was leaning towards interning)
06:50
<ljharb>
it's perfectly fine to have two ways to do a thing tho. using pattern matching to get decls in conditionals is gross, and it'd be better to also have proper decls
06:51
<rbuckton>
To be clear, decls in conditionals in a language like Rust is pattern matching.
06:51
<ljharb>
it wouldn't be here because of the condition part
06:51
<snek>
i think we should have pattern matching in if statement heads
06:52
<rbuckton>

IMO, these are certainly not gross:

if (opt is Option.Some(let x)) {
  ...
}

while (iter.next() is { let value, done: false }) {
  ...
}
06:52
<Steve Hicks>
I'd love to see pattern matching land - is there a reasonable path forward for it?
06:52
<snek>
its also an even better argument for else not binding, because there is no possible value to bind the variable to in the failure case
06:52
<ljharb>
i agree! but neither of those is just a declaration
06:53
<rbuckton>
I believe so, we just haven't had the opportunity to work on the proposal in a while.
06:53
<Michael Ficarra>
can you get on the queue? sometimes if you haven't interacted in a long time, you have to re-auth for things to start working again
06:53
<rbuckton>
Neither is if (let x = ...; ...) {}
06:53
<mgaudet>
Seems to be working.
06:54
<ljharb>
true. but that one isn't pattern matching :-)
06:55
<nicolo-ribaudo>
I guess strings are technically garbage collectable
06:55
<snek>
if (let truthy(x) = ...) {}
06:55
<rbuckton>
Consider the extractor case. if (opt is Option.some(let x)) actually checks the extractor matches, but what would if (let Option.some(x) = opt) { ... } do?
06:56
<Rob Palmer>
^^ vote 1
06:56
<snek>
i mean i would've expected the syntax to be if (let Option.some(x) = opt)
06:56
<snek>
but in all 3 of these its just syntactic choices
06:56
<bakkot>
if (opt is Option.Some(let x)) {
  ...
}

if we're going to let you write

let Some(x) = opt

then I want to write the above as

if (let Some(x) = opt) {
  // ...
}

not your pattern matching thing

06:57
<waldemar>
The temp checks were useful
06:57
<rbuckton>
The first is pattern matching, which follows left to right evaluation. The second is assignment, which follows right to left evaluation.
06:57
<Aki>
Don't forget to write your summaries and conclusions!!!
06:57
<rkirsling>
this would be a useful three minutes for a temp check 😭
06:58
<rbuckton>
Ah, extra let in the second example, fixed.
06:58
<snek>
my point was that i don't intuit any behavioral difference between these
06:58
<snek>
to me they are 3 ways to write the same thing
06:58
<bakkot>
rust literally has exactly this
06:59
<bakkot>
the if (let Some(x) = opt) { syntax
06:59
<danielrosenwasser>
I have a thought, but I think you will hate it.
06:59
<bakkot>
this committee is an exercise in hearing hateful things; hit me
07:00
<rbuckton>
let Some(x) = opt is exhaustive. If it doesn't match its an error. Just as let [x] = opt throws if opt isn't iterable.
07:00
<bakkot>
my point is that if you put it in an if then you would get the else, not an error
07:00
<bakkot>
this is very obviously how it should work, and is how it works in other languages with analogous features
07:00
<rbuckton>
There are a lot of issues with trying to extend destructuring syntax to pattern matching.
07:01
<snek>
i think we are conflating two different things here
07:01
<rbuckton>
Those languages can use pattern matching in declarations. JS can't because of decisions we made for how assignment and binding patterns work that preclude other pattern matching uses.
07:02
<bakkot>
but we can make extractors work like this
07:02
<bakkot>
can, and should
07:02
<bakkot>
I don't want extractors if we don't have this
07:02
<danielrosenwasser>
Basically a restriction where you can always write an else, but it's a ReferenceError to refer to a if (using) variable in an else block
07:02
<rbuckton>
I'm actually trying to very clearly delineate the two. Declarations can't be actual pattern matching.
07:02
<Steve Hicks>
Agreed. Is it the case that different options make sense depending on if your if is doing pattern matching? I.e. Rust is pattern matching and doesn't expose the binding in the else, Golang does not pattern match and does.
07:02
<bakkot>
seems fine as long as it's also a ReferenceError for the other kinds of declarations!
07:03
<rbuckton>
I investigated this several years ago: https://gist.github.com/rbuckton/df6ade207eecad4fc94cedc3aae79ceb
07:03
<danielrosenwasser>
I mean I'm fine with that too, it at least tells people "this can't be expressed this way, or you're probably making a mistake"
07:04
<rbuckton>
Specifically: https://gist.github.com/rbuckton/df6ade207eecad4fc94cedc3aae79ceb#extending-if
07:04
<rbuckton>
The pattern matching champions group were overwhelmingly opposed to extending existing syntax
07:08
<bakkot>

but seriously I would at least prefer that to the state where you can't write else at all.

I do think it would be a very strange inconsistency, though, and would much prefer it to be an error for the other kinds of declaration as well.

07:08
<rbuckton>
IMO, if if (let Option.some(x) = opt) actually checks the extractor matches, then if (let [x, y] = z) also need to check and not throw, and that means to any level of depth within the binding pattern.
07:08
<bakkot>
I don't see much reason to want any declarations to be visible in the else when you can so easily just move them up a line. using is the only reason you need to be extremely careful with when bindings are and are not in scope.
07:09
<rbuckton>
move them up a line and surround the whole statement in {}
07:09
<bakkot>
if you want to be that careful with scope, sure
07:09
<bakkot>
but if you're not using using you don't actually need to be that careful
07:09
<rbuckton>
Isn't that the point of the proposal?
07:10
<bakkot>
IMO the point of the proposal is basically using, and the other declarations are just nice-to-haves which would not be adequate motivation for the proposal on its own
07:12
<Steve Hicks>
The proposal was originally written before using existed, so that's definitely an opinion.
07:12
<rbuckton>
I can maybe get on board with a narrowly focused if (using x = ...; ...) {} proposal without supporting var/let/const as it also short circuits the whole destructuring and extractor concerns as well, since neither are allowed in using.
07:12
<bakkot>
yeah I said the same thing when it was originally presented
07:12
<bakkot>
I think it would be very weird to leave out let and const at that point
07:13
<bakkot>
like, as a user, that would make no sense
07:13
<Steve Hicks>
Would that be open to abuse by just writing using for ordinary non-disposable objects?
07:13
<rbuckton>
No, because that's an error.
07:13
<rbuckton>
using x = 1 throws
07:14
<rbuckton>
it only allows null, undefined, and an object with [Symbol.dispose]()
07:14
<Steve Hicks>
At that point it's basically just try-with-resources
07:14
<rbuckton>
No, try-with-resources doesn't support conditions
07:14
<bakkot>
nnnnot really? it's still a conditional
07:14
<rbuckton>
And using started as a try-with-resources variant
07:15
<Steve Hicks>
(false -> throw and catch, maybe? but point taken)
07:18
<rbuckton>
I think we need to knuckle down and get the pattern matching proposal up to date and present it soon. We've lost some momentum over the last year and at least one of the champions has had to step back.