Closed mvriel closed 6 years ago
It's an interesting question. I suppose as it will act like a return in most (all) ways, it is irrelevant to the outside user.
On the other hand it might be worth noting the value is coming from yield just to let the user know they do not need to assign all content to a variable before using, as looping through a value which yields data piece at a time is going to be much more efficient that storing it all up then iterating.
Technically it's just @return \Generator
, and I don't think you can specify a more specific type because every yield
can output a different type.
In that case we should be safe using @return Generator<int>
or whatever the syntax ends up being for collections. So this is clearly different from @return array<int>
, and developers should know how to handle the two.
@mvriel Close 'er up!
@philsturgeon Using @return Generator<int>
will clash will coroutine return values, should PHP want to introduce them. Context: Python, as well as the Harmony proposal, support yield from
/yield*
which is effectively a call to a coroutine, where all it's yielded values are passed through. The return value of the coroutine will be the return value of yield from
/yield*
. Currently the only valid "return value" for a generator is null
but supporting this would allow arbitrary return values.
As such it might be better for forwards-compatability to use @yield int
rather than @return Generator<int>
.
References: PEP 380 - Syntax for Delegating to a Subgenerator
Proviso on that.... yield can be used to pass input to a generator as well as returning a value from it.... that would definitely be an interesting one to document, an argument passed not in the function call, but when the code reaches a specific line of execution within the function
I am currently not (yet) sold on adding a new tag but that also stems from my lack of knowledge on the concept of yield. From a black box principle, so without knowing there is a yield call in there, this feels a lot like an iterator.
@nikic can you provide more information on how this should be viewed from a black box principle? What I see is a method that @return
s a Generator class (which is an iterator) and it may @see
another generator method as source data.
Am I wrong here?
Proviso on that.... yield can be used to pass input to a generator as well as returning a value from it
Sounds like it would be a good idea to add a @yield
tag for documenting THAT, while reusing @return
for documenting values that are yielded from a generator, since from the outside, yield and return are not really different.
A generator is a form of iterator. If you are using it as a co-routine, then it becomes a special iterator, one that accepts values called on the iterator. The language construct makes the pattern easily to implement with fewer lines and adds convention. There is only one way for generators and co-routines to work.
To summarize, there are five primary types involved in a generator:
Generator
.V
returned by Generator::current()
(value).K
returned by Generator::key()
S
which Generator::send()
accepts as the argument.R
which is returned by Generator::getReturn()
which is likely to be added in PHP 7.So essentially a generator function returns a Generator<V, K, S, R>
type.
PHP 7 return type annotations for generators can use just Generator
(or Iterator
or Traversable
) - more detailed information about the yielded values etc is not possible due to the lack of generics.
As such I think phpdoc should use @return Generator
and support additional generic arguments if possible, though probably just having V
and K
is enough for most practical purposes.
Is it necessary to have a further type for Exceptions thrown into a generator that the generator can catch?
@MarkBaker Theoretically yes, one could further specialize this. But it's probably good enough to just keep throw()
accepting an Exception
object without further specifying which exception objects exactly are "accepted". It's usually a different type for every potentially throwing yield anyway. (It depends more on the function that is being called by the yield.)
For arrays and array-like constructs, such as collection objects, there should be a simple way to declare what key and value types they contain. I think generators can benefit from this as well.
Unless a more specific notation is necessary (and proposed, because I am lacking in detailed enough knowledge on coroutines) this is currently the best that I can come up with
If this needs to be pursued further, please bring this up as a new thread on the FIG mailing list for discussion -- https://groups.google.com/forum/#!forum/php-fig
Do we need something for the yield keyword or does @return suffice?