Re: [PHP-DEV] Adding Generator::throw()
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()
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()
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()
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()
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()
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()
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()
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()
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