Open samuelgoto opened 6 years ago
(also @bmeck)
To clarify: is it possible in any way for unless
to prevent return 2;
from executing, short of invoking the block that contains return 1;
lexically?
It certainly feels awkward for unlesss
to have the ability to return anything to a
that wasn't written lexically inside of a
in the block param.
Because receivers are written as functions in their own scope, there is nothing that they can do to change the return value of the functions. For example:
function unless(expr, block) {
// I can store block, setTimeout on it, pass it around, etc. For example:
// When executed, if block() returns, it throws a ContinuationException,
// something along the lines of this:
// http://tronicek.blogspot.com/2008/08/nonlocal-transfer.html
setTimeout(block);
// returning 2 here doesn't return to the ```a``` function, but rather to the ```unlesss```
// function.
return 2;
}
It is interesting to note, though, that unless
could use finally
and throw an exception. For example:
function unless (expr, block) {
try {
block();
} finally {
throw 1;
}
}
It is unclear to me what are the consequences of this and what are the possible solutions (e.g. swallowing exceptions? allowing?). Writing it down to make sure I don't forget what was discussed.
We discussed an example of this at the meeting, with the assumption that the completion value slot is filled in a well defined way.
unless
would write to a
's completion value slot including with normal completions.
a
would write to an implicit completion value and the above would roughly desugar to the following.
function a() {
let a_completion = {
type: 'normal',
value: undefined
};
let block_completion = unless(false, () => {
a_completion = {
type: 'return',
value: 1
}
});
switch (a_completion.type) {
case 'normal': break;
case 'throw': throw a_completion.value;
case 'return': return a_completion.value;
}
}
Which would decouple non-exception values from changing the completion value of a
. However, the question of if block_completion
above would be able to overwrite a_completion
for some types of completions. If so, which ones or why none.
I am not tied to any intent of the feature, but I feel like making some determination of pseudocode to be more concrete would make me able to more clearly discuss this.
@ljharb's feedback:
Is it possible for receivers to change the value that gets returned? For example:
Is it possible, in any way, for
unless
to control what gets returned toa
independently of what the block param returns lexically?