n00b question: Better Syntax for Coroutines?

I

ig

First off, I'm a python n00b, so feel free to comment on anything if
I'm doing it "the wrong way." I'm building a discrete event simulation
tool. I wanted to use coroutines. However, I want to know if there's
any way to hide a yield statement.

I have a class that I'd like to look like this:

class Pinger(Actor):
def go(self):
success = True
while success:
result = self.ping("128.111.41.38")
if result != "success":
success = False
print "Pinger done"

But because I can't hide yield inside ping, and because I can't find a
convenient way to get a self reference to the coroutine (which is used
by the event queue to pass back results), my code looks like this:

class Pinger(Actor):
def go(self):
# I dislike this next line
self.this_pointer = (yield None)
success = True
while success:
# I want to get rid of the yield in the next line
result = (yield self.ping("128.111.41.38"))
if result != "success":
success = False
print "Pinger done"

I posted a more detailed version of this as a rant here:
http://illusorygoals.com/post/49926627/

I'd like to know, is there a way to get the syntax I want? After
staying up late last night to get a proof-of-concept working with
coroutines, my boss expressed disappointment in the ugliness of the
Pinger code (we agreed on the desired syntax above). I spent almost 2
hours today to migrate the system over to threads. That made my boss
happy, but I'm still curious if I can do something to salvage the
coroutine version.

Regards,
IG
 
A

Aaron \Castironpi\ Brady

First off, I'm a python n00b, so feel free to comment on anything if
I'm doing it "the wrong way." I'm building a discrete event simulation
tool. I wanted to use coroutines. However, I want to know if there's
any way to hide a yield statement.

I have a class that I'd like to look like this:

class Pinger(Actor):
    def go(self):
        success = True
        while success:
            result = self.ping("128.111.41.38")
            if result != "success":
                success = False
        print "Pinger done"

But because I can't hide yield inside ping, and because I can't find a
convenient way to get a self reference to the coroutine (which is used
by the event queue to pass back results), my code looks like this:

class Pinger(Actor):
    def go(self):
        # I dislike this next line
        self.this_pointer = (yield None)
        success = True
        while success:
            # I want to get rid of the yield in the next line
            result = (yield self.ping("128.111.41.38"))
            if result != "success":
                success = False
        print "Pinger done"

I posted a more detailed version of this as a rant here:http://illusorygoals.com/post/49926627/

I'd like to know, is there a way to get the syntax I want? After
staying up late last night to get a proof-of-concept working with
coroutines, my boss expressed disappointment in the ugliness of the
Pinger code (we agreed on the desired syntax above). I spent almost 2
hours today to migrate the system over to threads. That made my boss
happy, but I'm still curious if I can do something to salvage the
coroutine version.

Regards,
IG

I did not read you whole post though I did skim your link. I don't
know your whole problem but it seems you are trying to inform a
generator of its own identity. Here's a solution to that problem;
perhaps it relates to yours. (The shorter retort is, "Just use
closures.")

def gen( ):
def _gen( ):
while 1:
yield 1, 'i am %r'% ob
yield 2, 'i am %r'% ob
yield 3, 'i am %r'% ob
ob= _gen( )
return ob

gens= [ gen( ) for _ in range( 4 ) ]
for i in range( 6 ):
print i
for g in gens:
print g.next( )

/Output (lengthy):

0
(1, 'i am <generator object at 0x009FEC10>')
(1, 'i am <generator object at 0x009FEC38>')
(1, 'i am <generator object at 0x009FEC60>')
(1, 'i am <generator object at 0x009FEC88>')
1
(2, 'i am <generator object at 0x009FEC10>')
(2, 'i am <generator object at 0x009FEC38>')
(2, 'i am <generator object at 0x009FEC60>')
(2, 'i am <generator object at 0x009FEC88>')
2
(3, 'i am <generator object at 0x009FEC10>')
(3, 'i am <generator object at 0x009FEC38>')
(3, 'i am <generator object at 0x009FEC60>')
(3, 'i am <generator object at 0x009FEC88>')
3
(1, 'i am <generator object at 0x009FEC10>')
(1, 'i am <generator object at 0x009FEC38>')
(1, 'i am <generator object at 0x009FEC60>')
(1, 'i am <generator object at 0x009FEC88>')
4
(2, 'i am <generator object at 0x009FEC10>')
(2, 'i am <generator object at 0x009FEC38>')
(2, 'i am <generator object at 0x009FEC60>')
(2, 'i am <generator object at 0x009FEC88>')
5
(3, 'i am <generator object at 0x009FEC10>')
(3, 'i am <generator object at 0x009FEC38>')
(3, 'i am <generator object at 0x009FEC60>')
(3, 'i am <generator object at 0x009FEC88>')
 
C

Carl Banks

First off, I'm a python n00b, so feel free to comment on anything if
I'm doing it "the wrong way." I'm building a discrete event simulation
tool. I wanted to use coroutines. However, I want to know if there's
any way to hide a yield statement.

I have a class that I'd like to look like this:

class Pinger(Actor):
    def go(self):
        success = True
        while success:
            result = self.ping("128.111.41.38")
            if result != "success":
                success = False
        print "Pinger done"

But because I can't hide yield inside ping, and because I can't find a
convenient way to get a self reference to the coroutine (which is used
by the event queue to pass back results), my code looks like this:

class Pinger(Actor):
    def go(self):
        # I dislike this next line
        self.this_pointer = (yield None)
        success = True
        while success:
            # I want to get rid of the yield in the next line
            result = (yield self.ping("128.111.41.38"))
            if result != "success":
                success = False
        print "Pinger done"

I'd like to know, is there a way to get the syntax I want?

I think you're stuck with using threads in a standard Python release.
Generators can't serve as coroutines when you're yielding from a
nested call (they only go one level deep).

You can get coroutines with Stackless Python, a non-standard version
of Python. But even with Stackless I got the impression that you'd be
building coroutines atop something that was fairly thread-like. There
is no coroutine syntax.


Carl Banks
 
A

Arnaud Delobelle

First off, I'm a python n00b, so feel free to comment on anything if
I'm doing it "the wrong way." I'm building a discrete event simulation
tool. I wanted to use coroutines. However, I want to know if there's
any way to hide a yield statement.

I have a class that I'd like to look like this:

class Pinger(Actor):
    def go(self):
        success = True
        while success:
            result = self.ping("128.111.41.38")
            if result != "success":
                success = False
        print "Pinger done"

But because I can't hide yield inside ping, and because I can't find a
convenient way to get a self reference to the coroutine (which is used
by the event queue to pass back results), my code looks like this:

class Pinger(Actor):
    def go(self):
        # I dislike this next line
        self.this_pointer = (yield None)
        success = True
        while success:
            # I want to get rid of the yield in the next line
            result = (yield self.ping("128.111.41.38"))
            if result != "success":
                success = False
        print "Pinger done"

I posted a more detailed version of this as a rant here:http://illusorygoals.com/post/49926627/

I'd like to know, is there a way to get the syntax I want? After
staying up late last night to get a proof-of-concept working with
coroutines, my boss expressed disappointment in the ugliness of the
Pinger code (we agreed on the desired syntax above). I spent almost 2
hours today to migrate the system over to threads. That made my boss
happy, but I'm still curious if I can do something to salvage the
coroutine version.

Regards,
IG

You can't avoid the yield, and generators are not coroutines. A
little while ago when thinking about this kind of problem I defined
"cogenerators", which roughly are to generators what coroutines are to
routines, i.e. they can pass "yielding control" on to another
cogenerator [1].

[1] http://www.marooned.org.uk/~arno/python/cogenerator.html
 
P

Paul McGuire

First off, I'm a python n00b, so feel free to comment on anything if
I'm doing it "the wrong way." I'm building a discrete event simulation
tool. I wanted to use coroutines. However, I want to know if there's

You could "look in the back of the book" - download SimPy and see how
they does this.

-- Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top