On Sun, Mar 22, 2009 at 9:18 PM, Anoop Saldanha <[email protected]>wrote:
> > > 2009/3/21 Lisandro Dalcin <[email protected]> > > On Sat, Mar 21, 2009 at 9:24 AM, Stefan Behnel <[email protected]> >> wrote: >> >>>>> >> >>>>> for i from 0 <= i < 10: >> >>>>> print i >> >>>>> i += 5 >> > >> > So I'm +1 for officially allowing the above and making it exit early. >> > Letting Cython basically ignore the "i += 5" would be a bug. >> > >> >> Me too, +1. >> >> >> >> -- >> Lisandro Dalcín >> --------------- >> Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC) >> Instituto de Desarrollo Tecnológico para la Industria Química (INTEC) >> Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET) >> PTLC - Güemes 3450, (3000) Santa Fe, Argentina >> Tel/Fax: +54-(0)342-451.1594 >> _______________________________________________ >> Cython-dev mailing list >> [email protected] >> http://codespeak.net/mailman/listinfo/cython-dev >> > > I looked at a range optimization example > > cdef int g(): > print "g called" > return 10 > > def f(): > cdef int i > for i in range(0, g(), 2): > print i > i += 2 > > This gives the following output - > > >>> > g called > 0 > 4 > 8 > > Is this the output we are expecting? I for one expected i to hold the next > value from the list supplied by range every time it iterates over the loop, > inspite of i being defined as a cdef int type. > > I created a temp variable inside Nodes.py. Every time i enter the loop, i > assign the loop counter var to the temp. Inside the loop, there on I can > modify the loop counter, but at the end of the loop i reassign the temp back > to the loop counter var. > > This is the code change i made > > diff -r 651a88137be7 Cython/Compiler/Nodes.py > --- a/Cython/Compiler/Nodes.py Fri Mar 20 17:51:46 2009 +0100 > +++ b/Cython/Compiler/Nodes.py Sun Mar 22 21:05:41 2009 +0530 > @@ -3968,6 +3968,7 @@ > loopvar_name = self.loopvar_node.result() > if from_range: > range_bound = code.funcstate.allocate_temp(self.bound2.type, > manage_ref=False) > + temp_loop_counter = > code.funcstate.allocate_temp(self.loopvar_node.type, manage_ref=False) > code.putln("%s = %s;" % (range_bound, self.bound2.result())) > # Skip the loop entirely (and avoid assigning to the loopvar) > if > # the loop is empty: > @@ -3976,18 +3977,22 @@ > )) > else: > range_bound = self.bound2.result() > code.putln( > "for (%s = %s%s; %s %s %s; %s%s) {" % ( > loopvar_name, > self.bound1.result(), offset, > loopvar_name, self.relation2, range_bound, > loopvar_name, incop)) > + if from_range: > + code.putln("%s = %s;" % (temp_loop_counter, loopvar_name)) > if self.py_loopvar_node: > self.py_loopvar_node.generate_evaluation_code(code) > self.target.generate_assignment_code(self.py_loopvar_node, > code) > self.body.generate_execution_code(code) > code.put_label(code.continue_label) > if from_range: > + code.putln("%s = %s;" % (loopvar_name, temp_loop_counter)) > # Undo last increment to maintain Python semantics: > code.putln("} %s%s;" % (loopvar_name, decop)) > # End the outer if statement: > > With that I get the following output- > g called > 0 > 2 > 4 > 6 > 8 > > Shouldn't this be the expected output? > > -- > Regards, > Anoop S. > > And for a "for in range", shouldn't we fall back to the way the python "for in range" works, even though a range optimization happens in case of a cython "for in range"? For example the following code: def f(): cdef int i i = 0 for i in range(10): print i i += 3 print "modify loop counter >> ", i print "outside the loop", i we currently get this output - >> calling f() 0 modify loop counter >> 3 4 modify loop counter >> 7 8 modify loop counter >> 11 outside the loop 11 But wouldn't the output be more intuitive if we get the following output? - 0 modify loop counter >> 3 1 modify loop counter >> 4 2 modify loop counter >> 5 3 modify loop counter >> 6 4 modify loop counter >> 7 5 modify loop counter >> 8 6 modify loop counter >> 9 7 modify loop counter >> 10 8 modify loop counter >> 11 9 modify loop counter >> 12 outside the loop 9 We can fall back to exiting the loop early in case of a "for from", but in case of a "for in range()", I feel the second output above is more intuitive, since that is how a python "for in range()" behaves. -- Regards, Anoop S.
_______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
