Martin Sand Christensen <[EMAIL PROTECTED]> wrote:

> Now to the main point. When a generator function is run, it 
immediately
> returns a generator, and it does not run any code inside the 
generator.
> Not until generator.next() is called is any code inside the generator
> executed, giving it traditional lazy evaluation semantics. Why don't
> generators follow the usual eager evaluation semantics of Python and
> immediately execute up until right before the first yield instead?

You mean you expect the semantics of generators to be that when you 
create them, or every time you call next() they run until they hit yield 
and then (except for the initial run) return the result that was yielded 
the time before? It is easy enough to implement that, but could be a bit 
confusing for the user.

>>> def greedy(fn):
    def greedygenerator(*args, **kw):
        def delayed():
                it = iter(fn(*args, **kw))
                try:
                        res = it.next()
                except StopIteration:
                        yield None
                        return
                yield None
                for value in it:
                        yield res
                        res = value
                yield res
        it = delayed()
        it.next()
        return it
    return greedygenerator

>>> @greedy
def mygen(n):
        for i in range(n):
                print i
                yield i

                
>>> x = mygen(3)
0
>>> list(x)
1
2
[0, 1, 2]
>>> x = mygen(0)
>>> list(x)
[]
>>> 

Now try:

   for command in getCommandsFromUser():
       print "the result of that command was", execute(command)

where getCommandsFromUser is a greedy generator that reads from stdin, 
and see why generators don't work that way.

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to