03:42
<pokute>
There's resistance against adding syntax to ECMAScript and implicit tail-call elimination doesn't seem to be working out from engine implementers. Then how about explicit, magical Function.prototype.callWithElimination(this, ...params) that gives an error during AST generation if the call is not in correct place for eliminating the tail call?
07:13
<ljharb>
what is "AST generation"? that's not a thing in the spec afaict
07:20
<ryzokuken>
what is "AST generation"? that's not a thing in the spec afaict
They mean "while parsing"
07:20
<ryzokuken>
But I don't think a function call should fail while parsing?
07:20
<ljharb>
sure, but how could you parse an API call like that?
07:21
<ryzokuken>
Exactly
07:21
<ljharb>
const x = Function.prototype.callWithElimination; return x.call(f);
07:21
<ljharb>
pretty sure it requires syntax to detect the position of something, eg tail call position
07:21
<ryzokuken>
I don't think this will work, it's valid syntax and shouldn't fail.
07:23
<ryzokuken>
pretty sure it requires syntax to detect the position of something, eg tail call position
You mean syntax around the expression inside the function?
07:23
<ryzokuken>
The expression containing the tail call I mean.
07:35
<Mathieu Hofman>
Yeah I don't see how something that isn't syntax could cause a parsing time error. Now the premise about syntax is that it should pay for itself. If there is a way to add something without syntax, then there is little justification to add syntax. If the only option is syntax (like in this idea of explicit tail call) then the question becomes, is it worth the cost? I'm not sure I know enough about tail call use cases to form a complete opinion, but the fact we've gotten away without it for so long is an indicator there are likely ways to avoid a tail call optimization requirements.
13:11
<pokute>
const x = Function.prototype.callWithElimination; return x.call(f);
I was thinking of that, but it's difficult. I was thinking of only recognising return recursiveFunc.callWithElimination(undefined, accumulator, moreParams) or something like that.
13:12
<ryzokuken>
I was thinking of that, but it's difficult. I was thinking of only recognising return recursiveFunc.callWithElimination(undefined, accumulator, moreParams) or something like that.
that do you mean "only recognizing"?
13:12
<ryzokuken>
that it won't work if you assign it to another variable?
13:12
<ryzokuken>
that seems to go against pretty much every single rule of the language
13:14
<pokute>
As the only valid position that doesn't give error during parsing. The error thing was that it should give an error before runtime so that it's impossible to have code that tries to call it in wrong position. And yeah, can't assign. :-) It's magical. But it's not unprecended! You can't have const myImport = import.
13:15
<ryzokuken>
import is a keyword
13:15
<ryzokuken>
this is a function on a prototype
13:17
<pokute>
Well, we could make it less conventional with return recursiveFunc[Function.withCallEliminationSymbol]( ... ).
13:20
<pokute>
I was thinking of early error just that people don't accidentally write it in positions where it can't be tail eliminated away.
13:21
<Ashley Claymore>
I should re-read the previous meeting notes, but in my memory I didn't think syntax was the main item stopping tco ? I thought it was more implementation complexity and relation to the stack trace proposal?
13:23
<pokute>
Explicity would weaken the expectations that stack traces and debugging is identical to normal function calls.
13:39
<Ashley Claymore>
last notes I could find: https://github.com/tc39/notes/blob/master/meetings/2016-05/may-24.md#syntactic-tail-calls-bt
15:17
<ryzokuken>
Yeah, I don't think it would be easy to sell new syntax for TCO to the committee...
16:36
<Mathieu Hofman>
Well, we could make it less conventional with return recursiveFunc[Function.withCallEliminationSymbol]( ... ).
This is still a dynamic non parse time evaluation. `import()` is pure syntax. `Function` is not and can be replaced by code, as can any of it's prototype or self methods.
16:37
<Mathieu Hofman>
If you want explicit tail call that throws at parse time, i don't see any other way but requiring syntax.
16:38
<ljharb>
I don’t see how non-syntax could throw at any time
16:40
<Mathieu Hofman>
Yeah I think you're right, you'd probably need something to link your current stack to the runtime call to ensure it throws if not I'm tail position. That reeks of `function.callee`
16:42
<Mathieu Hofman>
At which point since you need syntax anyway, I'd rather make it static/parse time syntax. Note that I still don't understand enough the motivation.