On Thu, Jul 26, 2012 at 2:20 AM, Stas Malyshev <smalys...@sugarcrm.com> wrote:
> Hi!
>
>> The implementation is outlined in the RFC-stub here:
>> https://wiki.php.net/rfc/generators
>>
>> Before going any further I'd like to get some comments about what you
>> think of adding generator support to PHP.
>
> Some notes on the RFC:
> 1. I think we should support rewind() by just creating a new generator
> instance (i.e. doing the same that is done when generator is called for
> the first time). If it depends on the resource that generator changes as
> a side effect, so be it. rewindable() looks like unnecessary
> complication which IMHO will not be useful in most cases.

I think the best thing to do is neither. I.e. don't support rewinding
and also don't provide a rewindable() function. I think that the
concept of generators implies that it is a one-time data stream.
Rewinding would fight the very nature of the concept. I think the
currently implemented behavior of rewind() being a no-op is okay, but
one could obviously also throw an exception when rewind() is called
more than once, to make errors easier to see.

> 2. I understand the pre-yield code is called on current(). What about
> key()? I think it makes sense to call it there too - i.e. pre-yield code
> is called whenever first key() or current() - it should be made explicit.

All the Iterator functions (and send()) will move to the first yield
before performing their respective action. This is also mentioned in
the RFC:

> If the generator is not yet at a ''yield'' statement (i.e. was just created
> and not yet used as an iterator), then any call to ''rewind'', ''valid'', 
> ''current'',
> ''key'', ''next'' or ''send'' will resume the generator until the next 
> ''yield''
> statement is hit.

> 3. return values. I think non-empty return in generator should produce a
> notice or E_STRICT.

Non-empty return values currently throw an E_COMPILE_ERROR. I think
that's okay as doing `return $foo` in a generator is clearly some kind
of bug.

In the future, should yield delegation be implemented, the return
value would become meaningful again, as it would be the result of the
delegation instruction. This is important for coroutine-based parsing
code, so that you can write $result = yield* $this->parseSomething();.

> 4. What happens to the state variables when generator is cloned? Just
> addref or real cloning for objects?

Cloning currently just uses addref everywhere. I'm not really sure
what the right behavior is in that situation. Generally I think that
cloning a generator is a rather strange thing to do, so it might make
sense to drop cloning-support altogether. At least I can't really
imagine a use case for it.

> 5. Are multiple yields allowed? I.e. the rfc mentions something like
> yield yield $a - what that would mean? I'd allow yield only be applied
> to variable expression (lval) because double yield doesn't make sense to
> me, but maybe I miss something.

yield yield $a would basically first yield $a and then receive some
value (via send) and yield that value again. Nothing you'd normally do
;) It was mentioned only as a syntax ambiguity consideration.

Actually I added some additional parenthesis requirements for yield.
For example you'd have to write the above as `yield (yield $a)` now
(which should be slightly more clear). I haven't yet reflected this
change in the RFC, but I'll add a section on it later.

> 6. “Sending values” section seems to be missing. Especially useful would
> be to cover what happens with keys there and what is the syntax there -
> is it just "$a = yield;"? Or does it mean when yield is used in
> expression it becomes incoming yield? And, last but not least - do we
> need sending into generators at all?

Yeah, I haven't written that section yet. But it is fairly simple: If
you go $generator->send($foo) then $foo will be the result of the
current `yield` expression. And yes, this also works with keys and
values. All of the following are valid:

    $data = yield;
    $data = (yield $value);
    $data = (yield $key => $value);

The first case is the most common though. I.e. you usually use it
either as a generator or a reverse generator, not both. But doing both
is also common for cooperative multitasking etc.

Regarding the last question: I think the feature is worth adding. It
is a very powerful concept that is hard to implement otherwise. Useful
in particular for things like parsing and multitasking.

> 6. What happens if you send into a by-ref generator? Is the data sent
> by-ref then? What if it's an expression that can't be send by-ref?

No, sending is always by-value. By-ref only affects the yielding part.

Nikita

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to