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

Reply via email to