473,651 Members | 3,068 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Generators versus Coroutines

It seems to me that in python, generators are not truly coroutines. I
do not understand why. What I see is that generators are used almost
exclusively for generation of lists just-in-time. Side effects are
frowned upon. Coroutines, in contrast, are like split functions where
side effects are often as important or more important than return
values. I am currently writing a real time strategy game where I have
visual effects and use generators as coroutines which yield after
processing a single frame of the effect. I can easily make an object
rotate indefinitely with a scant four or five lines of code, all of
which is in one place. So knowing that the difference between a
generator and a coroutine is minor, I come (in a very roundabout way)
to my issue. Why can I use "return" without an expression and it
implicitly returns None but I can't do the same thing with "yield" ?
Jul 18 '05 #1
8 2252
[Timothy Fitz]
It seems to me that in python, generators are not truly coroutines.
Yes, formally speaking Python generators are semi-coroutines.
I do not understand why.
Please read the PEP:

http://www.python.org/peps/pep-0255.html
What I see is that generators are used almost exclusively for
generation of lists just-in-time. Side effects are frowned upon.
Simple uses are naturally most common.
Coroutines, in contrast, are like split functions where
side effects are often as important or more important than return
values. I am currently writing a real time strategy game where I have
visual effects and use generators as coroutines which yield after
processing a single frame of the effect. I can easily make an object
rotate indefinitely with a scant four or five lines of code, all of
which is in one place. So knowing that the difference between a
generator and a coroutine is minor, I come (in a very roundabout way)
to my issue. Why can I use "return" without an expression and it
implicitly returns None
If you explicitly intend to return None as a value, it's terrible
practice to spell that as

return

instead of as

return None

It's equally terrible practice to rely on that "falling off the end"
of a Python function returns None, when you expliclty intend to return
a None value.

Plain "return" is intended to be used in Python only when
*conceptually* no value is being returned, as in "a subroutine" as
opposed to "a function". The language doesn't enforce the latter
distinction, but it's intended all the same.
but I can't do the same thing with "yield" ?


It's the purpose of "yield" to deliver a value. There was no intent
that it be possible to yield without delivering a value. If you want
to deliver the value None, then say

yield None

If you want a concept of yielding without delivering a value, that's
simply not a use case Python's generators intended to address. If you
wish, you can adhere to a *convention* that "yield None" (or "yield
False", or "yield 42", ...) means "I'm not really delivering a value".
Jul 18 '05 #2
Tim Peters <ti********@gma il.com> wrote in message
Coroutines, in contrast, are like split functions where
side effects are often as important or more important than return
values. I am currently writing a real time strategy game where I have
visual effects and use generators as coroutines which yield after
processing a single frame of the effect. I can easily make an object
rotate indefinitely with a scant four or five lines of code, all of
which is in one place. So knowing that the difference between a
generator and a coroutine is minor, I come (in a very roundabout way)
to my issue. Why can I use "return" without an expression and it
implicitly returns None
If you explicitly intend to return None as a value, it's terrible
practice to spell that as

return

instead of as

return None

It's equally terrible practice to rely on that "falling off the end"
of a Python function returns None, when you expliclty intend to return
a None value.


It was not that I want to explicitly return None, I specifically don't
want to return anything, it's just that None happens to be the default
for return so it seems like a convention to adhere to.
If you want a concept of yielding without delivering a value, that's
simply not a use case Python's generators intended to address. If you
wish, you can adhere to a *convention* that "yield None" (or "yield
False", or "yield 42", ...) means "I'm not really delivering a value".


It's not a use case, but why not? And should it be? I know generators
are semi-coroutines, but the fact is that their useage outside of
value generation is just as useful and should be adressed as such. I
do not see how accepting a plain yield would break anything at all.

I have read the PEP, twice, and I don't see why it -wasn't- addressed.
Seems to me to be a fairly large arbitrary decision.
Jul 18 '05 #3
> values. I am currently writing a real time strategy game where I have
I have written a simple 2D-real-time vehicle simulator in Python
(+ graphics library Allegro), using chained generators
which works well enough.

If your game is more ambitious, spend some time designing
a good architecture and specify your components' interfaces.
Then you could generate your code-skeleton from that;
simple generators should be sufficient to implement
your methods which are then driven by your architectures
"execution model".

ciao,
Dominic
Jul 18 '05 #4
[Tim Peters]
If you want a concept of yielding without delivering a value, that's
simply not a use case Python's generators intended to address. If
you wish, you can adhere to a *convention* that "yield None"
(or "yield False", or "yield 42", ...) means "I'm not really delivering a
value".

[Timothy Fitz] It's not a use case, but why not?
In the years generators were discussed before they were implemented,
nobody asked for that.
And should it be?
Not by my lights, no.
I know generators are semi-coroutines, but the fact is that their
useage outside of value generation is just as useful and should be
adressed as such. I do not see how accepting a plain yield would
break anything at all.
The vast majority of generator applications (as you said
before,"generat ors are used almost exclusively for generation of lists
just-in-time", so you already know this) have no use for that; so, for
the vast majority of generator applications, allowing it anyway would
offer nothing of value, but would reduce the quality of compile-time
error-checking.
I have read the PEP, twice, and I don't see why it -wasn't- addressed.
If someone asked for a thing, it got into the PEP. Nobody wanted it.
Seems to me to be a fairly large arbitrary decision.


For general coroutines it would have been. For Simple Generators (the
PEP's title) I think it was the right decision -- "simple" isn't
consistent with piling on gimmicks.

If you want to change it, write a new PEP.
Jul 18 '05 #5
Dominic <no****@nospam. no> wrote in message news:<cf******* ***@news.uni-kl.de>...
values. I am currently writing a real time strategy game where I have

I have written a simple 2D-real-time vehicle simulator in Python
(+ graphics library Allegro), using chained generators
which works well enough.

If your game is more ambitious, spend some time designing
a good architecture and specify your components' interfaces.
Then you could generate your code-skeleton from that;
simple generators should be sufficient to implement
your methods which are then driven by your architectures
"execution model".

ciao,
Dominic


It really was never an issue of "Python can't handle this." it was
more of an issue of "Python should more openly support this." I am
championing generators because they make programming SO much easier in
cases, and people really just don't use them outside if list
generation, which saddens me.
Jul 18 '05 #6
> For general coroutines it would have been. For Simple Generators (the
PEP's title) I think it was the right decision -- "simple" isn't
consistent with piling on gimmicks.

If you want to change it, write a new PEP.


Hmm, I do agree in the context of "Simple Generators" yield implying
None would not make sense and (as shown by the fact that nobody else
seems to care) is a good parse-time error facility.

Is there, then, demand for full on Coroutines? I will live having to
type those extra four letters, or maybe I'll cop out and yield 0 (hah)
but it seems other people are used to coroutines in other languages
(python is my first and only) and there might be demand.

(Also, my first post on Usenet, ever, and in under two hours I get a
respond from someone whose name I recognize on sight... I am
impressed!)
Jul 18 '05 #7
"Timothy Fitz" <fi******@gmail .com> wrote in message
news:97******** *************** ***@posting.goo gle.com...
Dominic <no****@nospam. no> wrote in message

news:<cf******* ***@news.uni-kl.de>...
values. I am currently writing a real time strategy game where I have

I have written a simple 2D-real-time vehicle simulator in Python
(+ graphics library Allegro), using chained generators
which works well enough.

If your game is more ambitious, spend some time designing
a good architecture and specify your components' interfaces.
Then you could generate your code-skeleton from that;
simple generators should be sufficient to implement
your methods which are then driven by your architectures
"execution model".

ciao,
Dominic


It really was never an issue of "Python can't handle this." it was
more of an issue of "Python should more openly support this." I am
championing generators because they make programming SO much easier in
cases, and people really just don't use them outside if list
generation, which saddens me.


Have you looked at SimPy? This is a discrete event simulation package in
pure Python, using generators in simulation objects to implement the
objects' behavior, while managing state, blocking on waits between objects,
etc. I think this may be more in the realm you are thinking, beyond simple
"list generation."

-- Paul

Jul 18 '05 #8
It really was never an issue of "Python can't handle this." it was
more of an issue of "Python should more openly support this." I am
championing generators because they make programming SO much easier in
cases, and people really just don't use them outside if list
generation, which saddens me.

Coroutines are much more powerful than Python's generators and
they can be easily abused to create unstructured
"goto"-like programs thus I assume it would still be a good idea
to put most effort into your architecture and it's
underlying execution model regardless of what you finally
use to keep state: coroutines, threads, (nested) generators.
Try to hide the implementation if you can.

Nesting generators works, but I have to admit
it's (probably) not very elegant.
I would also prefer coroutines for simulation and games as
a module similar to thread/threading.

I think Michael Jackson wrote a converter for COBOL
in the 70s, which would "invert" active entities into
ordinary functions keeping their state in ordinary data structures.
This can certainly be done in Python too.
Maybe this helps.
Ciao,
Dominic
P.S. Many programming languages do not even have
support for "generators ", e.g. Java

Ha! Maybe @decorators are the solution ! ;-)
Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
1909
by: Dave Benjamin | last post by:
Hey all, I was just reflecting upon the old code block debate, and the thought occurred to me that Python really does have a form of code blocks in its implementation of generators. It was a pretty natural conclusion, and I'm not sure why I didn't think of it before. For instance, compare Python's generator-style iteration versus Ruby's codeblock-style iteration: Python: for item in seq:
5
3232
by: Robert Oschler | last post by:
Preamble: - I know this is the Python forum - I know about (and have used) Jython I already posted this question in comp.lang.java. But after a week I have still not received a single reply. One of my favorite Python features is generators. I have to use Java for one particular project (it happens). I would like to have something at
15
2125
by: Jordan Rastrick | last post by:
First, a disclaimer. I am a second year Maths and Computer Science undergraduate, and this is my first time ever on Usenet (I guess I'm part of the http generation). On top of that, I have been using Python for a grand total of about a fortnight now. Hence, I apologise if what follows is a stupid suggestion, or if its already been made somewhere else, or if this is not the appropriate place to make it, etc. But I did honestly do some...
11
3417
by: Deiter | last post by:
State Machines and Coroutines The other thread on goto: Lead me to want to ask... In the spirit of state machines and coroutines, This n00b to C would like to know if setjmp/longjmp are the only way to break out of a routine; leave the function and re-enter the stack state. I ask this because I've only briefly, as yet, reviewed these functions and I believe longjmp will only return a designated int. Therefore I would naively assume...
12
1609
by: Wolfgang Keller | last post by:
Hello, in <dr86uc$8kt$1@wake.carmen.se>, Magnus Lycka <lycka@carmen.se> posts the result of a short test that seems to indicate that resuming a generator takes more time than calling a function. If this is actually also true in the general case, and not due to eventual non-representativeness of the test mentioned above, is it simply due to a less-than-optimum implementation of generators in the current Pyython interpreter and thus...
7
1193
by: Ben Sizer | last post by:
A simple question - can anybody give a short example of how these work and what they are good for? I've read PEP 342 and the associated bit in the What's New section and it's still all Greek to me. The latter seems to focus on how to do it, rather than why you'd do it, so it doesn't aid the understanding too much. -- Ben Sizer
0
965
by: Kay Schluehr | last post by:
While this has been possible before and I guess ( from somewhat superficial reading ) Michael Sparks Kamaelia project is all about this kind of stuff, Python 2.5 generators can be used trivially to turn higher order functions like reduce or map into generators producing streams. After reading a thread here on comp.lang.python initiated by someone who gets nervous about reduce() is going away in Py3K one might just respond that it's not a...
3
1477
by: rocco.rossi | last post by:
I would really like to know more about python 2.5's new generator characteristics that make them more powerful and analogous to coroutines. Is it possible for instance to employ them in situations where I would normally use a thread with a blocking I/O (or socket) operation? If it is, could someone show me how it can be done? There appears to be a very limited amount of documentation in this repect, unfortunately. Thank you.
0
1187
by: Jean-Paul Calderone | last post by:
On Wed, 23 Apr 2008 07:17:46 -0700 (PDT), rocco.rossi@gmail.com wrote: They're not coroutines. The difference between generators in Python 2.4 and in Python 2.5 is that in Python 2.5, `yield´ can be used as part of an expression. If a generator is resumed via its `send´ method, then the `yield´ expression evaluates to the value passed to `send´. You still can't suspend execution through arbitrary stack frames; `yield´ only...
0
8367
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8811
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8703
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8467
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8589
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7302
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6160
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4291
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2703
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.