Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupport
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.
If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.
Nikita
On Tue, Jun 5, 2012 at 10:35 AM, Nikita Popov nikita.ppv@googlemail.comwrote:
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsBefore going any further I'd like to get some comments about what you
think of adding generator support to PHP.If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.Nikita
--
Some observations and questions:
- In the RFC, the top example claims to make use of the
file()
function, but in fact does not. Did you meanfopen()
? Or did you mean
that this to be an example of someone writing their ownfile()
function in
PHP for some reason (the "userland" reference is a bit confusing IMHO given
the context). - In what way(s) do you believe this approach would differ from inline
functions and what advantage(s) do you see in those differences? - What release version do you believe should be targetted for this?
--Kris
Some observations and questions:
In the RFC, the top example claims to make use of the
file()
function, but
in fact does not. Did you meanfopen()
? Or did you mean that this to be an
example of someone writing their ownfile()
function in PHP for some reason
(the "userland" reference is a bit confusing IMHO given the context).
It's an implementation of thefile()
function in userland code (as
opposed to the internalfile()
implementation).file()
returns all
lines from a file as an array.
In what way(s) do you believe this approach would differ from inline
functions and what advantage(s) do you see in those differences?
I'm not sure what you mean by inline functions. PHP doesn't do
function inlining (and it doesn't seem related to this). Or do you
mean closures? Again, I'm not sure how closures are related to this.
What release version do you believe should be targetted for this?
The next major version, i.e. PHP 5.5.
Nikita
On Wed, Jun 6, 2012 at 10:09 AM, Nikita Popov nikita.ppv@googlemail.comwrote:
Some observations and questions:
In the RFC, the top example claims to make use of the
file()
function,
but
in fact does not. Did you meanfopen()
? Or did you mean that this to
be an
example of someone writing their ownfile()
function in PHP for some
reason
(the "userland" reference is a bit confusing IMHO given the context).
It's an implementation of thefile()
function in userland code (as
opposed to the internalfile()
implementation).file()
returns all
lines from a file as an array.In what way(s) do you believe this approach would differ from inline
functions and what advantage(s) do you see in those differences?
I'm not sure what you mean by inline functions. PHP doesn't do
function inlining (and it doesn't seem related to this). Or do you
mean closures? Again, I'm not sure how closures are related to this.
Yes sorry, I meant closures. I have the nasty habit of calling them
"inline functions," forgetting that that term already means something
completely different lol.
I guess the point I was making is that closures and generators are very
similar in many ways. This isn't to say that generators are a bad idea (I
actually think it's an awesome idea), but the question occurred to me as to
whether or not generators will add any functionality that can't already be
accomplished (albeit somewhat more clumsily) via closures. I tend to think
the answer to that probably lies in yields, but I think it would be
beneficial to address this-- along with some examples to illustrate this
advantage over closures in appropriate use-cases-- in the RFC. I agree
with Stas that, while it's a great idea, the RFC itself is far from
complete.
What release version do you believe should be targetted for this?
The next major version, i.e. PHP 5.5.
Ok good. Just wanted to make sure we weren't talking about squeezing this
into 5.4 lol. Personally, I think RFCs should specify the target PHP
version when applicable. I know it's not required but I think it'd be a
good idea to get in that habit anyway IMHO.
--Kris
Nikita
Hi Nikita:
the most important part to me is how did you implemented `yield`
keyword, is there a whole patch file I can look into?
what will happen if you use a `yield` in a normal function?
actually, I tried to implemented coroutine, but since I could not
find a way to make zend_execute interruptable, then I didn't make it.
so, I am really interesting of this tech-specific :)
thanks
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsBefore going any further I'd like to get some comments about what you
think of adding generator support to PHP.If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.Nikita
--
--
Laruence Xinchen Hui
http://www.laruence.com/
Hi Nikita:
the most important part to me is how did you implemented
yield
keyword, is there a whole patch file I can look into?
Nervermind, I will check the branch out later
thanks
what will happen if you use a
yield
in a normal function?actually, I tried to implemented coroutine, but since I could not
find a way to make zend_execute interruptable, then I didn't make it.so, I am really interesting of this tech-specific :)
thanks
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsBefore going any further I'd like to get some comments about what you
think of adding generator support to PHP.If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.Nikita
--
--
Laruence Xinchen Hui
http://www.laruence.com/
--
Laruence Xinchen Hui
http://www.laruence.com/
Hi Nikita:
the most important part to me is how did you implemented
yield
keyword, is there a whole patch file I can look into?
Nervermind, I will check the branch out laterthanks
After a quick look, I think the main idea should goes to two parts:
- implement yield (Zend)
- implement spl_generators but not generator class (Spl)
then we can implement spl_coroutine later base on this. what do you think?
thanks
what will happen if you use a
yield
in a normal function?actually, I tried to implemented coroutine, but since I could not
find a way to make zend_execute interruptable, then I didn't make it.so, I am really interesting of this tech-specific :)
thanks
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsBefore going any further I'd like to get some comments about what you
think of adding generator support to PHP.If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.Nikita
--
--
Laruence Xinchen Hui
http://www.laruence.com/--
Laruence Xinchen Hui
http://www.laruence.com/
--
Laruence Xinchen Hui
http://www.laruence.com/
Hi Nikita:
the most important part to me is how did you implemented
yield
keyword, is there a whole patch file I can look into?
Nervermind, I will check the branch out laterthanks
After a quick look, I think the main idea should goes to two parts:
- implement yield (Zend)
- implement spl_generators but not generator class (Spl)
yield is interesting. It is one of the main features Facebook added, so
it might be worthwhile poking someone there for their implementation
details in order to at least be somewhat compatible.
-Rasmus
hi Rasmus, Sara,
Adding Sara to the loop as she is around and may miss that thread. We
also tried to convince her to contribute that back to core :)
Hi Nikita:
the most important part to me is how did you implemented
yield
keyword, is there a whole patch file I can look into?
Nervermind, I will check the branch out laterthanks
After a quick look, I think the main idea should goes to two parts:
- implement yield (Zend)
- implement spl_generators but not generator class (Spl)
yield is interesting. It is one of the main features Facebook added, so
it might be worthwhile poking someone there for their implementation
details in order to at least be somewhat compatible.-Rasmus
--
--
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Hi Nikita:
the most important part to me is how did you implemented
yield
keyword, is there a whole patch file I can look into?what will happen if you use a
yield
in a normal function?actually, I tried to implemented coroutine, but since I could not
find a way to make zend_execute interruptable, then I didn't make it.
Yes I also faced that problem. The current execute() function accepts
an op_array and initializes the execution context from that
(execute_data + CVs + Ts).
So I added a new function execute_ex() which takes that execution
context directly. The execute() function now works by initializing the
execute_data using a new zend_create_execute_data_from_op_array()
function and then calls execute_ex() with it.
The most relevant commit for this change is
https://github.com/nikic/php-src/commit/f627be52540738e124da7cb1566d7f60a2b6a48b.
Nikita
Before going any further I'd like to get some comments about what you
think of adding generator support to PHP.
I approve.
A few comments on the current RFC:
- The RFC is too vague.
- You're violating the contract of Iterator left and right.
current()
andkey()
should return false when !valid().next()
is underspecified.
valid() refers to a section that doesn't exist. And if you cannot
implementrewind()
, doing nothing is not an option. In fact, if you
can't implement Iterator in full, you should implement Traversable
instead. RewindableGenerator could perhaps implement Iterator though --
but I find the nature of RewindableGenerator very strange. Whether an
iterator is rewindable or not seems to be related to the nature of the
generator (e.g., is it reading packets from the network). It's not
something you can wrap a non-rewindable generator and expect it to work.
So it's a sort of unsafe operation, like a cast in C. - Overall, the RFC is very underspecified. We never have a formal
description of what a generator is and exact semantics of it. There is
no reference to exceptions. What to do if the generator returns
function. If the generator can be a function method. - There are missing sections
I suppose this is a work in progress and that you just want to gauge
the general interest, and I hope you take these considerations into
account.
--
Gustavo Lopes
Before going any further I'd like to get some comments about what you
think of adding generator support to PHP.I approve.
A few comments on the current RFC:
- The RFC is too vague.
Yup, it's not yet complete.
current()
andkey()
should return false when !valid()
Are you sure about that? The Iterator::current() docs don't specify
anything, but the Iterator::key() docs say that it should returnNULL
on failure. Checking on the first spl class that came to my mind
SplFixedArray also returnsNULL
when it is out of elements.
My personal preference would be to throw exceptions if those two
methods are called after the generator was closed (as calling them is
clearly an error, isn't it?), but I see that this would be
inconsistent with the usual iterator behavior.
next()
is underspecified.
Not sure what exactly you mean.next()
really doesn't do much more
than resuming the generator. What should I add additionally about it?
valid() refers to a section that doesn't exist.
Yes, sorry, I hadn't yet written it. I now added it at
https://wiki.php.net/rfc/generators#closing_a_generator.
And if you cannot implement
rewind()
, doing nothing is not an option.
I was thinking of the Generator as a NoRewindIterator, which also
simply does nothing whenrewind()
is called on it. This allows you to
start traversing the iterator in one loop and continue traversing it
in another loop:
function *allNaturalNumbers() {
for ($i = 0; ; ++$i) {
yield $n;
}
}
$numbers = allNaturalNumbers();
echo 'First loop:', "\n";
foreach ($numbers as $n) {
echo $n, "\n";
if ($n == 3) break;
}
echo 'Second loop:', "\n";
foreach ($numbers as $n) {
echo $n, "\n";
if ($n == 6) break;
}
This would output:
First loop:
1
2
3
Second loop:
4
5
6
Generators in Python behave the same way. (To be fair though Python
generally has no notion of rewinding an iterator, so all
iterators in Python act like that.)
I don't know whether that behavior is of any use, so I'll gladly
change the behavior to throwing an exception if that's more desirable.
In fact, if you can't implement Iterator in full, you should implement Traversable instead.
Not sure whether the lack of rewinding behavior really disqualifies it
to use the Iterator interface. I think having the internal iteration
methods exposed is quite handy, especially if you consider their use
as coroutines, where you often want to call the iteration interface
manually and not using a foreach loop.
RewindableGenerator could perhaps implement Iterator though -- but I find
the nature of RewindableGenerator very strange. Whether an iterator is
rewindable or not seems to be related to the nature of the generator (e.g.,
is it reading packets from the network). It's not something you can wrap a
non-rewindable generator and expect it to work. So it's a sort of unsafe
operation, like a cast in C.
Yes, agree with that.
- Overall, the RFC is very underspecified. We never have a formal
description of what a generator is and exact semantics of it. There is no
reference to exceptions. What to do if the generator returns function. If
the generator can be a function method.
Yes, the RFC is only a stub, it's not complete yet. But to answer your
questions:
- Exceptions can be thrown from generators as always.
- Not sure what you mean by "generator returns function". What would
be that problem with that? - Generators can be methods, as shown in the example in the
Introduction section. Closures can also be generators.
I suppose this is a work in progress and that you just want to gauge the
general interest, and I hope you take these considerations into account.
Yup, thanks for your comments!
Nikita
Nikita,
I don't know whether that behavior is of any use, so I'll gladly
change the behavior to throwing an exception if that's more desirable.
You can't throw an exception from rewind, since it's called before
foreach(). So it wouldn't be iterable then.
I think the noop on rewind is valid in this context, as long as it's
documented...
Anthony
current()
andkey()
should return false when !valid()Are you sure about that? The Iterator::current() docs don't specify
anything, but the Iterator::key() docs say that it should returnNULL
on failure. Checking on the first spl class that came to my mind
SplFixedArray also returnsNULL
when it is out of elements.
My bad. I was under the impression the semantics were similar to those
of next()
, key()
, etc. Instead the docs say under current()
that the
function can return anything, under key) that it returns NULL
on failure
(and issues an E_NOTICE) and for next()
that "the return value is
ignored" -- whatever that means; I'll interpret it as saying anything
can be returned. I'm not sure how correct this documentation is, though.
next()
is underspecified.
Not sure what exactly you mean.next()
really doesn't do much more
than resuming the generator. What should I add additionally about it?
Sorry for not having been clearer. I mean you say "Resumes the
generator (unless the generator is already closed)", but you don't
specify what it returns (though apparently Iterator does not re
valid() refers to a section that doesn't exist.
Yes, sorry, I hadn't yet written it. I now added it at
https://wiki.php.net/rfc/generators#closing_a_generator.And if you cannot implement
rewind()
, doing nothing is not an
option.
I was thinking of the Generator as a NoRewindIterator, which also
simply does nothing whenrewind()
is called on it. This allows you to
start traversing the iterator in one loop and continue traversing it
in another loop:function *allNaturalNumbers() { for ($i = 0; ; ++$i) { yield $n; } } $numbers = allNaturalNumbers(); echo 'First loop:', "\n"; foreach ($numbers as $n) { echo $n, "\n"; if ($n == 3) break; } echo 'Second loop:', "\n"; foreach ($numbers as $n) { echo $n, "\n"; if ($n == 6) break; }
This would output:
First loop: 1 2 3 Second loop: 4 5 6
Generators in Python behave the same way. (To be fair though Python
generally has no notion of rewinding an iterator, so all
iterators in Python act like that.)I don't know whether that behavior is of any use, so I'll gladly
change the behavior to throwing an exception if that's more
desirable.In fact, if you can't implement Iterator in full, you should
implement Traversable instead.
Not sure whether the lack of rewinding behavior really disqualifies
it
to use the Iterator interface. I think having the internal iteration
methods exposed is quite handy, especially if you consider their use
as coroutines, where you often want to call the iteration interface
manually and not using a foreach loop.RewindableGenerator could perhaps implement Iterator though -- but I
find
the nature of RewindableGenerator very strange. Whether an iterator
is
rewindable or not seems to be related to the nature of the generator
(e.g.,
is it reading packets from the network). It's not something you can
wrap a
non-rewindable generator and expect it to work. So it's a sort of
unsafe
operation, like a cast in C.
Yes, agree with that.
- Overall, the RFC is very underspecified. We never have a formal
description of what a generator is and exact semantics of it. There
is no
reference to exceptions. What to do if the generator returns
function. If
the generator can be a function method.
Yes, the RFC is only a stub, it's not complete yet. But to answer
your
questions:
- Exceptions can be thrown from generators as always.
- Not sure what you mean by "generator returns function". What would
be that problem with that?- Generators can be methods, as shown in the example in the
Introduction section. Closures can also be generators.I suppose this is a work in progress and that you just want to gauge
the
general interest, and I hope you take these considerations into
account.
Yup, thanks for your comments!Nikita
--
Gustavo Lopes
(Sorry, I pressed something that sent the message prematurely)
current()
andkey()
should return false when !valid()Are you sure about that? The Iterator::current() docs don't specify
anything, but the Iterator::key() docs say that it should returnNULL
on failure. Checking on the first spl class that came to my mind
SplFixedArray also returnsNULL
when it is out of elements.
My bad. I was under the impression the semantics were similar to those
of next()
, key()
, etc. Instead the docs say under current()
that the
function can return anything, under key) that it returns NULL
on failure
(and issues an E_NOTICE) and for next()
that "the return value is
ignored" -- whatever that means; I'll interpret it as saying anything
can be returned. I'm not sure how correct this documentation is, though.
next()
is underspecified.
Not sure what exactly you mean.next()
really doesn't do much more
than resuming the generator. What should I add additionally about it?
Sorry for not having been clearer. I mean you say "Resumes the
generator (unless the generator is already closed)", but you don't
specify what it returns (though apparently Iterator does not require you
to specify anything specific) and you don't say what happens when
theiterator is already closed.
In fact, if you can't implement Iterator in full, you should
implement Traversable instead.
Not sure whether the lack of rewinding behavior really disqualifies
it
to use the Iterator interface. I think having the internal iteration
methods exposed is quite handy, especially if you consider their use
as coroutines, where you often want to call the iteration interface
manually and not using a foreach loop.
Well, the Iterator::rewind() docs say that rewind()
rewinds the
iterator. If this is not possible, then Iterator should not be
implemented. See
http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.8
In the same order, your options are:
- As changing Iterator is not possible, have a new interface, say,
BasicIterator from which Iterator will inherit withoutrewind()
. - Make all the Generators rewindable (possibly by fetching a new
generator each time). - Do not implement Iterator.
(By the way, if you implement Traversable, one you can always use the
unsafe IteratorIterator to get access to the methods)
- Exceptions can be thrown from generators as always.
- Not sure what you mean by "generator returns function". What would
be that problem with that?
I mean how do you deal with "return $foo" in the body of the generator?
Does it work like a final yield? Is the return value ignored?
- Generators can be methods, as shown in the example in the
Introduction section. Closures can also be generators.
Can other callable classes be generators?
Are you planning on any internal API for functions to implement
generators (though I really haven't thought how that would work)?
--
Gustavo Lopes
I mean how do you deal with "return $foo" in the body of the generator? Does
it work like a final yield? Is the return value ignored?
Currently there will be a fatal error if return statements (with
values) are used in the generator. In the future I'd like to use the
return value as the result of a yield from / yield* expression, as it
is currently done in Python and JavaScript. This is particularly
useful if you are delegating control to another coroutine. This way
you can for example break down a coroutine-based parser into several
functions (instead of having one big ugly function).
Are you planning on any internal API for functions to implement generators
(though I really haven't thought how that would work)?
I don't think that this is possible. Generators require that the
execution context is suspended in some way and we have to that control
only over userland code, not internal C code.
Nikita
Are you planning on any internal API for functions to implement
generators
(though I really haven't thought how that would work)?
I don't think that this is possible. Generators require that the
execution context is suspended in some way and we have to that
control
only over userland code, not internal C code.
Couldn't we simulate this by saving the state in a heap allocated
structure (whose exact form would depend on the generator
implementation). Something like:
struct generator_context {
zval *(yield_next)(struct generator_context);
}
struct spec_generator_context {
struct generator_context parent;
int foo;
}
PHP_FUNCTION(get_generator)
{
struct spec_generator_context *ctx = emalloc(*ctx);
ctx->parent.yield_next = foo_bar();
return_value = make_internal_generator(ctx);
}
And you could also change the yield_next pointer in foo_bar() to avoid
going through goto's or switch statements. Possibly yield_next could be
take the arg with double indirection and you could also completely
replace the context.
I understand this has the problem that the internal and userspace
implementations would be markedly different.
--
Gustavo Lopes
Hi internals!
Hi Nikita,
Before going any further I'd like to get some comments about what you
think of adding generator support to PHP.
I have always hoped to see the “yield” keywork introduced in PHP. I even
suggested that in this mailing-list at least one time but I'm very glad
to see some patches coming out.
In addition to Gustavo's remarks, I wonder how the GC would collect a
Generator object that is not use anymore (especially with a referenced
yield). Does it fit to the current CG strategy or do we need an extra
strategy? I would notice that the “Yield by reference” section does not
exist but you have targeted it).
Moreover, I wonder how a “recursive yield” would act (something like
“public function *f ( … ) { … yield $this->f(…); … }”). It is possible?
Is it anticipated?
Thanks for you work.
Cheers.
--
Ivan Enderlin
Developer of Hoa
http://hoa.42/ or http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
Hello Ivan,
Moreover, I wonder how a “recursive yield” would act (something like
“public function *f ( … ) { … yield $this->f(…); … }”). It is possible? Is
it anticipated?
According to the RFC, your syntax will yield an entire generator and not
its intividual values. Please consider this example:
function * f() { ... }
function * g() {
yield f();
}
function * h() {
foreach( f() as $key => $value )
yield $key => value;
}
The pattern in function h() is quite common, and it is what you ask for. It
would be nice to have some syntactical sugar for it, maybe something like
that:
public function * h() {
yield foreach f();
}
Good work, I am looking forward to having generators in php.
Lazare INEPOLOGLOU
Ingénieur Logiciel
2012/6/6 Ivan Enderlin @ Hoa ivan.enderlin@hoa-project.net
Hi internals!
Hi Nikita,
Before going any further I'd like to get some comments about what you
think of adding generator support to PHP.
I have always hoped to see the “yield” keywork introduced in PHP. I even
suggested that in this mailing-list at least one time but I'm very glad to
see some patches coming out.In addition to Gustavo's remarks, I wonder how the GC would collect a
Generator object that is not use anymore (especially with a referenced
yield). Does it fit to the current CG strategy or do we need an extra
strategy? I would notice that the “Yield by reference” section does not
exist but you have targeted it).
Moreover, I wonder how a “recursive yield” would act (something like
“public function *f ( … ) { … yield $this->f(…); … }”). It is possible? Is
it anticipated?Thanks for you work.
Cheers.
--
Ivan Enderlin
Developer of Hoa
http://hoa.42/ or http://hoa-project.net/PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/Member of HTML and WebApps Working Group of W3C
http://w3.org/
On Wed, Jun 6, 2012 at 12:20 PM, Ivan Enderlin @ Hoa
ivan.enderlin@hoa-project.net wrote:
In addition to Gustavo's remarks, I wonder how the GC would collect a
Generator object that is not use anymore (especially with a referenced
yield). Does it fit to the current CG strategy or do we need an extra
strategy? I would notice that the “Yield by reference” section does not
exist but you have targeted it).
I added a new section which answers the question at least partially:
https://wiki.php.net/rfc/generators#closing_a_generator
If you don't need the generator object anymore you can either
explicitly ->close() it or wait until all references to it are removed
(typically when leaving the scope of the calling function). When the
generator is closed it releases all used resources, including the
suspended execution context and the currently yielded value. Whether
or not the value is yielded by reference shouldn't make a difference.
So, yes, the current GC strategy works well for generators too :)
Moreover, I wonder how a “recursive yield” would act (something like “public
function *f ( … ) { … yield $this->f(…); … }”). It is possible? Is it
anticipated?
Your particular code would simply yield a generator object (as that's
what $this->f(…) returns).
If instead you wanted to yield all values from that object you could
wrap it in a foreach loop:
function *f() {
// ...
foreach ($this->f() as $value) {
yield $value;
}
// ...
}
What this doesn't yet properly cover is the use of generators as
cofunctions. In this case it is desirable that ->send() calls are also
propagated (same applies to ->close() and the not yet implemented
->throw()).
To cover all those use-cases you'd have to come up with a rather big
and ugly block of code (you can find a Python same implementation in
http://www.python.org/dev/peps/pep-0380/#formal-semantics).
Thus it is clear that another expression is required which allows you
to delegate execution to another generator/cofunction. In Python this
is "yield from", in JavaScript "yield*".
A tree implementation using it could look like this:
class Tree implements IteratorAggregate {
protected $value, $left, $right;
public function __construct($value, Tree $left = null, Tree $right = null) {
$this->value = $value;
$this->left = $left;
$this->right = $right;
}
function *getIterator() {
if ($this->left) yield* $this->left;
yield $this->value;
if ($this->right) yield* $this->right;
}
}
As you can see the iterator implementation is dead simple.
(Note though that the yield* expression described above isn't yet
implemented, but I plan to implement it.)
Nikita
Hi Nikita,
On Wed, Jun 6, 2012 at 12:20 PM, Ivan Enderlin @ Hoa
ivan.enderlin@hoa-project.net wrote:In addition to Gustavo's remarks, I wonder how the GC would collect a
Generator object that is not use anymore (especially with a referenced
yield). Does it fit to the current CG strategy or do we need an extra
strategy? I would notice that the “Yield by reference” section does not
exist but you have targeted it).
I added a new section which answers the question at least partially:
https://wiki.php.net/rfc/generators#closing_a_generator
Good. Thank you.
If you don't need the generator object anymore you can either
explicitly ->close() it or wait until all references to it are removed
(typically when leaving the scope of the calling function). When the
generator is closed it releases all used resources, including the
suspended execution context and the currently yielded value. Whether
or not the value is yielded by reference shouldn't make a difference.
So, yes, the current GC strategy works well for generators too :)
Ok. A very naive question: would it be interesting to make the
difference between a “yield” and a “weak referenced yield values” (same
concept that https://wiki.php.net/rfc/weakreferences which is under
voting phase as the RFC said).
Thank you for your clarifications.
--
Ivan Enderlin
Developer of Hoa
http://hoa.42/ or http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
I don't understand why you need to introduce two new keywords into the
language - * and yield. Could you not solve it like follows?
// Generator implements Iterable
class AllEvenNumbers extends Generator {
private $i;
public __construct() { $this->i = 0; }
function generate() {
return ($this->i++) * 2;
}
}
That way I think you can persist state (as part of the class instance)
and implement rewind (per whichever way you do it - either caching the
output, or serialising the class instance) without having to introduce
yet more keywords.
If this is instead a discussion to specifically implement yield,
rather than simplifying the implementation of rewindable Iterators, it
might be more useful to frame the discussion in that way.
Jevon
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsBefore going any further I'd like to get some comments about what you
think of adding generator support to PHP.If you don't know what generators are you should have a look at the
"Introduction" section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.Nikita
Hi internals!
In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupportThe implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generators
A small progress update on this:
- There now is support for yield by reference
- Generators are now automatically detected by the presence of "yield"
instead of requiring the "*" modifier.
The main open point I still have is whether or not generators should
have a throw() method (á la Python). I couldn't yet find a convincing
use case for it, so I'm considering to just leave it out.
If there is any further feedback on the proposal, I'd love to hear it :)
Nikita
2012/7/20 Nikita Popov nikita.ppv@gmail.com:
Hi internals!
The implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generatorsA small progress update on this:
- Generators are now automatically detected by the presence of "yield"
instead of requiring the "*" modifier.
My first thought was how could someone reading the code see, that it
is a generator?
I mean: The "yield" can be between 50 lines of code. How could someone
see that? That a machine can do this is out of question, but humans
can't see that. Why is this important? Because when I see such code as
in the RFC and overlook the "yield" I would think "WTF", how could the
code work like this?
Why would someone not see this? Assume that the code was written and
is now quite old. The original developer is gone. A new one sits on
his place and now the customer says "hey, there is a bug anywhere".
The developer begins to search for it, and has no clue, how he can
reproduce it. Maybe he finds a part and he thinks now "Whoa, WTF" and
begins to debug that. After a while he will of course find "Oh, it's a
generator... just forgotten, that PHP can have that and the 'yield' is
so small in the middle of the function, nobody will see that..." But
he has spend some time to find that out.
That's what I think will happen. I think "yield" makes it more
difficult to maintain unknown code.
I think "yield" alone is too less. I think the function should be
explicitly marked as generator function.
Stupid Suggestions:
generator function gen()
{
yield 1;
}
generator gen()
{
yield 1;
}
function generator gen()
{
yield 1;
}
Hm... not really satisfied with that. For me this is a little bit
unlogical, that just a simple function can return an object.
So, how about implementing as a class? I mean: If it is returning a
class, why not implement it as class?
class gen implements generator
{
function __generator()
yield 1;
}
}
class gen extends generator
{
function __generator()
yield 1;
}
}
Calling looks for me now much less "magic":
$gen = new gen;
$gen->next();
As maintainer I see "oh, it's a magic method", it's such an iterator thingy.
Another advantage: It's not final. I could replace next()
etc. with my
own implementation.
And it works more hand in hand with iterators.
Just my very primitive first thoughts as PHP-scripts-developer,
without knowing much about the implementations in other languages. :)
PS: I would like to see that yield goes hand in hand with the iterator-stuff.
PPS: Ok, maybe a change isn't really needed, but I think how to use
this in a good manner (to avoid the problems mentioned above) should
be part of the docs.
--
Regards, Alex Aulbach
My first thought was how could someone reading the code see, that it
is a generator?
Somewhat snarky answer: By documenting the code in the first place.
Yeah, I know, we all inherit other people's code and the other person never
writes comments.
I don't think this is as big of a problem in practice, however. If you're
looking at the function to understand what it does, you're certainly
looking at statements like "return $foo;" already, right? Why would "yield
$foo;" be any more stealthy?
You posit that future engineer will have to spend hours understanding what
generatorX does because it's 50+ lines long and original engineer isn't
around anymore, but if the function is so complex, then future engineer is
going to be spending hours whether or not it's a generator at all. Code
like that is just bad code. The fact that it's a generator isn't the
problem, nor is whether it's been explicitly flagged as such.
Hm... not really satisfied with that. For me this is a little bit
unlogical, that just a simple function can return an object.
So, how about implementing as a class? I mean: If it is returning a
class, why not implement it as class?Because that misses the entire point of generators as simplified
iterators. What you suggest already exists, it's called: class foo
implements Iterator { /* iterator funcs */ } Also, it doesn't allow for
generators as class methods:
class foo {
function bar() {
yield 1;
}
}
Since this isn't Java, you can't really do:
class foo {
class bar implements generator {
function __generator() {
yield 2;
}
}
}
PS: I would like to see that yield goes hand in hand with the
iterator-stuff.
Curious if you could expand on that. Generators are iterators, so not sure
what you're asking for.
-Sara
2012/7/23 Sara Golemon pollita@php.net:
Curious if you could expand on that. Generators are iterators, so not sure
what you're asking for.
It's the point which is unlogical for me. Maybe it's a question. If
the generator is an object with the implementation of an iterator, why
do we need to have it as function?
--
Alex Aulbach
2012/7/23 Sara Golemon pollita@php.net:
Curious if you could expand on that. Generators are iterators, so not sure
what you're asking for.
It's the point which is unlogical for me. Maybe it's a question. If
the generator is an object with the implementation of an iterator, why
do we need to have it as function?
Much easier to make an iterator with a function than as a class.
--
Andrew Faulds
http://ajf.me/
2012/7/23 Sara Golemon pollita@php.net:
Curious if you could expand on that. Generators are iterators, so not sure
what you're asking for.
It's the point which is unlogical for me. Maybe it's a question. If
the generator is an object with the implementation of an iterator, why
do we need to have it as function?Much easier to make an iterator with a function than as a class.
--
Andrew Faulds
http://ajf.me/--
I agree, implementing a class only for iterator may be pain sometimes, and functions is much better - especially when 5.3 got the anonymous functions, so we can even use the generators for iterator functions in class methods which can be great.
2012/7/24 Andrew Faulds ajf@ajf.me:
Much easier to make an iterator with a function than as a class.
2012/7/24 Yahav Gindi Bar g.b.yahav@gmail.com:
I agree, implementing a class only for iterator may be pain sometimes, and functions is much better - especially when 5.3 got the anonymous functions, so we can even use the generators for iterator functions in class methods which can be great.
Ok, why not call it "iterator" or "generator" or "huffpuff" instead of
"function"? It's just the naming, which disturbs me, because a
function is something which is, when called once finished once. I
don't like mathematics, but that is one of the definition of a
function:
http://en.wikipedia.org/wiki/Function_%28mathematics%29
"each input is related to exactly one output"
Couldn't be so complicated to introduce a new name for that, or?
--
Alex Aulbach
2012/7/24 Andrew Faulds ajf@ajf.me:
Much easier to make an iterator with a function than as a class.
2012/7/24 Yahav Gindi Bar g.b.yahav@gmail.com:
I agree, implementing a class only for iterator may be pain sometimes, and functions is much better - especially when 5.3 got the anonymous functions, so we can even use the generators for iterator functions in class methods which can be great.
Ok, why not call it "iterator" or "generator" or "huffpuff" instead of
"function"? It's just the naming, which disturbs me, because a
function is something which is, when called once finished once. I
don't like mathematics, but that is one of the definition of a
function:http://en.wikipedia.org/wiki/Function_%28mathematics%29
"each input is related to exactly one output"Couldn't be so complicated to introduce a new name for that, or?
You'll love LISP, I'm sure, or maybe Python's functional subset.
But PHP functions usually have side-effects, they aren't strict
mathematical functions.
So complaining about this is rather pointless.
--
Andrew Faulds
http://ajf.me/
2012/7/24 Andrew Faulds ajf@ajf.me:
But PHP functions usually have side-effects, they aren't strict mathematical
functions.
Ah, you might mean str_tok()? Are there more, do you have a list?
But we're in PHP-programming-context. You write a function in PHP, you
call it and it will return once called. I see there no exeption.
So complaining about this is rather pointless.
I don't complain about the past. I just think now, that if it doesn't
behave like a function it shouldn't be called function. A function
which returns as an object and is not completed is not a function.
And if other languages do so, my argument will be the same.
<rising finger with epic mimic, fistulous voice> We need not to make
the same mistake again! :)
--
Alex Aulbach
2012/7/24 Andrew Faulds ajf@ajf.me:
But PHP functions usually have side-effects, they aren't strict mathematical
functions.
Ah, you might mean str_tok()? Are there more, do you have a list?But we're in PHP-programming-context. You write a function in PHP, you
call it and it will return once called. I see there no exeption.So complaining about this is rather pointless.
I don't complain about the past. I just think now, that if it doesn't
behave like a function it shouldn't be called function. A function
which returns as an object and is not completed is not a function.And if other languages do so, my argument will be the same.
<rising finger with epic mimic, fistulous voice> We need not to make
the same mistake again! :)
All the array_* functions have side effects. Most class methods, which
are also functions, have side effects. Most of the functions I write
have side effects. Much of mysql_* has side effects.
PHP is not LISP.
--
Andrew Faulds
http://ajf.me/
2012/7/24 Andrew Faulds ajf@ajf.me:
PHP is not LISP.
Hey, I don't want to have LISP. I just want to make complicated things
more clear, and it doesn't matter, if something else is right or wrong
in the past.
It isn't difficult to make a new keyword or something wich disticts it
a little bit more for that.
--
Alex Aulbach
2012/7/24 Andrew Faulds ajf@ajf.me:
But PHP functions usually have side-effects, they aren't strict
mathematical
functions.Ah, you might mean str_tok()? Are there more, do you have a list?
But we're in PHP-programming-context. You write a function in PHP, you
call it and it will return once called. I see there no exeption.So complaining about this is rather pointless.
I don't complain about the past. I just think now, that if it doesn't
behave like a function it shouldn't be called function. A function
which returns as an object and is not completed is not a function.And if other languages do so, my argument will be the same.
<rising finger with epic mimic, fistulous voice> We need not to make
the same mistake again! :)All the array_* functions have side effects. Most class methods, which are
also functions, have side effects. Most of the functions I write have side
effects. Much of mysql_* has side effects.PHP is not LISP.
LISP has side effects.
--
Andrew Faulds
http://ajf.me/--
Trying to solve cultural problems with the programming language rarely
works. I don't think it contributes much to how well a developer will
learn the use of generators with whether we use function or another
keyword.
With that said I believe that's the point of a discussion phase and
I'd like to offer that we're free to implement it how we want.
PHP made implementation mistakes in the past that led to awkward
behavior (like objects passed by value in PHP4), but that's never
stopped things from moving forward and offering up useful features
that users want. I think putting the technical details aside the
engine can aid a developer in distinguishing between spotting
unintended side effects and preventing disastrous consequences. You
have similar issues with developers that try to execute database
queries while there are buffered results or developers that
inadvertently write infinite loops. There are enough safeguards in
place to help avoid such nuances.
2012/7/25 Sherif Ramadan theanomaly.is@gmail.com:
PHP made implementation mistakes in the past that led to awkward
behavior (like objects passed by value in PHP4), but that's never
stopped things from moving forward and offering up useful features
that users want. I think putting the technical details aside the
engine can aid a developer in distinguishing between spotting
unintended side effects and preventing disastrous consequences.
I like that kind of agile programming, too.
But if someone like me says "come on, lets make it a little bit more
easy, because returning objects from functions is some kind of
unconventional; many developers will make mistakes here..." - why not?
They will. I can tell by sure.
Since I begun reading this mailing list I have the impression, that
there are only PHP-programmers like us out there. But the fact is,
that the most PHP-programmers didn't even read the manuals completly.
You may say "Their fault" "Are they programmers, if they don't?", but
this is first a little bit of ignorance because second this is one of
the best features, that PHP has - this "nicely flow", everybody can do
it. I always think of Bob Ross, when I explain PHP.
But it's ok, there are no mistakes, there are just happy little accidents. :)
[means: I will not complain any more]
--
Alex Aulbach
Alex Aulbach wrote:
PHP made implementation mistakes in the past that led to awkward
behavior (like objects passed by value in PHP4), but that's never
stopped things from moving forward and offering up useful features
that users want. I think putting the technical details aside the
engine can aid a developer in distinguishing between spotting
unintended side effects and preventing disastrous consequences.
I like that kind of agile programming, too.But if someone like me says "come on, lets make it a little bit more
easy, because returning objects from functions is some kind of
unconventional; many developers will make mistakes here..." - why not?
They will. I can tell by sure.Since I begun reading this mailing list I have the impression, that
there are only PHP-programmers like us out there. But the fact is,
that the most PHP-programmers didn't even read the manuals completly.
You may say "Their fault" "Are they programmers, if they don't?", but
this is first a little bit of ignorance because second this is one of
the best features, that PHP has - this "nicely flow", everybody can do
it. I always think of Bob Ross, when I explain PHP.
The manual that I read bears no resemblance to the current one, and I still have
to find a manual that ACTUALLY explains how I should write code that it 'strict'
compliant. The bulk of the on-line boilerplates are no longer fit for purpose so
how can we expect newcomers to 'get it right first time'
But it's ok, there are no mistakes, there are just happy little accidents.:)
That covers most of my best software :)
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
I like that kind of agile programming, too.
But if someone like me says "come on, lets make it a little bit more
easy, because returning objects from functions is some kind of
unconventional; many developers will make mistakes here..." - why not?
They will. I can tell by sure.
What are suggesting is going to make this easy that isn't already
covered by the RFC? Lets not get caught up in semantics here. The
current RFC outlines what appears to be inline with other established
implementations. The fact that a function can return an object should
be nothing new to PHP. The fact that an object cause some flow of
control through a construct, also shouldn't be new to PHP.
I don't understand what you find non-conventional about functions or
methods that return objects.
function foo() {
return new bar;
}
$foo = foo();
That's already a common thing in most PHP code I see. PDO::prepare(),
MySQLi::prepare(), DateTime::diff(), also return objects as a result
of calling those methods. I don't think very many PHP developers will
find this concept difficult to grasp if they can already grasp the
aforementioned methods, for example.
Since I begun reading this mailing list I have the impression, that
there are only PHP-programmers like us out there. But the fact is,
that the most PHP-programmers didn't even read the manuals completly.
You may say "Their fault" "Are they programmers, if they don't?", but
this is first a little bit of ignorance because second this is one of
the best features, that PHP has - this "nicely flow", everybody can do
it. I always think of Bob Ross, when I explain PHP.
Yes, there are people who don't read the manual. This is nothing new
or unique to any particular language. Yes, PHP makes it easy for
virtually anybody to use. No, not everything in PHP is easy. No, not
everybody who can use PHP will find it easy to write good code or to
understand all of the language's features at first. What programming
language holds this characteristic? From all of the programming
languages I've learned over the years PHP is still by far at the top
of my list for taking on new features.
Just between PHP 5.2 and 5.4 we've gained traits, closures,
namespaces, function array derefrencing, access to member upon
instantiation, and lots of other lovely additions to the language. I
don't see languages like Java or Python evolving this quickly -- by
contrast.
But it's ok, there are no mistakes, there are just happy little accidents. :)
[means: I will not complain any more]
--
Alex Aulbach
I didn't take any of that as a complaint. I think if you have an
object suggestion (or even subjective one) as to how this can be
easier on the end-user of the language it would be important to bring
it out now. I was unable to ascertain from the prior discussion thus
far.
Sherif Ramadan wrote:
Just between PHP 5.2 and 5.4 we've gained traits, closures,
namespaces, function array derefrencing, access to member upon
instantiation, and lots of other lovely additions to the language. I
don't see languages like Java or Python evolving this quickly -- by
contrast.
But now we also need the people who insisted that these were essential coming up
to the plate and producing good documentation on how they should be used
properly. As yet they are not adding anything to MY existing code base except
hassle.
All these 'extras' may seem 'sexy' to some people, but if there is no pressing
need to use them why would many of us bother? Apart from later having to debug
some third party library that has been 'sexed up' with the latest gismoes and
which is almost unreadable due to the shortcuts it uses.
( I'll start a new thread for my other rant ... )
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
( I'll start a new thread for my other rant ... )
nah, you won't, you will bring that up in every thread instead.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
Just between PHP 5.2 and 5.4 we've gained traits, closures,
namespaces, function array derefrencing, access to member upon
instantiation, and lots of other lovely additions to the language. I
don't see languages like Java or Python evolving this quickly -- by
contrast.But now we also need the people who insisted that these were essential
coming up to the plate and producing good documentation on how they should
be used properly. As yet they are not adding anything to MY existing code
base except hassle.All these 'extras' may seem 'sexy' to some people, but if there is no
pressing need to use them why would many of us bother? Apart from later
having to debug some third party library that has been 'sexed up' with the
latest gismoes and which is almost unreadable due to the shortcuts it uses.( I'll start a new thread for my other rant ... )
I don't see anything about these particular features that isn't
already documented. Albeit there are parts of the documentation that
could always use a bit of refinement every now and then. With that
said, the manual isn't a place to tell people "how" a particular
feature should be used, but how it "can" be used and to what
consequence. The actual use is left up to the developer and we all
know there is more than one way any given developer likes to implement
things in any language.
In an effort not to devolve this thread into something it's not I'd
like to reposition that towards generators.
In order for PHP features to end up getting implemented and committed
into PHP there's a lot of real estate invovled. For one, you have to
have enough developer interest around the feature to begin with. In
the last 24 hours alone there has been significant activity in this
thread (and over 50 responses total in the last few weeks). Two, you
need the have core developers motivated enough to spend the time in
actually writing up the implementation and getting it shipped. That
involves a lot of other intricate work so someone that isn't focused
or motivated enough isn't going to get very far. This also means more
core developers have to jump in if the feature gets into a release
version where maintenance and bug fixes come into play (after all you
can't test everything until you release it into the wild and get
people to discover new edge cases). Three, it has to prove useful
enough that people could not easily achieve the functionality without
language addition. Otherwise it eventually becomes tainted and dies
off (take mysql_* as an example).
All the PHP developers I've spoken with over the past few weeks that
now about the generators RFC are very excited to see it come to PHP.
Especially those developers that have worked with generators in other
languages and know of its usefulness. As for those who don't know
about it yet -- give them a chance. They may like it (of course some
may not). We're not here to discuss it's popularity, but it's
usefulness and feasibility. It's too early to start debating anything
else.
Sherif Ramadan wrote:
I don't see anything about these particular features that isn't
already documented. Albeit there are parts of the documentation that
could always use a bit of refinement every now and then. With that
said, the manual isn't a place to tell people "how" a particular
feature should be used, but how it "can" be used and to what
consequence. The actual use is left up to the developer and we all
know there is more than one way any given developer likes to implement
things in any language.
My only 'complaint' is that while there is a lot of 'documentation' it is all
somewhat fragmented. There is nothing which provides a 'good practice' guide,
and all of the examples returned by google searches nowadays are well behind the
times. Everything is well documented in it's own little niche, but nothing
provides a guide to link the whole into a coherent 'strict compliant' practice?
Generators are scratching another itch, from a base that I never started from.
My CSV scanners have always read in and processed blocks of data. The
fundamental mistake in the rfc is 'getLinesFromFile' not processing each line as
it is loaded. I do a LOT of database data processing which 'generate' results
sets, and the example of 'rewinding a generator' is much better handled by a
function that handles the cursor position on the data set. So I'm still not
seeing anywhere that 'generator' has a pressing application? Perhaps because I
already have library code that scratches the particular itch?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
2012/7/25 Sherif Ramadan theanomaly.is@gmail.com:
I don't understand what you find non-conventional about functions or
methods that return objects.
Again: I don't have any problems with the object returning. :)
I see a problem that the mechanism isn't understood and used wrong.
And I think, that it is too easy to oversee that it is not a "normal"
PHP-function, because the "yield" is normaly in the middle of the code
and "return" at the end.
Both couldn't be changed. But it could help, if you name different
things different. That's just better than nothing. And it's easy. I
suggested that, but the arguments are some kind of ignored.
"No, it's their problem" (of course it is, but it's our job to help
them avoiding this) "No, functions can behave like this, because PHP
is not consistent at all" (of course it is, but this is a completly
new type) "No, we'll do it so, because other languages do it so and we
are used to it" (What an argument is that? Do we want to make a
java-clone?)
Just between PHP 5.2 and 5.4 we've gained traits, closures,
namespaces, function array derefrencing, access to member upon
instantiation, and lots of other lovely additions to the language. I
don't see languages like Java or Python evolving this quickly -- by
contrast.
I don't see this as an compelling advantage. If it is done in the
wrong way, the learning curve could become to steep. I have no problem
with it, I use PHP every day, but as explained most PHP-developers
will have problems and I can say that, because I've more than 20 years
experience in that. Do you have that?
Every new feature should match into context. This one doesn't. I
suggested how to make it a little bit better and I explained why.
I'm just wondering... for whom is PHP developed, for the PHP-internals
or for PHP-developers?
--
Alex Aulbach
I use PHP every day, but as explained most PHP-developers
will have problems and I can say that, because I've more than 20 years
experience in that. Do you have that?
http://en.wikipedia.org/wiki/Appeal_to_authority
I'm just wondering... for whom is PHP developed, for the PHP-internals
or for PHP-developers?
Just wow.
First you say that you are right, because you have more experience in the
topic than the others, then you accuse the "PHP-internals" that they
are favoring their opinion over the rest about the php language development.
I think that argument should either work both ways or none at all.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
2012/7/25 Ferenc Kovacs tyra3l@gmail.com:
more than 20 years
experience in that. Do you have that?
So what? U are using Wikipedia to invalidate me. :) <shrug> Is it so
bad to hear an people with more experience? Do you have problems with
it with authority? :)
So lets make it clear: I say - and I would bet on it - this feature
will cause problems, when implemented like this. Not because of
technical reasons, but because it isn't nicely embedded into PHP.
Normal PHP-programmers will have problems to understand it correctly.
And I'm sure that I'm right, because of my experience. And be warned:
In 90% when I begin to bet, I win. This is also from experience.
First you say that you are right, because you have more experience in the
topic than the others, then you accuse the "PHP-internals" that they are
favoring their opinion over the rest about the php language development.
Name conflict. I meant the PHP-programmers. I call me a PHP-developer,
because I develop programs in PHP. Not a good idea at this list. :)
And yes, I think that there is a more ore less small gap between that,
what the "mass" of anonymous PHP-programmers really needs and that,
what is written in this internals list.
I with you introducing new features like this, but it must be done in
a way that is more self-explaining, has a low learning-curve. Yield
implemented like this dosn't match this criteria.
--
Alex Aulbach
2012/7/25 Ferenc Kovacs tyra3l@gmail.com:
more than 20 years
experience in that. Do you have that?
http://en.wikipedia.org/wiki/Appeal_to_authority
So what? U are using Wikipedia to invalidate me. :) <shrug> Is it so
bad to hear an people with more experience? Do you have problems with
it with authority? :)So lets make it clear: I say - and I would bet on it - this feature
will cause problems, when implemented like this. Not because of
technical reasons, but because it isn't nicely embedded into PHP.
Normal PHP-programmers will have problems to understand it correctly.
And I'm sure that I'm right, because of my experience. And be warned:
In 90% when I begin to bet, I win. This is also from experience.First you say that you are right, because you have more experience in the
topic than the others, then you accuse the "PHP-internals" that they are
favoring their opinion over the rest about the php language development.
Name conflict. I meant the PHP-programmers. I call me a PHP-developer,
because I develop programs in PHP. Not a good idea at this list. :)And yes, I think that there is a more ore less small gap between that,
what the "mass" of anonymous PHP-programmers really needs and that,
what is written in this internals list.
I with you introducing new features like this, but it must be done in
a way that is more self-explaining, has a low learning-curve. Yield
implemented like this dosn't match this criteria.
He linked to the Wikipedia "Appeal to authority" article because it's a
common logical fallacy. Experience alone does not make you any more
right than somebody else, and in the same way, someone without it is not
"less right".
Also, I have 16 years of experience at life, so obviously I'm an expert
at it, right?
I don't see how it means anything.
--
Andrew Faulds
http://ajf.me/
He linked to the Wikipedia "Appeal to authority" article because it's a
common logical fallacy. Experience alone does not make you any more right
than somebody else, and in the same way, someone without it is not "less
right".Also, I have 16 years of experience at life, so obviously I'm an expert at
it, right?I don't see how it means anything.
I'm not arguing that experience doesn't help understanding the issues
related to that experience, what I'm saying is that if someone has more
experience, and he/she is right about his/her statement, then he/she should
have reasons and facts to support his/her opinion and shouldn't use the 'I
have more experience, therefore I'm right' reasoning.
ps: he/she for the honor of
internals@lists.php.net/msg58114.html" rel="nofollow" target="_blank">http://www.mail-archive.com/internals@lists.php.net/msg58114.html
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
On Wed, Jul 25, 2012 at 5:37 PM, Alex Aulbach alex.aulbach@gmail.comwrote:
2012/7/25 Ferenc Kovacs tyra3l@gmail.com:
more than 20 years
experience in that. Do you have that?So what? U are using Wikipedia to invalidate me. :) <shrug> Is it so
bad to hear an people with more experience? Do you have problems with
it with authority? :)
it seems that you missed the point.
oh well.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
On Wed, Jul 25, 2012 at 5:37 PM, Alex Aulbach <alex.aulbach@gmail.com
mailto:alex.aulbach@gmail.com> wrote:2012/7/25 Ferenc Kovacs <tyra3l@gmail.com <mailto:tyra3l@gmail.com>>: >> more than 20 years >> experience in that. Do you have that? > > http://en.wikipedia.org/wiki/Appeal_to_authority So what? U are using Wikipedia to invalidate me. :) <shrug> Is it so bad to hear an people with more experience? Do you have problems with it with authority? :)
it seems that you missed the point.
oh well.--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
I think this quote from that sums this up nicely: " Although certain
classes of argument from authority do on occasion constitute strong
inductive arguments, arguments from authority are commonly used in a
fallacious manner."
Now, let us not argue about this any more :D
--
Andrew Faulds
http://ajf.me/
You could introduce new keyword for generator... even call it "generator" but why (its kind of "design" issue...)? if the syntax that one should use in order to implement the generator is just like a function, but using yield keyword in order to return the items to store?
As long as I know, most programming languages that uses generators wrap it up in a function, so why shall we introduce new keyword that can confuse programmers?
I think using function and returning the value using yield is great... although I'm open to any new nicely-written generator syntax.
2012/7/24 Andrew Faulds ajf@ajf.me:
Much easier to make an iterator with a function than as a class.
2012/7/24 Yahav Gindi Bar g.b.yahav@gmail.com:
I agree, implementing a class only for iterator may be pain sometimes, and functions is much better - especially when 5.3 got the anonymous functions, so we can even use the generators for iterator functions in class methods which can be great.
Ok, why not call it "iterator" or "generator" or "huffpuff" instead of
"function"? It's just the naming, which disturbs me, because a
function is something which is, when called once finished once. I
don't like mathematics, but that is one of the definition of a
function:http://en.wikipedia.org/wiki/Function_%28mathematics%29
"each input is related to exactly one output"Couldn't be so complicated to introduce a new name for that, or?
--
Alex Aulbach
You could introduce new keyword for generator... even call it "generator" but why (its kind of "design" issue...)? if the syntax that one should use in order to implement the generator is just like a function, but using yield keyword in order to return the items to store?
As long as I know, most programming languages that uses generators wrap it up in a function, so why shall we introduce new keyword that can confuse programmers?
I think using function and returning the value using yield is great... although I'm open to any new nicely-written generator syntax.
2012/7/24 Andrew Faulds ajf@ajf.me:
Much easier to make an iterator with a function than as a class.
2012/7/24 Yahav Gindi Bar g.b.yahav@gmail.com:
I agree, implementing a class only for iterator may be pain sometimes, and functions is much better - especially when 5.3 got the anonymous functions, so we can even use the generators for iterator functions in class methods which can be great.
Ok, why not call it "iterator" or "generator" or "huffpuff" instead of
"function"? It's just the naming, which disturbs me, because a
function is something which is, when called once finished once. I
don't like mathematics, but that is one of the definition of a
function:http://en.wikipedia.org/wiki/Function_%28mathematics%29
"each input is related to exactly one output"Couldn't be so complicated to introduce a new name for that, or?
--
Alex Aulbach
And anyway it just depends on your perspective. It's still a function
IMO, it doesn't return, it yields. To me it's kinda like having a
function in another thread that passes several messages back over its
lifetime, and then finally returns.
--
Andrew Faulds
http://ajf.me/
Em Tue, 24 Jul 2012 19:56:46 +0200, Alex Aulbach alex.aulbach@gmail.com
escreveu:
2012/7/24 Andrew Faulds ajf@ajf.me:
Much easier to make an iterator with a function than as a class.
2012/7/24 Yahav Gindi Bar g.b.yahav@gmail.com:
I agree, implementing a class only for iterator may be pain sometimes,
and functions is much better - especially when 5.3 got the anonymous
functions, so we can even use the generators for iterator functions in
class methods which can be great.Ok, why not call it "iterator" or "generator" or "huffpuff" instead of
"function"? It's just the naming, which disturbs me, because a
function is something which is, when called once finished once. I
don't like mathematics, but that is one of the definition of a
function:http://en.wikipedia.org/wiki/Function_%28mathematics%29
"each input is related to exactly one output"
Other have already explained that PHP functions are not strictly
mathematical functions, but generators nevertheless somewhat fit that
description. When you have function foo() { ... yield /* ... */; ... } and
you call foo(), you get the same thing every time: a Generator object. It
so happens that the implementation of that object is inside the body of
the function.
Maybe this helps you reason about the feature.
--
Gustavo Lopes
2012/7/24 Gustavo Lopes glopes@nebm.ist.utl.pt:
When you have function foo() { ... yield /* ... */; ... } and
you call foo(), you get the same thing every time: a Generator object. It so
happens that the implementation of that object is inside the body of the
function.
Hmmm. It's not that I didn't understand it. :)
My thoughts are about usage in practice. Ok, my first argument with
the developer, who overtakes an old project was weak.
What about situations, when developers with different knowlegde work together?
Or when you have programming errors, when you write
function blubb()
{
... yields...
...
... return....
}
(you may only see the "return").
And many those situations are thinkable, because this kind of PHP
function works so totally different from current.
Maybe this helps you reason about the feature.
Please understand me, it's not that I don't like it or that I couldn't
live with it. It's because I have too much experience what could
happen if new programming features are introduced.
For example: Exceptions in PHP are quite old now. And the concept of
exceptions should be known. But I worked together with programmers
wich produced code like
...
try {
$value = method_which_throws_exceptions();
} catch (...) {
return $value;
}
return $value;
...
And he has it done, although I wrote some example code for him how to
use exceptions in this context!!11!
THAT'S the reality.
We can ignore that, but I just want to make such simple mistakes not
so easy and the afford is worth the results.
You can argue: "Those mistakes will always happen". I say "Yes, of
course, but if we have the chance to reduce those mistakes we should
do it."
--
Alex Aulbach
2012/7/24 Gustavo Lopes glopes@nebm.ist.utl.pt:
When you have function foo() { ... yield /* ... */; ... } and
you call foo(), you get the same thing every time: a Generator object. It so
happens that the implementation of that object is inside the body of the
function.
Hmmm. It's not that I didn't understand it. :)My thoughts are about usage in practice. Ok, my first argument with
the developer, who overtakes an old project was weak.
What about situations, when developers with different knowlegde work together?Or when you have programming errors, when you write
function blubb()
{
... yields...
...
... return....
}(you may only see the "return").
And many those situations are thinkable, because this kind of PHP
function works so totally different from current.Maybe this helps you reason about the feature.
Please understand me, it's not that I don't like it or that I couldn't
live with it. It's because I have too much experience what could
happen if new programming features are introduced.For example: Exceptions in PHP are quite old now. And the concept of
exceptions should be known. But I worked together with programmers
wich produced code like...
try {
$value = method_which_throws_exceptions();
} catch (...) {
return $value;
}
return $value;
...And he has it done, although I wrote some example code for him how to
use exceptions in this context!!11!THAT'S the reality.
We can ignore that, but I just want to make such simple mistakes not
so easy and the afford is worth the results.You can argue: "Those mistakes will always happen". I say "Yes, of
course, but if we have the chance to reduce those mistakes we should
do it."
It's fairly obvious from context these aren't ordinary functions, IMO.
And anyway, what could possibly go wrong? Is there any incorrect but
non-fatal or warning-generating way you could use them?
--
Andrew Faulds
http://ajf.me/
Or when you have programming errors, when you write
function blubb()
{
... yields...
...
... return....
}(you may only see the "return").
But that's okay, because PHP does see both, and it tells you "yield may
not be used with return" in a lovely little parser error. Some developers
consider this a useful hint.
-Sara