08:07
<nicolo-ribaudo>
Wow two experiments in the same meeting
08:09
<ljharb>
(btw i think the japan plenary end date is wrong in the previous slide ryzokuken )
08:17
<rbuckton>
Michael Ficarra: Minor, but I am unable to enable notifications
08:17
<nicolo-ribaudo>
yeah me too, I didn't get notified for the poll
08:22
<Michael Ficarra>
FYI the reply button is only supposed to be visible when there's an actual topic, and the agenda item intro doesn't count as a topic; somebody has to use the new topic button first (and a chair has to advance to it)
08:22
<Michael Ficarra>
in the moment, I was too panicked to think
08:22
<Michael Ficarra>
we had a poll?!
08:23
<eemeli>
For like 2 seconds.
08:23
<ljharb>
pro tip, check the log :-p
08:24
<Michael Ficarra>
the chairs haven't advanced to the secretary's report yet?
08:24
<Justin Ridgewell>
I believe we have
08:24
<Michael Ficarra>
I see now
08:25
<Michael Ficarra>
ujjwal, 19 seconds ago
08:25
<ryzokuken>
I did it when I read your message yeah
08:25
<Justin Ridgewell>
I did it, though?
08:25
<ryzokuken>
I hate this feature already btw
08:25
<Michael Ficarra>
we have a log now, you can't gaslight me
08:25
<ryzokuken>
race condition
08:25
<Justin Ridgewell>
Maybe it's because we reordered the Call for Notetakers before this?
08:26
<Justin Ridgewell>
Excuse me
08:27
<Michael Ficarra>
lmao
08:28
<Justin Ridgewell>
Are we in the same room?
09:06
<nicolo-ribaudo>
Only the chairs can write conclusions in TCQ?
09:07
<Chris de Almeida>
yes because only chairs can advance the agenda and it's a modal dialog that pops up when advancing
09:08
<Chris de Almeida>
it's not meant to be a replacement for the conclusion + summary we have in the notes doc
09:20
<Aki>
I frequently do not ask for summary/conclusion for Needs Consensus PRs, but this has led to more discussion than I expected so please do make sure that is added.
09:30
<canadahonk>
they are less than 20 minutes apart i think, checking
09:32
<canadahonk>
notes still has a few minutes lost
09:33
<Chris de Almeida>
there is no recording of the missing notes in the revision history, they're gone
09:33
<Caio Lima>
Regarding not writing a bunch of 0s as a motivation, we can actually use 42n * (10n ** 3000n)
09:33
<Chris de Almeida>
a bunch of stuff people said, is gone
09:33
<Michael Ficarra>
this notes thing is a recurring issue, it's not just this meeting
09:34
<Chris de Almeida>
I don't recall someone just nuking an entire page of discussion
09:34
<canadahonk>
same person is selecting again :p
09:34
<ljharb>
seems good to require login, then we have attribution
09:34
<nicolo-ribaudo>
I don't think we can continue the meeting until when this is solved
09:34
<ryzokuken>
doxx their anonymous animal
09:34
<Michael Ficarra>
I'm referring to someone selecting large chunks of text even though it was nobody on the call (presumably)
09:34
<nicolo-ribaudo>
Even if it might mean moving to a separate document and moving the bot to that new document
09:35
<canadahonk>
definitely before we resume after lunch at least
09:35
<canadahonk>
fwiw afaik what was lost was most of the conversation between ofr and jhd
09:36
<ljharb>
i can flesh out my part if needed
09:38
<Michael Ficarra>
of course a lot of engines don't use it, this degree of freedom is a carveout specifically for JSC
09:51
<yusukesuzuki>
Richard Gibson: OK, I found the commit.
https://github.com/WebKit/WebKit/commit/e4a6a6964d558f0b1e57d779a325b46a9c3bc2d1
The website which was broken at that time was https://www.tax.ny.gov/online/
09:53
<Michael Ficarra>
that seems like an important website
09:54
<Michael Ficarra>
like a life-changingly important website
09:54
<yusukesuzuki>
I remember that we got reports internally, saying "I cannot do tax return", yeah...
09:54
<snek>
can't believe mamdani would break javascript like this
09:54
<ljharb>
i'm sure someone can get mamdani to help fix it
09:55
<Michael Ficarra>
👮 #⏱️💀 Temporal Dead Zone 💀⏱️
09:55
<ljharb>
tbf i was actually being serious, i suspect it would be an actual viable channel. he be fixin stuff
09:59
<keith_miller>
IIRC, we also got reports after the revert that the Russian consulate websites were broken.
10:06
<Richard Gibson>
yusukesuzuki keith_miller if I'm reading correctly, what broke websites was the change to insert "get " and "set " where it was previously absent. Have you seen any evidence of sites relying upon presence of those prefixes for other built-in accessor functions? Because if not, then it seems like JSC could be compliant with https://github.com/tc39/ecma262/pull/3855 by uniformly omitting the prefix, like SpiderMonkey does.
10:38
<Richard Gibson>

I note also that the bug ticket mentions String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get), which is especially interesting because that's actually a distinct area of web-reality cross-implementation spec nonconformance—every major browser presents unique functions for Function.prototype.{arguments,caller} {get,set} rather than the specified realm-singleton empty-[[InitialName]] %ThrowTypeError% that non-browser implementations correctly expose:

$ eshost -si function-prototype-accessor-names.js 
## Source
const initialNamePatt = /function\s*(?:\[")?([^(]*?)(?:"\])?\s*[(]/;
const manifestations = new Map();
for (const key of ["arguments", "caller"]) {
  const desc = Object.getOwnPropertyDescriptor(Function.prototype, key) || {};
  for (const kind of ["get", "set"]) {
    const fn = desc[kind];
    if (!fn) continue;
    const name = Function.prototype.toString.call(fn).match(initialNamePatt)?.[1];
    const reprName = `name=${name ? JSON.stringify(name) : "<empty string>"}`;
    if (!manifestations.has(fn)) manifestations.set(fn, [`name=${reprName}`]);
    manifestations.get(fn).push(`${key}{${kind}}`);
  }
}
for (const [_fn, paths] of manifestations) print(`${paths[0]} [${paths.slice(1)}]`);


#### engine262, GraalJS, LibJS, Moddable XS, QuickJS
name=name=<empty string> [arguments{get},arguments{set},caller{get},caller{set}]

#### JavaScriptCore, SpiderMonkey
name=name="arguments" [arguments{get}]
name=name="arguments" [arguments{set}]
name=name="caller" [caller{get}]
name=name="caller" [caller{set}]

#### V8
name=name="get arguments" [arguments{get}]
name=name="set arguments" [arguments{set}]
name=name="get caller" [caller{get}]
name=name="set caller" [caller{set}]
11:29
<Aki>
Requests to delegates who did editor or TG updates: a short (one sentence is sufficient) summary of your update on the notes
11:52
<Justin Ridgewell>
I wonder if it's because we made the arg more complicated. It was originally smaller value is bigger waits, which matches low level C APIs?
12:00
<nicolo-ribaudo>
It seems lindeed like setting target to ESNext still downlevels in TS: https://www.typescriptlang.org/play/?target=99#code/MYGwhgzhAECC0G8BQ1XQAIBMCmxoGIAzAe2IG4kBfJIA
12:00
<rbuckton>
I am incorrect, TS does not preserve decorators with esnext as of yet
12:01
<rbuckton>
I cannot recall if this changed in the Go port of TypeScript, you'd have to ask danielrosenwasser what the plan is there
12:20
<ljharb>
the weight goes away from the wire and individual applications, though, and moves into the browser.
12:21
<canadahonk>
since there's nothing else in the agenda until the break can we expand the timebox?
12:22
<Justin Ridgewell>
As long as discussion remains productive, we can go a little longer
12:25
<Justin Ridgewell>
rbuckton: Do you want to enter yourself as a reply/
12:26
<Justin Ridgewell>
Never mind
12:29
<Justin Ridgewell>
Michael Ficarra: I think I just hit a race condition between a reply being deleted and me hitting next speaker.
12:30
<Michael Ficarra>
it depends on what your intent is when you press "next speaker"
12:30
<Michael Ficarra>
do you mean "the speaker that I currently see as next" or "the speaker that is currently next"?
12:30
<Michael Ficarra>
I would assume it's the latter, so there's no race condition to handle
12:31
<Justin Ridgewell>
I mean that between me reading the next item, and pressing, they deleted their reply. Now we're on the wrong topic.
12:32
<Justin Ridgewell>
This is supposed to be about the cost of desugaring.
12:33
<Michael Ficarra>
I guess I still don't understand the scenario, you're gonna have to explain it to me in an issue
12:34
<nicolo-ribaudo>
"As a chair, I want to mark that the current reply is done, but I don't want yet to move to the next topic as the topic person might have an answer or others might be getting on the queue"?
12:34
<nicolo-ribaudo>
And right now I assume we have a single button for that and "this topic is done", and somebody removing their last reply immediately switches the meaning of the button
12:35
<Justin Ridgewell>
I just wanted to move to the reply, but it no longer exists, and we went to the the next discussion item.
12:37
<Michael Ficarra>
ah now I get it
12:37
<Michael Ficarra>
okay that's an existing issue with the interaction types in TCQ, but we can probably do something better now
12:37
<Michael Ficarra>
open an issue!
12:40
<Justin Ridgewell>
Before I forget, the images show the previous speaker for a second before changing to the new speaker.
12:40
<Justin Ridgewell>
Even if the rest of the text has updated already
12:42
<Justin Ridgewell>
Now after 15m we've moved onto the correct topic
12:48
<nicolo-ribaudo>
Was SIMD withdrawn when at stage 3 or stage 2?
12:49
<ljharb>
it was 3, then 1, then withdrawn
12:50
<ljharb>
that's the only one tho afaik - Object.observe was stage 2.
12:52
<ljharb>
"Topic: <eom> is not allowed" wth, my topic got lost
12:52
<yusukesuzuki>
The reported website was relying on not having "get" / "set" prefix. So far, I'm not seeing any pages which is rather relying on "get" / "set" prefix existence, but since we are not dropping it so far, whether such websites exists or not is unknown to us (I hope it does not exist, but not so much confident. But maybe, if SpiderMonkey is not attaching these prefixes so far, probably this indicates that always-not-having-these-prefixes is web-compat...?)
12:52
<pzuraq>
for context, here's a minimal "compile out"/Sugar example
12:53
<pzuraq>
// input
class Foo {
  @reactive #bar = 123;
}

// output
let getBar, setBar, initBar;

class Foo {
  static {
    ({ get: getBar, set: setBar, init: initBar } = reactive(this)); 
  }

  #_bar = initBar(123);

  get #bar() {
    return getBar.call(this, this.#_bar);
  }

  set #bar(value: number) {
    this.#_bar = setBar.call(this, value);
  }
}
12:54
<pzuraq>
for private fields/methods
12:55
<pzuraq>
that (or something similar) needs to be emitted for every decorated private method/field (for common use cases)
12:58
<Justin Ridgewell>
Sorry, 2 min
12:58
<Michael Ficarra>
I think this topic deserves a continuation later in this meeting, if we have time
12:59
<Justin Ridgewell>
We'll figure it out, especially with the break to hallway track.
13:06
<pzuraq>
and a similar example for methods
13:06
<pzuraq>
// input
class Foo {
  @reactive
  #bar() {
    return 123;
  }
}

// output if bar becomes a class field
class Foo {
  #bar = reactive(function () {
    return 123;
  })
}

// output if bar remains a method
let barDecorated;

class Foo {
  static {
    barDecorated = reactive(this, function() {
      return 123;
    });
  }


  #bar(arguments) {
     return barDecorated.call(this, arguments);
  }
}
13:08
<nicolo-ribaudo>
This minimal output is with a hypothetical version of the proposal and not the current one, right?
13:09
<pzuraq>
yes, this is like, if we just have decorator syntax be blessed and specify semantics but not output (e.g. the JSSugar route)
13:09
<pzuraq>
we wouldn't have the accessor keyword for instance, so every field would need to emit the getters/setters
13:09
<pzuraq>
https://signalium.dev/core/signals-and-reactive-functions#reactive-functions
13:10
<pzuraq>
this is an example of a reactivity framework where I'm actively using decoration patterns a lot
13:10
<pzuraq>
I would like to be able to decorate methods, but it's costly so my current solution is
13:11
<Christian Ulbrich>
Decorators are used in a lot of frameworks, users clearly want them.
13:12
<pzuraq>
class Fetcher {
  baseUrl = signal('https://api.example.com');

  fetch = reactiveMethod(this, async (path: Signal<string>) => {
    const response = await fetch(`${this.baseUrl.value}${path.value}`);
    return response.json();
  });
}
13:13
<pzuraq>
it's not pretty but it works, and most of the time users are just meant to declare reactive functions (e.g. const myFunc = reactive(() => {})) so I've been ok with this, but it would be much nicer as a decorator
13:25
<Justin Ridgewell>
Would frameworks have added them if decorators weren't on standards track? Could they have been solved with another solution?
13:26
<dminor>
User interest does not necessarily make it a good idea for the language
13:26
<Justin Ridgewell>
I think we're suffering from the initial attempt at decorators that led to projects adopting a feature they shouldn't have.
13:26
<snek>
they came from frameworks first, right?
13:26
<Christian Ulbrich>
Basically it is all Google's fault, because they were so Decorator-focused that they coerced M$ to add them to TS so both could use TS for initial Angular 2.
13:26
<Justin Ridgewell>
Angular 💀
13:27
<Christian Ulbrich>
Since Angular decorators became popular and nobody cared, how they are actually implemented, as long as they worked with TypeScript.
13:27
<snek>
angular, known for high developer satisfaction
13:27
<Christian Ulbrich>
Google wanted to invent their own script-language called AtScript... basically specifically for that purpose...
13:28
<Justin Ridgewell>
I continually suffer from our backend Java Annotations. They are my most hated feature, and the reason I dislike decorators so much.
13:28
<Christian Ulbrich>
It does not matter, Decorators are now used. They are not so much used in Angular anymore, but in nest.js, Lit, Salesforce LWC, ...
13:29
<Justin Ridgewell>
Magic is bad, and our annotation implementation should be burnt with fire.
13:29
<Justin Ridgewell>
Maybe all of Java while I'm at it.
13:29
<Christian Ulbrich>
Annotations are annotations, decorators are much more powerful and for good reason :)
13:29
<snek>
i miss function decorators from python so much. also the getter/setter pattern. we should support that.
13:30
<ljharb>
tbf, java functions would make me hate functions in JS too, if i had to use them
13:35
<Justin Ridgewell>
Done.
14:14
<Michael Ficarra>
so does temporal_rs implement all of these fixes?
14:15
<Chris de Almeida>
not yet
14:20
<pzuraq>
FWIW, this is why I actually prefer decorators to annotations. Decorators are about replacing the existing thing with another, identical thing that adds some additional functionality (e.g. @memoize), whereas annotations expose information for external systems to metaprogram and then you get spooky-action-at-a-distance and headaches
14:21
<pzuraq>
like I said, decorators exist for standard functions in JS and we use them all the time
14:21
<pzuraq>
they're great
14:21
<Justin Ridgewell>
Our Decorators have annotation metadata, though.
14:22
<Chris de Almeida>
yeah, I think this is somewhere you really need to define terms to avoid misunderstanding
14:22
<Justin Ridgewell>
And they also allow general magic that makes tracing from source code difficult. I have to know the method being called, the decorator impl, and the runtime args passed to the decorator.
14:22
<pzuraq>
yeah, totally valid, you can still do difficult/magical things
14:22
<pzuraq>
but they are less magical than the alternatives in my experience
14:24
<pzuraq>
and our most recent spec is actually less magical in that regard - you can't add or remove non-related properties easily
14:28
<rbuckton>

Decorator metadata is still different from annotations though, and its more like defining a blessed extra property to share information between decorators. It allows for ergonomics vs not having them:

// with annotations

// NOTE: A and B can coordinate using metadata
@A
class C1 {
  @B
  method() {}
}

// NOTE: metadata is unique to each class
@A
class C2 {
  @B
  method() {}
}

// without metadata
const { A: A1, B: B1 } = createEntagledDecorators();

@A1
class C1 {
  @B1
  method() {}
}

// NOTE: needs new entangled instance
const { A: A2, B: B2 } = createEntagledDecorators();

@A2
class C2 {
  @B2
  method() {}
}
14:35
<pzuraq>

even the stage 1 spec allowed people to add additional fields/methods easily, and when I really stepped back I understood that was really bad for DX because of the magic. Like, people could do:

class Foo {
  @reactive
  bar = 123;
}

let foo = new Foo();

foo.setBar(456);
14:35
<pzuraq>
and that is absolutely terrible IMO. You could do even more of this in the OG stage 2 proposal
14:36
<pzuraq>
in the current proposal, you cannot do this very easily
14:36
<pzuraq>
it guides users away from complexity
14:36
<rbuckton>
I think the Symbol.metadata buy-in was that the presence of a decorator was a syntactic opt-in to add the Symbol.metadata property, so it wasn't dynamically added
14:37
<pzuraq>
right, that field would always exist if the class was decorated at all
14:37
<pzuraq>
may be undefined, but would be assigned (I think)
14:38
<pzuraq>
but that was just to avoid the dynamic shape change which was a hard constraint. The constraint we were given was that we had to basically know the shape at initial parse time, before executing any code at all
14:39
<pzuraq>
this is also what drove the accessor keyword. It was either that, or @accessor:decorator to denote that it did a shape change
14:40
<Christian Ulbrich>
I do not get it. Every means for meta programming allows magic, but "they-will-allow-to-do-crazy-things" is not a sufficient argument for me against them. I am in line with pzuraq with decorators you can actually tame the magic, i.e. use proper linting rules, because having decorators in the language will expose them to the AST.
14:40
<pzuraq>
from a language standpoint, it's also about symmetry
14:40
<pzuraq>
like, similar to the arguments for AsyncContext
14:41
<Justin Ridgewell>
We (Google Search) disallow many of the metaprogramming patterns because they can't be compiled efficiently. This is a new metaprogramming that we need to ban.
14:41
<Justin Ridgewell>
AC carries data, not implementations.
14:42
<Christian Ulbrich>
Recently I used them for some very basic AOP, i.e. just for annotation and then dynamically adding runtime behavior on composition / instantiation.
14:42
<Justin Ridgewell>
I want implementations to be static functions. Basically C. Let's make JS more like C.
14:42
<pzuraq>
yes, people can do crazy things with implicit context. But JS does have implicit context and there are a lot of users of it (e.g. Signals, Telemetry). From a language design perspective, it allows those to be implemented in both
14:42
<keith_miller>
Pointers!!
14:42
<pzuraq>
hmm
14:43
<pzuraq>
I think that to be more like C, you need to go back to the drawing board. A new language can make different decisions, but it's the worst of both worlds to have incomplete patterns
14:43
<pzuraq>
like in Go, you just can't have implicit context
14:43
<Zb Tenerowicz (ZTZ/naugtur)>
that ship might have sailed :)
14:43
<pzuraq>
whereas in most functional languages, you can
14:44
<pzuraq>
in JS, you kinda can
14:44
<keith_miller>
Memory corruption!!
14:44
<pzuraq>
that's a weird tension
14:44
<Justin Ridgewell>
I want the good parts of C.
14:44
<Justin Ridgewell>
Static functions and structs.
14:44
<keith_miller>
We're saying the same thing then
14:44
<pzuraq>
(any language that supports algebraic effects supports implicit context I believe)
14:45
<snek>
https://x.com/devsnek/status/1249369811454394368
14:45
<snek>
wow it doesn't embed
14:46
<Justin Ridgewell>
If we had a standard library that supported passing context explicitly, I would support that. But that would have to have been done 30 years ago.
14:46
<ljharb>
for a team, you can use linters to ban patterns; that's not necessarily a good reason to exclude something from the language
14:47
<Justin Ridgewell>

they can't be compiled efficiently

I think we should designing features that don't cause mass user harm.

14:48
<Justin Ridgewell>
This is like the DCE discussion we had in NYC.
14:48
<ljharb>
i agree. but not everyone has "compiles efficiently" as a constraint.
14:48
<ljharb>
meaning, it's not inherently "harm"
14:53
<nicolo-ribaudo>
We're missing module declarations!!!!
14:55
<ljharb>
import(specifier, { as: ['foo', 'bar'] })
14:56
<nicolo-ribaudo>
Nooo this reads like it's the opposite direction
14:57
<ljharb>
instead of "as" i guess it could be "only" or something
14:58
<canadahonk>
could someone kill the transcript bot 🫡
14:58
<nicolo-ribaudo>
  • filter
  • names
  • only
  • ...?
14:58
<nicolo-ribaudo>
I'll open an issue with names
14:58
<nicolo-ribaudo>
Whatever we pick is probably what people will then use to refer to the import { ... } as ns from syntax
14:59
<Caio Lima>
select 👀
15:09
<pzuraq>

fwiw, I think you could argue that features like closures cause mass user harm with this logic, and by extension promises/futures. There is a logic to this, for sure. But at the same time, I think that the complexity of futures/promises is worth it because of how complex traditional callbacks are.

Bringing it back to decorators and async-context, this is what I'm exploring with "reactive functions". You can think of a signals + reactive functions as analogous to an promises + async functions.

  • Async functions capture the execution context (e.g. the current variables in scope, the location of the program counter) and through that, know when and how to resume the function later.
  • Reactive functions capture the reactive context (e.g. the dependencies of the current function instance) and through that, know when and how to automatically re-execute and stay up to date.

So far, I'm finding these really simplify reactive code and make common, complex, and error-prone tasks much safer. But, they rely on implicit context (to gather the dependencies during execution) and decoration (to annotate the functions).

15:10
<pzuraq>
One of the nice things about JavaScript is that we enable these patterns to be explored in library land without committing to them in syntax first. That's how promises eventually happened, and eventually got us to async/await
15:12
<pzuraq>
I feel like my concept of "reactive functions" is pretty experimental. It's basically like, attempting to formalize/rationalize React's Hooks system, and also sort of tie it together with Signals. I could imagine in the future it solidifying and then eventually, like promises, proposing something like reactive function() {} as first class syntax
15:13
<pzuraq>
but I can't imagine jumping directly to that without a loooooot of experimentation and validation in the ecosystem first
15:13
<pzuraq>
so, like, my 2 cents, providing consistency and symmetry in the language, even around the more powerful metaprogramming features, is worth it IMO
16:12
<Chris de Almeida>
I restored the deleted content from earlier using the transcript bot's backup. Looks like the only thing that was missing was OFR's comments, so Olivier Flückiger please review when you have a chance. search for this text to find the paragraph: Just clarification since people are proposing
17:39
<Chris de Almeida>
for the most part, MF's TCQ 2000 XP Millennium Edition was excellent today however, I must formally declare my objection to TCQ Premium™️, a troublingly classist innovation which creates a two-tiered queue society where the landed gentry of TC39 can purchase tiny badges of aristocratic distinction while the rest of us toil badgeless in the proposal mines. the dichotomy betwixt badge-having nobility and the unadorned peasantry will surely lead to conflict in the near future
17:56
<Michael Ficarra>
you sound like a TCQ basic user, tbh
17:57
<Chris de Almeida>
😑
18:02
<Zb Tenerowicz (ZTZ/naugtur)>
I thought these were only awarded for notetaking
18:04
<Chris de Almeida>
I would support this 🙂 -- but the status quo is that some folks possess the badge yet didn't help with notes
18:06
<bakkot>
logbot (i.e. the physical computer in my house) is back online and logs are now up to date
18:24
<Zb Tenerowicz (ZTZ/naugtur)>
I would support this 🙂 -- but the status quo is that some folks possess the badge yet didn't help with notes
Outrageous 😅
18:25
<Zb Tenerowicz (ZTZ/naugtur)>
Wrong channel, I suppose. IMHO letting MF have fun with it is the best payment we can offer for building it.