13:52
<zacque>
Hi, what's the difference between Completion Record normal and return type?
13:53
<zacque>
https://tc39.es/ecma262/#table-completion-record-fields
13:56
<jmdyck>
If you evaluate a statement (within a function body, say), and it causes a return from that function, then that's signaled via a return completion. If evaluation is to proceed normally to the next statement, then that's signaled by a normal completion.
14:00
<zacque>
Makes sense, but what about the next paragraph: "Callable objects that are defined in this specification only return a normal completion or a throw completion. Returning any other kind of Completion Record is considered an editorial error."
14:00
<zacque>
I'll expect it to include return completion?
14:02
<jmdyck>
No, if, within function A, you call function B, that call cannot cause a return from function A. (But it can cause A to throw.)
14:05
<jmdyck>
The wording you quoted is not the best: callable objects (i.e., functions) don't return completions at all.
14:08
<jmdyck>
Rather, the completions are 'internal' to the process of calling a function. I.e., certain algorithms in the spec are returning completions.
14:12
<jmdyck>
It would be more accurate to say something like "a function's [[Call]] internal method can only return a normal completion or a throw completion..."
14:13
<zacque>
Hmm, I see... But still, it's a bit weird to me. Can you please point me to the semantics of function invocation in the spec? I can't seem to find it in https://tc39.es/ecma262/#sec-function-objects, https://tc39.es/ecma262/#sec-ecmascript-language-functions-and-classes, or https://tc39.es/ecma262/#sec-ecmascript-language-expressions
14:14
<zacque>
What if I want to describe the semantics of invoking function A?
14:16
<jmdyck>
Function invocation is kind of involved. You should maybe start at https://tc39.es/ecma262/#sec-function-calls-runtime-semantics-evaluation
14:17
<jmdyck>
skip the first group and go to CallExpression : CallExpression Arguments
14:18
<jmdyck>
to EvaluateCall(), to Call(), to [[Call]]
14:20
<jmdyck>
And then either https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist or https://tc39.es/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist, depending on whether the function is a built-in. (Actually, there are a couple other possibilities here that you don't need to worry about.)
14:22
<jmdyck>
For a built-in function, that'll go to BuiltinCallOrConstruct, which basically bottoms out in prose.
14:26
<jmdyck>
For a non-built-in, you'll get to OrdinaryCallEvaluateBody, which calls EvaluateBody, which goes various ways depending on what kind of function it is. If it's the plainest kind of function, then you'll go to EvaluateFunctionBody which calls FunctionDeclarationInstantiation to instantiate the function's declarations, and then Evaluation to evaluate its body.
14:35
<zacque>
Great, thanks for your pointers! I'll need some time to digest them
14:36
<jmdyck>
Yup!
14:39
<jmdyck>
And all those operations return a completion, either normal or throw.
14:42
<jmdyck>
(Actually, some say "an abrupt completion" rather than "a throw completion". I'm not sure whether that's an unnecessary generalization, or I'm forgetting something.)
14:44
<nicolo-ribaudo>
An abrupt completion is any completion that's not a normal completion
14:44
<nicolo-ribaudo>
So throw/return/break/continue
14:45
<jmdyck>
Right, but do you think these ops can validly return a return/break/continue completion?
14:46
<nicolo-ribaudo>
No — in this case they are equivalent, but not always :)
14:47
<jmdyck>
Okay, so that's what I meant by "unnecessary generalization". The operation header is naming a more general return-type than it could.
17:22
<jmdyck>
In the case of EvaluateCall, it looks like the possibility of a non-throw abrupt completion comes from ArgumentListEvaluation, which I think has that possibility because an argument could involve a yield expression, which (under somewhat obscure circumstances) could result in a return completion. Is that right, @bakkot?
17:35
<jmdyck>
Similarly, for OrdinaryCallEvaluateBody and the ones below it, I think "an abrupt completion" is in practice "a throw completion or a return completion". But here, the return completion happens for a more prosaic reason (usually): executing a ReturnStatement.
17:41
<jmdyck>
([[Call]] and [[Construct]] explicitly handle the possibility of a return completion, and only return a normal completion or throw completion .)