Suggestion: use `yield.sent` instead of `function.sent`
Opened this issue ยท 25 comments
It IMHO explains itself a little better, and it looks more generator specific than function.sent
(which looks like it would belong in any function, not just any generator).
function.sent
would also be helpful for arrow functions too, so it's not just generators - I think yield
wouldn't be appropriate.
@ljharb What would function.sent
be with arrows?
Hmm, maybe I'm thinking of something different. Rereading https://github.com/allenwb/ESideas/blob/master/Generator%20metaproperty.md does imply it's just for generators.
I was thinking of it like arguments
for arrow functions.
A complication is that yield
in non-strict code and outside of a generator yield
is just a normal non-reserved identifier that can used as a variable name. Hence is such contexts yield.sent
is just a property reference. We can't change that for backwards compat reasons. In a strict mode code (including within generator functions) yield.sent
is a syntax error because yield
is an AssignmentExpression rather than a PrimaryExpression.
It's bad enough that yield
means different things based upon the context. I think it would be making things worse to for yield.sent
to have differing valid context dependent meanings.
@allenwb Welp... ๐ฆ Problem is, there's not really a lot of decent options...
Keep in mind, function.sent
is generator-specific, so I was going from there, and my yield.sent
was also meant to be generator-specific.
It's bad enough that
yield
means different things based upon the context. I think it would be making things worse to foryield.sent
to have differing valid context dependent meanings.
Agreed, hence my reservations now. :-\
It's bad enough that yield means different things based upon the context. I think it would be making things worse to for yield.sent to have differing valid context dependent meanings.
If we take the point of view that non-strict mode is supposed to be mostly a backward-compatibility mode, and that new code are encouraged (and even forced in some cases) to be strict, that concern about non-strict mode should be less important.
I see a great opportunity to use yield.sent yield.last
instead of function.sent
.
We could imagine something more generic like this:
function * it() {
let i = 0;
while (true) {
i += yield.last; // get absolute last value sent with next()
yield i; // we don't update *i* here
}
}
const _it = it();
_it.next(1); // 1
_it.next(2); // 3
Revisiting this, I feel yield.received
would be better, since it's referring to the last received next
parameter. yield.last
, yield.sent
, and function.sent
all seem to imply the last yielded value, not the last received value.
All names of yield.xxx
suffer from the issues:
yield.xxx
and(yield).xxx
have different semantics in generators.yield.xxx
have different semantics in generators (meta property) and non-strict non-generator codes (normal property).yield.xxx
andyield xxx
looks close if the font of.
is too inconspicuous ๐yield.xxx
andyield*xxx
looks close if the font of.
is too conspicuous ๐คฃyield.xxx
implies something caused byyield
but actually the main reason of this proposal is about the first sent value before anyyield
(or without anyyield
).
I feel no any single issue is fatal, but there are too many potential ambiguity so maybe we should first consider alternatives of function.xxx
instead of yield.xxx
.
I don't think we have to worry about the font; anything can be unreadable with the wrong font.
Adding parens to things causes different semantics all over the place; i don't think that's a concern either - similarly, yield
has a different semantic in generators vs non generators, so that's also not a concern.
However, your last point is compelling; it'd be great to find another alternative.
Adding parens to things causes different semantics all over the place
@ljharb Could you explain more about that? I don't know other case which have different semantics between identifier.xxx
with (identifier).xxx
it'd be great to find another alternative
Do you have any options? ๐
(a?.b).c
vsa?.b.c
a, b.c
vs(a, b).c
a + b + c
vs(a + b) + c
vsa + (b + c)
when all three are different types
etc
No suggestions yet.
@ljharb What I mean is member access (or similar, like metaproperty) chaining ๐
a, b.c
vs(a, b).c
a + b + c
vs(a + b) + c
vsa + (b + c)
So I don't think these two cases are comparable to yield.xxx
vs (yield).xxx
at all.
(a?.b).c
vsa?.b.c
Actually this case seems weird at first glance, and there were several issues and discussions about that. IMO yield.xxx
vs (yield).xxx
is even worse because: it seems no real use case of (a?.b).c
, but (yield).xxx
in generator has valid use cases.
I have some thought about the name.
The real meaning of function.sent
in a generator function is "the value sent by the last next()
call to a generator object which created by this generator function". The problem is, strictly speaking, the value is sent to "generator object" not "generator function", so function.sent
sounds more like "a function instance sent to somewhere".
I feel if we use function.xxx
it should sound like "the value that generator function got".
Here are the names go to my mind:
function.got
function.input
function.lastValue
function.currentValue
function.receivedValue
function.received
var.received
(whilevar
seems have no relationship with generator, it could be understand as a special variable in the generator function)
@hax What about function.received
?
@isiahmeadows Oh, I forgot to add it. Added now.
Currently I slightly prefer function.got
or function.input
because they are shorter ๐.
I also slightly worry about function.received
could be considered to be a boolean.
What do you think of these names?
I remain concerned about using function
for something that doesn't apply to all functions :-/
maybe function*.sent
would work though (swap out "sent" for whatever the bikeshed produces)
Though function*.sent
may work, it looks very unlike a "meta property", not sure how committee would accept it ๐
. And addition of *
also make ergonomics a little bit worse (function
is already long enough)
For me the best would be something able to retrieve every values sent though next
(not only the first one)
keyWord
may be any of: last
, sent
, received
, input
, ... => TO BE DEFINED
I agree with @ljharb , function.keyWord
may be a little confusing. This specs only apply to generator functions intead of everyone.
(yield).keyWord
=> resolves first the yield, then go to the 'keyWord' property
yield.keyWord
=> returns the last value provided to next
I personally prefer yield.received
as its for me the most explicit.
Note: function *f() { yield.received }
throws an early error in Chrome, at least.
I do agree with @allenwb that yield.anything
is not ideal, since it's a valid identifier anywhere else.
Note:
function *f() { yield.received }
throws an early error in Chrome, at least.I do agree with @allenwb that
yield.anything
is not ideal, since it's a valid identifier anywhere else.
I'm not convinced that the fact yield
is an identifier in sloppy mode is that compelling of a reason not to use it. It already has different meanings depending on context for tagged template literals (any others?) yield `foobar`;
,
Although I do think the difference between (yield).blah
vs yield.blah
might be slightly confusing though given they can both occur in the same context. However I do feel like people wouldn't use (yield).prop
as much with yield.blah.prop
available anyway.
I am considering maybe lastValue@yield
could work ๐ though it still not solve:
yield.xxx
(orxxx@yield
) implies something caused byyield
but actually the main reason of this proposal is about the first sent value before anyyield
(or without anyyield
).
I strongly agree with yield.received
I strongly disagree with function.sent
think something other would be better