generators improvement

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Oleg Leschov

    generators improvement


    Here is a simple idea to make generators more useful for some applications,
    although I won't for now name them..
    anyways, advantage of current generators was not too obvious for all the
    people, too.

    So, currently the interface between generator and it's user program is rather
    poor, because it only consists of a signal from a user routine, and a kind
    of only one directional data passage - from the generator.
    This seems unsymmetric to me, and thus incomplete..
    What I think should increase the potential usefulness of a generators,
    is bi-directional data passage. This is very easy to implement, IMHO.

    What needs to be done is to allow yield return something - whatever was
    passed to the .next() thing from caller..
    Easy and obvious, isn't it? So is there any principal problem with this
    idea that would prevents its implementation?

    I understand that this can be achieved by using some
    global, for instance, but hey, I used to implement generator's functionality
    without using them, too - just make a class and make
    algorithm look horrible. The same thing, but much wordier and uglier
    looking... and that does not mean that generators are redundant.



  • Duncan Booth

    #2
    Re: generators improvement

    Oleg Leschov <kalmas@udm.r u> wrote in
    news:bhtiij$psc $2@ocasysi.rubb ernet.net:
    [color=blue]
    > What needs to be done is to allow yield return something - whatever was
    > passed to the .next() thing from caller..
    > Easy and obvious, isn't it? So is there any principal problem with this
    > idea that would prevents its implementation?[/color]

    Please read PEP 288, http://www.python.org/peps/pep-0288.html
    in particular the section:
    [color=blue]
    > Rejected Alternative
    > One idea for passing data into a generator was to pass an argument
    > through next() and make a assignment using the yield keyword:
    >
    > datain = yield dataout
    > . . .
    > dataout = gen.next(datain )
    >
    > The intractable problem is that the argument to the first next() call
    > has to be thrown away, because it doesn't correspond to a yield
    > keyword.[/color]




    --
    Duncan Booth duncan@rcp.co.u k
    int month(char *p){return(1248 64/((p[0]+p[1]-p[2]&0x1f)+1)%12 )["\5\x8\3"
    "\6\7\xb\1\x9\x a\2\0\4"];} // Who said my code was obscure?

    Comment

    • Oleg Leschov

      #3
      Re: generators improvement


      Oleg Leschov:
      <skip>[color=blue]
      > that either wouldn't take any arguments or will pass them as generator
      > function's parameters (which are not allowed at all now, anyway).[/color]

      Sorry, that was my wrong statement. Of cause these parameters are passed during
      creation of generator object.
      Still, this does not neglect other variant.

      <skip>

      Comment

      • John Roth

        #4
        Re: generators improvement


        "Duncan Booth" <duncan@NOSPAMr cp.co.uk> wrote in message
        news:Xns93DC5C1 AFAB9Eduncanrcp couk@127.0.0.1. ..[color=blue]
        > Oleg Leschov <kalmas@udm.r u> wrote in
        > news:bhtiij$psc $2@ocasysi.rubb ernet.net:
        >[color=green]
        > > What needs to be done is to allow yield return something - whatever was
        > > passed to the .next() thing from caller..
        > > Easy and obvious, isn't it? So is there any principal problem with this
        > > idea that would prevents its implementation?[/color]
        >
        > Please read PEP 288, http://www.python.org/peps/pep-0288.html
        > in particular the section:
        >[color=green]
        > > Rejected Alternative
        > > One idea for passing data into a generator was to pass an argument
        > > through next() and make a assignment using the yield keyword:
        > >
        > > datain = yield dataout
        > > . . .
        > > dataout = gen.next(datain )
        > >
        > > The intractable problem is that the argument to the first next()[/color][/color]
        call[color=blue][color=green]
        > > has to be thrown away, because it doesn't correspond to a yield
        > > keyword.[/color][/color]

        "I can't figure out how to do it so that it satisfies my sense of esthetics"
        is not the same as "this problem doesn't need to be solved."

        John Roth[color=blue]
        >
        >
        >
        >
        > --
        > Duncan Booth duncan@rcp.co.u k
        > int month(char *p){return(1248 64/((p[0]+p[1]-p[2]&0x1f)+1)%12 )["\5\x8\3"
        > "\6\7\xb\1\x9\x a\2\0\4"];} // Who said my code was obscure?[/color]


        Comment

        • Andrew Dalke

          #5
          Re: generators improvement

          Oleg Leschov:[color=blue]
          > What I think should increase the potential usefulness of a generators,
          > is bi-directional data passage. This is very easy to implement, IMHO.
          >
          > What needs to be done is to allow yield return something - whatever was
          > passed to the .next() thing from caller..[/color]
          ...[color=blue]
          > I understand that this can be achieved by using some
          > global, for instance, but hey, I used to implement generator's[/color]
          functionality[color=blue]
          > without using them, too - just make a class and make
          > algorithm look horrible. The same thing, but much wordier and uglier
          > looking... and that does not mean that generators are redundant.[/color]

          While somewhat cumbersome, you could do (mind the bad
          cut&paste - OE Express didn't like the tabs PythonWin sent over)

          class State:
          def __init__(self):
          self.args = None
          self.kwargs = None

          class OlegYield:
          def __init__(self, f):
          self.f = f
          def __call__(self, *args, **kwargs):
          state = State()
          args = (state,) + args
          return OlegIter(state, f(*args, **kwargs))

          class OlegIter:
          def __init__(self, state, iter):
          self.state = state
          self.iter = iter
          def __iter__(self):
          return self
          def next(self, *args, **kwargs):
          self.state.args = args
          self.state.kwar gs = kwargs
          return self.iter.next( )
          [color=blue][color=green][color=darkred]
          >>> def f(state, n):[/color][/color][/color]
          .... for i in range(n):
          .... yield i
          .... print state.args, state.kwargs
          ....[color=blue][color=green][color=darkred]
          >>> g = OlegYield(f)
          >>> a = g(5)
          >>> a.next()[/color][/color][/color]
          0[color=blue][color=green][color=darkred]
          >>> a.next(6, a=7)[/color][/color][/color]
          (6,) {'a': 7}
          1[color=blue][color=green][color=darkred]
          >>> list(g(4))[/color][/color][/color]
          () {}
          () {}
          () {}
          () {}
          [0, 1, 2, 3][color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          Andrew
          dalke@dalkescie ntific.com


          Comment

          Working...