Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generator.prototype is not defined #3230

Open
arai-a opened this issue Dec 3, 2023 · 9 comments
Open

Generator.prototype is not defined #3230

arai-a opened this issue Dec 3, 2023 · 9 comments

Comments

@arai-a
Copy link
Contributor

arai-a commented Dec 3, 2023

The "Generator Objects" section first mentions "A Generator is an instance of a generator function ...".

https://tc39.es/ecma262/#sec-generator-objects

A Generator is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

Then "Properties of the Generator Prototype Object" section defines "Generator prototype object" as %GeneratorFunction.prototype.prototype%

https://tc39.es/ecma262/#sec-properties-of-generator-prototype

The Generator prototype object:

  • is %GeneratorFunction.prototype.prototype%.

The "Generator prototype object" name is used by GeneratorFunction.prototype.prototype's definition, which makes sense:

https://tc39.es/ecma262/#sec-generatorfunction.prototype.prototype

The initial value of GeneratorFunction.prototype.prototype is the Generator prototype object.

But remaining subsections of "Generator Objects" define properties of Generator.prototype, that sounds like the same thing as %GeneratorFunction.prototype.prototype%, but it's not defined explicitly:

https://tc39.es/ecma262/#sec-generator.prototype.constructor

27.5.1.1 Generator.prototype.constructor

https://tc39.es/ecma262/#sec-generator.prototype.next

27.5.1.2 Generator.prototype.next ( value )

It also makes the first paragraph "A Generator is an instance of ..." confusing, that it sounds like Generator in Generator.prototype.constructor is "A Generator" instance (which is not true, because the instance doesn't have prototype property).

There would be 2 options to solve this:

  • (A) Replace all occurrences of Generator.prototype with %GeneratorFunction.prototype.prototype% (while keeping the ids of those sections, to avoid breaking links)
  • (B) Add a section or a paragraph that defines that Generator.prototype is a shorthand notation for %GeneratorFunction.prototype.prototype% (also clarifies Generator there isn't "A Generator" above)

Same for AsyncGenerator.prototype in https://tc39.es/ecma262/#sec-asyncgenerator-objects

@arai-a
Copy link
Contributor Author

arai-a commented Dec 3, 2023

* (A) Replace all occurrences of `Generator.prototype` with `%GeneratorFunction.prototype.prototype%` (while keeping the ids of those sections, to avoid breaking links)

This doesn't work with the current ecmarkup, because it doesn't accept a dot inside %.

https://github.com/tc39/ecmarkup/blob/08aa4a70f7695509fa779acf9173862a96de4084/src/lint/collect-header-diagnostics.ts#L50-L56

I'll see if the linter can be modified to accept the syntax.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2023

"Generator" is defined in the first sentence of https://tc39.es/ecma262/#sec-generator-objects, which means that "Generator.prototype.constructor", for example, is also defined. I'm confused what the problem is here.

@arai-a
Copy link
Contributor Author

arai-a commented Dec 3, 2023

I was assuming that "Generator" means the g() value for function *g() {}. Isn't it correct? Does it mean the g value ?

@ljharb
Copy link
Member

ljharb commented Dec 3, 2023

A Generator is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

I read that as the return value of g(), there, yes.

@arai-a
Copy link
Contributor Author

arai-a commented Dec 3, 2023

In that case, Generator.prototype is undefined, given g().prototype is undefined.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2023

ahh ok, on a reread "instance of a generator function" actually means g itself, yes. I see how that's confusing as I was myself confused.

It's still defined, though :-)

@arai-a
Copy link
Contributor Author

arai-a commented Dec 3, 2023

The sentence says "A Generator" conforms to the Iterator interfaces and Iterable Interfaces.
g() conforms to both, but g doesn't conform to neither.
So, only g() matches the requirement.

https://tc39.es/ecma262/#sec-generator-objects

A Generator is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

https://tc39.es/ecma262/#sec-iterable-interface

The Iterable Interface
The Iterable interface includes the property described in Table 77:
...
@@iterator

https://tc39.es/ecma262/#sec-iterator-interface

The Iterator Interface
An object that implements the Iterator interface must include the property in Table 78. Such objects may also implement the properties in Table 79.
...
"next"
"return"
"throw"

To my understanding, g is "a generator function", and "instance of" there means the function call operation, thus "instance of a generator function" there should be g().

Actually, "SOMETHING instance"/"instance of SOMETHING" term seems to be used in 2 ways throughout the spec,
one is that SOMETHING itself, and the other is that the result of SOMETHING(),
that would be the source of the confusion here.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2023

I agree with you that some terminology needs clarifying in this section.

@arai-a
Copy link
Contributor Author

arai-a commented Dec 4, 2023

I've checked the occurrences of "generator(s)" (without explicit suffix like "generator function" or "GeneratorBody"),
and almost all cases "generator" means g().

Sometimes "Generator" is used as abbreviation of "GeneratorFunction", but still the formal name would be "GeneratorFunction" for them.

https://tc39.es/ecma262/#sec-strict-mode-code

Function code that is supplied as the arguments to the built-in Function, Generator, AsyncFunction, and AsyncGenerator constructors is...

One exception is the following, which I'm not sure if it's really intended to be abbreviation:

https://tc39.es/ecma262/#table-well-known-intrinsic-objects

| %GeneratorFunction% | The constructor of Generators |

But anyway, defining "Generator" as a name of g() sounds more cleaner.
and in that case, the Generator.prototype notation remains problematic.

Then, if replacing with %GeneratorFunction.prototype.prototype% is not good for readability, what if we add yet another well-known intrinsic %GeneratorPrototype%, in the same way as %StringIteratorPrototype%?
That way the tc39/ecmarkup#564 patch isn't necessary.

I haven't chosen this in the first place because I thought the dot in the %GeneratorFunction.prototype.prototype% is part of name, instead of actual property operation, and having another alias would make the situation complicated. But if %GeneratorFunction.prototype.prototype% means almost same thing as %GeneratorFunction%.prototype.prototype, adding yet another well-known intrinsic for the value would be fine?

Also, about the "instance of a generator function", I think we should avoid the use of the combination of "instance"+"generator function" there, because both "GeneratorFunction constructor" and function* g() {} are callable, and it's hard to see which it means, given "instance" means 2 things.
We could instead say "A Generator can be created by calling a generator function. A generator conforms to both the Iterator and Iterable interfaces."

arai-a added a commit to arai-a/ecma262 that referenced this issue Dec 5, 2023
arai-a added a commit to arai-a/ecma262 that referenced this issue Dec 10, 2023
arai-a added a commit to arai-a/ecma262 that referenced this issue Jan 12, 2024
arai-a added a commit to arai-a/ecma262 that referenced this issue Jan 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants