473,386 Members | 1,738 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Opposite of yield?


The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?

If this is not implemented now, is there any chance that it's on the
list of things to come?
Al
Jul 18 '05 #1
22 3904
ac*****@easystreet.com writes:
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?

If this is not implemented now, is there any chance that it's on the
list of things to come?


Not much chance. Even Stackless can't do that any more, if I
understand correctly.
Jul 18 '05 #2
ac*****@easystreet.com wrote:
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?


Yep:

generator.next()

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Dead men have no victory.
\__/ Euripides
Jul 18 '05 #3
At 01:40 PM 9/10/2003, ac*****@easystreet.com wrote:

The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?


Sounds like a task for a thread that sleeps a while then checks for the data.

Also reminiscent (a long time ago) someone proposed a COME FROM statement
for FORTRAN to be the inverse of GO TO.

Perhaps a new Python statement "suck"?

Bob Gailer
bg*****@alum.rpi.edu
303 442 2625
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.506 / Virus Database: 303 - Release Date: 8/1/2003

Jul 18 '05 #4
"Bob Gailer" <bg*****@alum.rpi.edu> wrote in message
news:ma*********************************@python.or g...
At 01:40 PM 9/10/2003, ac*****@easystreet.com wrote:
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?


...

Perhaps a new Python statement "suck"?


Oh come on, now, just because Java does it...
Jul 18 '05 #5
ac*****@easystreet.com wrote:

The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?

If this is not implemented now, is there any chance that it's on the
list of things to come?


Queue.Queue.get() ...

-Peter
Jul 18 '05 #6
On Wed, 10 Sep 2003 12:40:37 -0700, rumours say that
ac*****@easystreet.com might have written:
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?
Almost. Use a Queue.Queue() and threads. That is, some other thread(s)
does/do .put() and you wait with a .get().
Without threads, I don't believe there is such a mechanism, not even in
Stackless, as Paul said.
If this is not implemented now, is there any chance that it's on the
list of things to come?


I believe such a chance would be a candidate for dietary products
advertising (that is, slim :).
--
TZOTZIOY, I speak England very best,
Microsoft Security Alert: the Matrix began as open source.
Jul 18 '05 #7
On Wed, 10 Sep 2003 20:19:35 GMT, rumours say that "Dave Benjamin"
<da**@3dex.com> might have written:
Perhaps a new Python statement "suck"?


Oh come on, now, just because Java does it...


QOTW +1 :)
--
TZOTZIOY, I speak England very best,
Microsoft Security Alert: the Matrix began as open source.
Jul 18 '05 #8
Peter Hansen wrote:


Queue.Queue.get() ...


That looks good. But that needs a thread to block, right?
A generator manages to run without being a thread (at least
overtly). If we have the suck() statement, we also need
something that's the opposite of a generator (a Sucker?)
and something that's the opposite of an iterator (a Suckee?).
I'm starting to get an idea why this is completely not all
there.

The main question this raises is "How lightweight are threads?"
Can I program with dozens or hundreds of python threads in a
program (for example under Windows) and not notice that this is
an inefficient or inept coding style?
Al
Jul 18 '05 #9
Erik Max Francis wrote:


Yep:

generator.next()


This style supports only output-driven processes. The generator,
being on the input side, is always the server, and the output
side is always the client. It doesn't fit the situation where the
input is heterogeneous and input has to get spewed in several
directions, depending on its content.
Al
Jul 18 '05 #10
ac*****@easystreet.com wrote:

Peter Hansen wrote:


Queue.Queue.get() ...

That looks good. But that needs a thread to block, right?


Yep.
A generator manages to run without being a thread (at least
overtly). If we have the suck() statement, we also need
something that's the opposite of a generator (a Sucker?)
and something that's the opposite of an iterator (a Suckee?).
I'm starting to get an idea why this is completely not all
there.

The main question this raises is "How lightweight are threads?"
Can I program with dozens or hundreds of python threads in a
program (for example under Windows) and not notice that this is
an inefficient or inept coding style?


The real question might be why would you want to?

If you don't want a thread, but you want something which takes
input from elsewhere and does some processing, then returns
control to some other place until more data is available (which
is what one might assume if threads aren't good for you), there
is already a convenient solution: the subroutine. ;-)

Seriously, what's the requirement driving the need for this?
(I suspect Erik Max's answer is still what you need, and you
misunderstand the nature of what he was suggesting, but if you'll
explain the specific case you have in mind we'll know for sure.)

-Peter
Jul 18 '05 #11
ac*****@easystreet.com wrote in news:3F***************@easystreet.com:
Peter Hansen wrote:


Queue.Queue.get() ...

That looks good. But that needs a thread to block, right?


yes
A generator manages to run without being a thread (at least
overtly). If we have the suck() statement, we also need
something that's the opposite of a generator (a Sucker?)
and something that's the opposite of an iterator (a Suckee?).
I'm starting to get an idea why this is completely not all
there.
basicaly you poll every generator (or more precicly "iterable" as that is
what a generator returns), one after the other... enjoy the link below.
The main question this raises is "How lightweight are threads?"
Can I program with dozens or hundreds of python threads in a
program (for example under Windows) and not notice that this is
an inefficient or inept coding style?


this one is for you :-)
http://www-106.ibm.com/developerwork.../l-pythrd.html

you wont get happy with hundrets of native threads, but with the light ones
from above you can have thousands...

generaly you will find interesting stuff here (one line):
http://www-
106.ibm.com/developerworks/views/linux/articles.jsp?sort_order=desc&expand=
&sort_by=Date&show_abstract=true&view_by=Search&se arch_by=charming+python%3
A

chris
--
Chris <cl******@gmx.net>

Jul 18 '05 #12
On Wed, 10 Sep 2003 14:39:14 -0700, ac*****@easystreet.com wrote:
Erik Max Francis wrote:


Yep:

generator.next()


This style supports only output-driven processes. The generator,
being on the input side, is always the server, and the output
side is always the client. It doesn't fit the situation where the
input is heterogeneous and input has to get spewed in several
directions, depending on its content.

Could you make some fantasy-code to illustrate what you mean?

Regards,
Bengt Richter
Jul 18 '05 #13
On Wed, 10 Sep 2003 17:39:14 -0400, achrist wrote:
Erik Max Francis wrote:

Yep:

generator.next()

This style supports only output-driven processes. The generator, being
on the input side, is always the server, and the output side is always
the client. It doesn't fit the situation where the input is
heterogeneous and input has to get spewed in several directions,
depending on its content.


It does if you add a dispatcher framework. There is a python project for
just such a framework, but I can't remember the name. The idea is dirt
simple, but the implementation gets knarly with exceptions and such.

Found it - Charming Python 
http://www-106.ibm.com/developerwork.../l-pythrd.html
Jul 18 '05 #14
ac*****@easystreet.com wrote:
This style supports only output-driven processes. The generator,
being on the input side, is always the server, and the output
side is always the client. It doesn't fit the situation where the
input is heterogeneous and input has to get spewed in several
directions, depending on its content.


The distinction you're making is push vs. pull processing. To get what
you want, you should use some sort of asynchronous mechanism with
synchronization when data is transferred. Threading with the use of the
Queue module comes to mind immediately. Other forms of asynchronous
processing are certainly possible, as well.

That being said, calling the next method of a generator _is_ the obvious
inverse process of a generator yielding a value.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Forever we / Infinitely
\__/ Sandra St. Victor
Jul 18 '05 #15
Peter Hansen wrote:

The real question might be why would you want to?

If you don't want a thread, but you want something which takes
input from elsewhere and does some processing, then returns
control to some other place until more data is available (which
is what one might assume if threads aren't good for you), there
is already a convenient solution: the subroutine. ;-)

Seriously, what's the requirement driving the need for this?
(I suspect Erik Max's answer is still what you need, and you
misunderstand the nature of what he was suggesting, but if you'll
explain the specific case you have in mind we'll know for sure.)


No, I didn't say that I didn't want a thread. If there are no
serious drawbacks to relying heavily on threads, I'd be glad to
use them. This would be deluxe.

There really isn't any need for a generator, but it is a very
nice way to construct the input side of a program (the caller
doesn't have to worry about expicitly calling initialization and
finalization). Some kind of through-the-looking-glass version
of a generator would be a very nice way to construct the output
side.

I decided to test threads to see what happens:

-------------Warning, Code Follows---------------------

import Queue
import thread
import time

queues = [Queue.Queue()]
threads = []

appendLock = thread.allocate_lock()

def TransferData(queues, atPos):
while len(queues) < atPos + 1:
pass
inputQueue = queues[atPos]
outputQueue = Queue.Queue()
appendLock.acquire()
queues.append(outputQueue)
appendLock.release()
while 1:
data = inputQueue.get(True)
outputQueue.put(data, True)

startTime = time.time()
for i in range(1000):
print i,
threads.append(thread.start_new_thread(TransferDat a, (queues, i)))
queues[0].put(i, True)
appendLock.acquire()
print queues[-1].get(True)
appendLock.release()

print time.time() - startTime
--------------Warning Discussion Follows -------------------------

Running this on my Windows NT 200 NHz machine gave decent results.
With 1000 threads and 1000 Queues, memory used was 24MB. Python
takes almost 10 MB to start, so the overhead per thread + Queue
is only a little over 10 kb. Passing all the messages through
the chain took 2.5 minutes, so we are down around a quarter millisec
for each put or get.

That should be pretty good for many uses.
Al
Jul 18 '05 #16
ac*****@easystreet.com wrote:

Peter Hansen wrote:


Queue.Queue.get() ...


That looks good. But that needs a thread to block, right?
A generator manages to run without being a thread (at least
overtly). If we have the suck() statement, we also need
something that's the opposite of a generator (a Sucker?)
and something that's the opposite of an iterator (a Suckee?).
I'm starting to get an idea why this is completely not all
there.

The main question this raises is "How lightweight are threads?"
Can I program with dozens or hundreds of python threads in a
program (for example under Windows) and not notice that this is
an inefficient or inept coding style?

Al


You may want to check out how such things are done with my MyHDL
package. The target application is hardware design, but the idea
is more probably general.

http://jandecaluwe.com/Tools/MyHDL/m...model-obj.html

Jan

--
Jan Decaluwe - Resources bvba - http://jandecaluwe.com
Losbergenlaan 16, B-3010 Leuven, Belgium
Bored with EDA the way it is? Check this:
http://jandecaluwe.com/Tools/MyHDL/Overview.html
Jul 18 '05 #17
On Wed, Sep 10, 2003 at 12:40:37PM -0700, ac*****@easystreet.com wrote:
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?


Here is a way of converting a generator function into a consumer using
a single item list as a mailbox:

from __future__ import generators

def consumer():
print "This code runs before any data is fed to the consumer"
mailbox = []; yield mailbox
while mailbox:
print "Here's what I got:", mailbox.pop()
yield mailbox
print "This code runs after end of data is signalled"

# How to feed a consumer:

i = 0
for mailbox in consumer():
if i < 5:
mailbox.append(i) # feed next item
i += 1
Output:
This code runs before any data is fed to the consumer
Here's what I got: 0
Here's what I got: 1
Here's what I got: 2
Here's what I got: 3
Here's what I got: 4
This code runs after end of data is signalled
For a more comprehensive solution try Christian Tismer's Stackless Python.

Oren

Jul 18 '05 #18
On Wed, 10 Sep 2003 12:40:37 -0700, ac*****@easystreet.com wrote:

The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?

If this is not implemented now, is there any chance that it's on the
list of things to come?


You can use a generator as the body of a function. That is, the generator is
only ever accessed through the function, and the function and the generator have
some agreed on way to pass parameters. I.e.:

def getline(output):
'''getline accumulates text until it has a complete line (signaled
by either a newline (\\n) or a null (\\0)). It then passes the
line (without trailing \n) to output'''

genargs = [None]
def callgen(text):
genargs[0] = text
return gennext()
def gen():
line = ''
while True:
text, = genargs
if text:
lines = text.splitlines(True)
if line:
lines[0] = line+lines[0]
for line in lines[:-1]:
output(line[:-1])
line = lines[-1]
if line[-1] in '\n\0':
if line[-1] == '\n':
line = line[:-1]
output(line)
line = ''
yield None
gennext = gen().next
return callgen

def printer(text):
print text

lineprinter = getline(printer)

lineprinter('hello') #nothing output
lineprinter(' world\n') #prints 'hello world'
---
Greg Chapman

Jul 18 '05 #19
ac*****@easystreet.com wrote in message news:<3F***************@easystreet.com>...
The yield statement looks to be a big step toward some kind of
lightweight concurrency-oriented programming in python. Is there
any similarly nice way to do the opposite of yield, just sit around
(perhaps in the middle of a loop) and wait until some other routine
(unknown to the waiting module) hurls a value in?


This sounds like event-driven programming to me.

(1) Usage of threads in principle is optional, but at Python level
event-driven programming is probably always done in multi-threaded
environment.

(2) Also, at software level, interruptions are always emulated by
polling (i.e. event loop.) You will have a loop somewhere.

(3) I won't get into details of the event-handler implementation, as
it is well-known and you probably already know it or can find it
easily. But I'd like to mention a simple implementation using
exception handling. For instance:

while 1:
try:
poll_keyboard()
poll_mouse()
poll_microphone()
poll_temperature_sensor()
except IncomingSignal, e:
... handle event ...

You raise the IncomingSignal event inside the various polling
routines.

regards,

Hung Jung Lu
Jul 18 '05 #20
>>>>> "Hung" == Hung Jung Lu <hu********@yahoo.com> writes:

Hung> This sounds like event-driven programming to me.

Hung> (1) Usage of threads in principle is optional, but at Python level
Hung> event-driven programming is probably always done in multi-threaded
Hung> environment.

That does not stop somebody who wants something cheaper than threads when he
know that at most one place of his program needs being serviced at each
time.

Hung> (2) Also, at software level, interruptions are always emulated by
Hung> polling (i.e. event loop.) You will have a loop somewhere.

At "software level", most event loops are waited by calling the OS. The OS
can deal with the hardware interrupts caused by devices or timers, or the
signalling caused by other processes. In these ways the OS will not need to
do polling most of the time.

Hung> (3) I won't get into details of the event-handler implementation,
Hung> as it is well-known and you probably already know it or can find
Hung> it easily. But I'd like to mention a simple implementation using
Hung> exception handling. For instance:

Hung> while 1: try: poll_keyboard() poll_mouse() poll_microphone()
Hung> poll_temperature_sensor() except IncomingSignal, e: ... handle
Hung> event ...

Hung> You raise the IncomingSignal event inside the various polling
Hung> routines.

Never do that! You have a lot of ways to avoid holding up the CPU without
doing anything real. No event loop in real systems acts like that, except
for embedded systems that has exactly one program loaded into the memory at
the same time. Instead, use something like select.poll() to wait from more
than one source of input/output, or use a thread as suggested by the parent
thread.

Regards,
Isaac.
Jul 18 '05 #21
Isaac To <kk**@csis.hku.hk> wrote in message
At "software level", most event loops are waited by calling the OS. The OS
can deal with the hardware interrupts caused by devices or timers, or the
signalling caused by other processes. In these ways the OS will not need to
do polling most of the time.
OSes do polling most of the time: on their idle event loop. Yes,
"idle" is considered an event, too.

Also, events are not restricted to hardware inputs. Users can generate
their own events. Like in the original poster's example: once he
computes a result, he may want to generate an event, and let the
program handle the generated result through an event handler.
Never do that! You have a lot of ways to avoid holding up the CPU without
doing anything real. No event loop in real systems acts like that, except
for embedded systems that has exactly one program loaded into the memory at
the same time. Instead, use something like select.poll() to wait from more
than one source of input/output, or use a thread as suggested by the parent
thread.


Take it easy. :) It's just a sample code that shows some fun usage of
exception handling in Python. What the original poster asked was
"opposite of yield", and I only wanted to point out that what he
wanted was probably just "event-driven programming", which I was
surprised that no one has mentioned, at all.

My example is just a typical dirty trick of execution flow control in
Python via the exception handling. It's a well-known trick.

I did not mention the details of typical event-driven programming
implementation, because it's known by most programmers. No need for me
to show it here.

regards,

Hung Jung
Jul 18 '05 #22
Bob Gailer <bg*****@alum.rpi.edu> writes:
Also reminiscent (a long time ago) someone proposed a COME FROM
statement for FORTRAN to be the inverse of GO TO.


http://c2.com/cgi/wiki?ComeFrom
Jul 18 '05 #23

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

Similar topics

2
by: yyhhjj | last post by:
I created a test program to implement an iterator. First, I used 'yield break' in the iterator, it worked normally. Then, I simply used 'break' in the places of 'yield break', it still worked...
2
by: IntraRELY | last post by:
I know this isnt really a VB question per say, but is what I am developing in VB.NET and Excel is the only place that has provided direction. I wanted to ask the public if perhaps you could lend me...
3
by: andy.leszczynski | last post by:
Hi, I might understand why this does not work, but I am not convinced it should not - following: def nnn(): print 'inside' yield 1 def nn():
22
by: Mateuszk87 | last post by:
Hi. may someone explain "yield" function, please. how does it actually work and when do you use it? thanks in forward mateusz
3
by: Ehsan | last post by:
hi coulde any one show me the usage of "yield" keyword specially in this example: """Fibonacci sequences using generators This program is part of "Dive Into Python", a free Python book for...
1
by: castironpi | last post by:
What if I say oath= yield or other= yield ?
13
by: Martin Sand Christensen | last post by:
Hi! First a bit of context. Yesterday I spent a lot of time debugging the following method in a rather slim database abstraction layer we've developed: ,---- | def selectColumn(self,...
7
by: Alex Bryan | last post by:
Okay, so i don't really understand the Yield thing and i know it is useful. I've read a few things about it but it is all programming jargon and so basically it is hard for me to understand. So can...
5
by: defn noob | last post by:
def letters(): a = xrange(ord('a'), ord('z')+1) B = xrange(ord('A'), ord('Z')+1) while True: yield chr(a) yield chr(B) Traceback (most recent call last):
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...

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.