Re: [PHP-DEV] Adding Generator::throw()

2012-12-25 Thread Stas Malyshev
Hi!

> I've been hearing this argument from time to time and I don't understand
> it; aren't exceptions created with the sole purpose of (error) flow control?

No. Exceptions are meant for something that "should never happen". I.e.,
if your application reads its config files and they are not there, or
connects to the database and database is not there - that's an
exception. If you just have something like "user clicked this button and
not that button" - it should not be an exception. Thus, exceptions
should be used to handle cases which are not part of the normal program
flow control.

That said, it does not look like in this case (generators) it is being
used wrongly, my initial impression was based on the lack of
information, and turns out to be wrong.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

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



Re: [PHP-DEV] Adding Generator::throw()

2012-12-24 Thread Anthony Ferrara
Tjerk,

I've been hearing this argument from time to time and I don't understand
> it; aren't exceptions created with the sole purpose of (error) flow
> control?
>
> If so, then how can "exceptions for flow control" and "very bad idea" be
> mentioned in the same sentence unless there are particular bad use cases
> that are implicitly referred to when saying this?
>
> If not, then perhaps my understanding of exceptions needs a spring cleaning
> :)


Correct, Exceptions aren't supposed to be used for flow control.

However, this isn't about flow control. This is about throwing the
exception in the proper context. With generators and coroutines, the code
that throws the exception may not actually be a child of the code that
called it (from the stack's perspective). Therefore, adding
Generator::throw() simply allows for throwing the exception in the proper
stack frame (the framew that called the original code).

For an example of how this would be useful, read this *awesome* post about
coroutines:
http://nikic.github.com/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html

Anthony


Re: [PHP-DEV] Adding Generator::throw()

2012-12-23 Thread Tjerk Anne Meesters
Hi,

On Tue, Dec 18, 2012 at 6:03 AM, Stas Malyshev wrote:

> Hi!
>
> > Basically the method allows you to do delegate error handling to the
> > coroutine, rather than doing it yourself (as you are not always able to
> do
> > it). It is particularly useful in more complicated settings, e.g. if you
> > are doing task scheduling through coroutines. For a small sample of how
>
> Could you expand on this point a bit more? It sounds like using
> exceptions for flow control, which is usually a very bad idea.
>

I've been hearing this argument from time to time and I don't understand
it; aren't exceptions created with the sole purpose of (error) flow control?

If so, then how can "exceptions for flow control" and "very bad idea" be
mentioned in the same sentence unless there are particular bad use cases
that are implicitly referred to when saying this?

If not, then perhaps my understanding of exceptions needs a spring cleaning
:)


>
> > this looks like see http://taskjs.org/. What the ->throw() method would
> do
> > in these examples is that it allows to check for errors by try/catching
> the
> > yield statement (rather than going for some odd solution with error
> > callbacks).
>
> Could you point to some specific example?
>
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
--
Tjerk


Re: [PHP-DEV] Adding Generator::throw()

2012-12-23 Thread Nikita Popov
On Fri, Dec 21, 2012 at 11:09 PM, Christopher Jones <
christopher.jo...@oracle.com> wrote:

>
>
> On 12/21/2012 06:54 AM, Nikita Popov wrote:
>
>> If there are no further objections I'll commit this tomorrow.
>>
>> Nikita
>>
>
> This feature needs documenting in Generator RFC before it is committed.
>
> The RFC will be referenced by people new to the feature and so it
> should have a complete list of changes.
>
> Thanks,
>
> Chris
>

Committed in
https://github.com/php/php-src/commit/be7b0bc3ec02e4f223920ee6397f9c4993eb7df5
.

I also adjusted the RFC to list this :)

Nikita


Re: [PHP-DEV] Adding Generator::throw()

2012-12-21 Thread Christopher Jones



On 12/21/2012 06:54 AM, Nikita Popov wrote:

If there are no further objections I'll commit this tomorrow.

Nikita


This feature needs documenting in Generator RFC before it is committed.

The RFC will be referenced by people new to the feature and so it
should have a complete list of changes.

Thanks,

Chris

--
christopher.jo...@oracle.com  http://twitter.com/ghrd

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



Re: [PHP-DEV] Adding Generator::throw()

2012-12-21 Thread Nikita Popov
On Mon, Dec 17, 2012 at 11:45 PM, Nikita Popov  wrote:

> On Mon, Dec 17, 2012 at 11:03 PM, Stas Malyshev wrote:
>
>> Hi!
>>
>> > Basically the method allows you to do delegate error handling to the
>> > coroutine, rather than doing it yourself (as you are not always able to
>> do
>> > it). It is particularly useful in more complicated settings, e.g. if you
>> > are doing task scheduling through coroutines. For a small sample of how
>>
>> Could you expand on this point a bit more? It sounds like using
>> exceptions for flow control, which is usually a very bad idea.
>>
>> > this looks like see http://taskjs.org/. What the ->throw() method
>> would do
>> > in these examples is that it allows to check for errors by try/catching
>> the
>> > yield statement (rather than going for some odd solution with error
>> > callbacks).
>>
>> Could you point to some specific example?
>>
> The basic idea behind this kind of task management is that you can do
> asynchronous operations just like you would synchronous ones, i.e. without
> the need for callbacks or wait-loops. Whenever the functions wants to
> perform some async action it doesn't directly do it, rather it yields the
> operation that does it. The scheduler then waits until that operation is
> finished (running other tasks in the meantime) and only resumes the
> coroutine once it is finished. This way you can write async code without
> the ugliness that is usually involved with async code.
>
> Here is an example to get a rough idea of how the use looks like:
>
> function server() {
> // ...
> $stuff = yield $socket->recv();
> // ...
> yield $socket->send($response);
> // ...
> }
>
> The throw() method comes in when you want to handle errors on those
> asynchronous operations. Without it you would be forced to use error codes.
> throw() allows you to do the error handling just like you would normally
> do. E.g. consider that $socket->send() were a fallible operation. Then you
> could catch errors like this:
>
> function server() {
> // ...
> try {
> yield $socket->send($response);
> } catch (SocketException $e) {
> // do some error handling
> }
> // ...
> }
>
> In this case the outside code (where the exception comes from) can't know
> what it should do in case of an error. Only the code in the coroutine knows
> that. That's why you need some possibility to throw the error into the
> context that knows how to deal with it.
>
> I hope that this makes it a bit more clear.
>
> Nikita
>

If there are no further objections I'll commit this tomorrow.

Nikita


Re: [PHP-DEV] Adding Generator::throw()

2012-12-17 Thread Nikita Popov
On Mon, Dec 17, 2012 at 11:03 PM, Stas Malyshev wrote:

> Hi!
>
> > Basically the method allows you to do delegate error handling to the
> > coroutine, rather than doing it yourself (as you are not always able to
> do
> > it). It is particularly useful in more complicated settings, e.g. if you
> > are doing task scheduling through coroutines. For a small sample of how
>
> Could you expand on this point a bit more? It sounds like using
> exceptions for flow control, which is usually a very bad idea.
>
> > this looks like see http://taskjs.org/. What the ->throw() method would
> do
> > in these examples is that it allows to check for errors by try/catching
> the
> > yield statement (rather than going for some odd solution with error
> > callbacks).
>
> Could you point to some specific example?
>
The basic idea behind this kind of task management is that you can do
asynchronous operations just like you would synchronous ones, i.e. without
the need for callbacks or wait-loops. Whenever the functions wants to
perform some async action it doesn't directly do it, rather it yields the
operation that does it. The scheduler then waits until that operation is
finished (running other tasks in the meantime) and only resumes the
coroutine once it is finished. This way you can write async code without
the ugliness that is usually involved with async code.

Here is an example to get a rough idea of how the use looks like:

function server() {
// ...
$stuff = yield $socket->recv();
// ...
yield $socket->send($response);
// ...
}

The throw() method comes in when you want to handle errors on those
asynchronous operations. Without it you would be forced to use error codes.
throw() allows you to do the error handling just like you would normally
do. E.g. consider that $socket->send() were a fallible operation. Then you
could catch errors like this:

function server() {
// ...
try {
yield $socket->send($response);
} catch (SocketException $e) {
// do some error handling
}
// ...
}

In this case the outside code (where the exception comes from) can't know
what it should do in case of an error. Only the code in the coroutine knows
that. That's why you need some possibility to throw the error into the
context that knows how to deal with it.

I hope that this makes it a bit more clear.

Nikita


Re: [PHP-DEV] Adding Generator::throw()

2012-12-17 Thread Stas Malyshev
Hi!

> Basically the method allows you to do delegate error handling to the
> coroutine, rather than doing it yourself (as you are not always able to do
> it). It is particularly useful in more complicated settings, e.g. if you
> are doing task scheduling through coroutines. For a small sample of how

Could you expand on this point a bit more? It sounds like using
exceptions for flow control, which is usually a very bad idea.

> this looks like see http://taskjs.org/. What the ->throw() method would do
> in these examples is that it allows to check for errors by try/catching the
> yield statement (rather than going for some odd solution with error
> callbacks).

Could you point to some specific example?

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

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



[PHP-DEV] Adding Generator::throw()

2012-12-17 Thread Nikita Popov
Hey internals!

I would like to add a ->throw() method to generator objects and as this
wasn't part of the proposal that was voted on I'd like to ask back first.

The Generator::throw(Exception $exception) method takes an exception and
throws it at the current interruption point in the generator. It basically
behaves as if you replaced the current yield statement with a throw
statement and resumed the generator.

This method is also part of Python's generator implementation (as well as
ECMAScript's). I decided not to implement it at first, because I wasn't
convinced of its usefulness. But after some further consideration adding it
seems to make more sense.

Basically the method allows you to do delegate error handling to the
coroutine, rather than doing it yourself (as you are not always able to do
it). It is particularly useful in more complicated settings, e.g. if you
are doing task scheduling through coroutines. For a small sample of how
this looks like see http://taskjs.org/. What the ->throw() method would do
in these examples is that it allows to check for errors by try/catching the
yield statement (rather than going for some odd solution with error
callbacks).

Here is a patch that would add this functionality:
https://github.com/nikic/php-src/commit/b16e29fea6cba576d4176524bf43d6e7d00f45fa

Anyone against adding this?
Nikita