03:53
<rkirsling>
I feel dumb but can somebody tell me what test262 directory a test for null[{ toString() { ... } }] belongs in?
04:02
<rkirsling>
e.g. language/expressions/property-accessors seems like it's about specific properties to access and not about the general concept of how "bracket access" should operate
04:36
<bakkot>
rkirsling: I don't see an obvious place for it
04:36
<bakkot>
so... make language/expressions/member-expression?
04:39
<rkirsling>
can do
12:08
<Jack Works>
ljharb: I just realized that I had previously suggested a Function.prototype.try, and that kind of conflicts with Promise.try in that Promise inherits from Function but Promise.try is a different thing than Function.prototype.try would be
does it have a receiver parameter?
13:10
<ljharb>
a receiver param for function try is awkward imo
13:29
<nicolo-ribaudo>
fn(...args)!? and obj.method(...args)!? syntax instead of .try, so that there is no question problem with the receiver?
13:31
<Anthony Bullard>
Are we talking about Rust? 😉
14:28
<Ashley Claymore>
Part of me feels like it should be a static helper. As this is the year of `Object.groupBy` and `Promise.try` but we don't have a class for what this returns. Or maybe we wait until we do and then it's `Result.try(fn)`
18:14
<bakkot>
It is not worth having syntax for this
18:14
<bakkot>
For the specifying the receiver, Function.prototype.tryCall(obj.method, obj, ...args)
18:37
<ljharb>
i don't think it makes sense to have a receiver argument at all. you can do that yourself with .bind. Function.try or Result.try makes much more sense to me.
18:54
<Michael Ficarra>
there's no need for a receiver parameter, you can just do Function.prototype.call.bind(Function.prototype.call).try(fn, thisValue, ...args)
18:55
<bakkot>
uhhhh I would much prefer to write obj.meth.tryCall(obj, ...args) instead of that
18:55
<Michael Ficarra>
I often save this "call-bound call" (Function.prototype.call.bind(Function.prototype.call)) and use it throughout my programs
18:55
<Michael Ficarra>
maybe instead we need to introduce a Reflect.call or something that has it pre-defined
18:55
<bakkot>
https://github.com/js-choi/proposal-function-demethodize
18:56
<Michael Ficarra>
lol nice: https://www.npmjs.com/package/call-bind
18:56
<bakkot>
https://github.com/tc39/proposal-call-this
18:57
<bakkot>
I am not in favor of new syntax but yes a new method would be good
18:58
<Michael Ficarra>
I think some people may be opposed to it being on Reflect, but it seems so nice to have call sitting next to apply there
18:58
<Richard Gibson>
I don't know why the current dislike of receiver is so prevalent (cf. proposal-async-context#80 and the aforementioned proposal-promise-try#15) and assumed to be permanent, but I very much dislike the corresponding fracturing of the language in which new proposals gratuitously diverge from Function.prototype.{apply,call} and Reflect.apply—especially when discussion in plenary has raised opposition to anything that encourages more use of things like .bind and arrow wrappers.
18:59
<Michael Ficarra>
Richard Gibson: maybe because most of the time you don't need to specify receiver, and when you do, you have call-bound call to bail you out?
18:59
<bakkot>
Function.prototype.apply/call and Reflect.apply are special helpers, which are very rarely sensible precedent to use for other methods
19:00
<bakkot>
I am happy to have a Function.prototype.tryCall sitting next to Function.prototype.try for that use case, but I don't want to make the signature of methods like that worse for the common case of no receiver just for parity with Function.prototype.call
19:00
<ljharb>
the receiver argument in array methods is terrible and if not for precedent, i'd hope none of the new methods would have had it. bind, or an arrow, is The Way
19:01
<ljharb>
I am happy to have a Function.prototype.tryCall sitting next to Function.prototype.try for that use case, but I don't want to make the signature of methods like that worse for the common case of no receiver just for parity with Function.prototype.call
which is also why "receiver" and "varargs" is a problem, because having to put null when you don't care about the receiver sucks
19:01
<ljharb>
so, we should just omit the receiver. the language has lots of tools to handle that, and there's proposals for the ones it doesn't.
19:08
<Richard Gibson>

bind, or an arrow, is The Way

have you forgotten that implementers specifically objected to proposals that would encourage their use?

most of the time you don't need to specify receiver
worse for the common case of no receiver

Emphasis mine. This is presumptive about future language use, but even so I would agree if not for precedent in the existing ways to call functions with arbitrary arguments. To have new signatures leave no room for an argument that is present in all old ones seems like unnecessary complexity. If you want to break with the past and foster arrow functions, then make that be necessary for arguments as well (e.g., try(() => fn(…))).

19:09
<bakkot>
To have new signatures specifically require the user to think about receivers is unnecessary complexity
19:12
<ljharb>

bind, or an arrow, is The Way

have you forgotten that implementers specifically objected to proposals that would encourage their use?

most of the time you don't need to specify receiver
worse for the common case of no receiver

Emphasis mine. This is presumptive about future language use, but even so I would agree if not for precedent in the existing ways to call functions with arbitrary arguments. To have new signatures leave no room for an argument that is present in all old ones seems like unnecessary complexity. If you want to break with the past and foster arrow functions, then make that be necessary for arguments as well (e.g., try(() => fn(…))).

that wasn't about encouraging their use, but their overuse
19:13
<ljharb>
as for "make it necessary for arguments as well", i agree with that, which is why Promise.try didn't initially have that capacity, but folks wanted it so i added it
19:13
<bakkot>
I am happy to have additional methods which allow specifying the receiver, but now that we have spread args there's no reason to use Function.prototype.call/apply except when specifying the receiver - specifying the receiver is what they're for. It really, really does not make sense to consider them precedent for other functions
19:13
<ljharb>
either way, "no receiver, with arguments" is way way more common than "with a receiver", at least for any usage that isn't literally obj.method(...args)
19:14
<Richard Gibson>
either way, "no receiver, with arguments" is way way more common than "with a receiver", at least for any usage that isn't literally obj.method(...args)
by "more common" you're referring to authored code, right?
19:14
<ljharb>
yes? if the alternative is "generated code", we should not care about what generated code does (not wrt API design, i mean, only wrt breakage)
19:18
<bakkot>
It is worth caring about generated code, but that should take the form of supplying APIs suitable for generated code, not changing the APIs for human-authored code
19:18
<bakkot>
... human or llm I guess
19:18
<Andreu Botella>
To have new signatures specifically require the user to think about receivers is unnecessary complexity
+1 to this, especially because of language learnability. this/receivers aren't things that come early when learning JS, especially because of how they differ from the equivalents in other languages. Even if Promise.try and AsyncContext are advanced use cases, language learning is non-linear.
19:20
<Richard Gibson>
fine, I yield
19:31
<Justin Ridgewell>
I also think an inline syntactic arrow fn doesn’t have the same performance penalties that dynamic closure-returning helpers and fn.bind() would have.
19:40
<littledan>

Richard Gibson:

have you forgotten that implementers specifically objected to proposals that would encourage their use?

Thinking about "how many closures is this going to imply are allocated in real use cases" is different from "thisArg should be a thing". Signals try to pass the right this value to achieve a similar goal.