(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?) In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I [ ] Get 4, because it should behave just like in Python, avoiding surprises when adding types to existing algorithms (this will require extra logic and be a bit slower) [ ] Get -1, because they're C ints, and besides one isn't using Cython if one doesn't care about performance Whatever we do, this also affects the division operator, so that one in any case will have a==(a//b)*b+a%b. (Orthogonal to this, we can introduce compiler directives to change the meaning of the operator from the default in a code blocks, and/or make special functions for the semantics that are not chosen as default.) -- Dag Sverre
On Thu, Mar 12, 2009 at 07:59:48PM +0100, Dag Sverre Seljebotn wrote:
(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?)
Yes, IMHO.
In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I
[ ] Get 4, because it should behave just like in Python, avoiding surprises when adding types to existing algorithms (this will require extra logic and be a bit slower)
[ ] Get -1, because they're C ints, and besides one isn't using Cython if one doesn't care about performance
Behave like in Python. Cython should try to be as Python-like as possible, IMHO. I would like to think of it as an (optionally) static-typed Python. My 2 cents, Gaël
Hi Dag 2009/3/12 Dag Sverre Seljebotn <dagss@student.matnat.uio.no>:
(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?)
Given that many of the subscribers make use of the NumPy support in Cython, I don't think they would mind; I, for one, don't.
In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I
[ ] Get 4, because it should behave just like in Python, avoiding surprises when adding types to existing algorithms (this will require extra logic and be a bit slower)
I'd much prefer this option. When students struggle to get their code faster, my advice to them is: "run it to Cython, and if you are still not happy, start tweaking this and that". It would be much harder to take that route if you had to take a number of exceptional behaviours into account.
(Orthogonal to this, we can introduce compiler directives to change the meaning of the operator from the default in a code blocks, and/or make special functions for the semantics that are not chosen as default.)
In my experience, keeping the rules simple has a big benefit (the "programmer's brain cache" can only hold a small number of items -- a very good analogy made by Fernando Perez), so I would prefer not to have this option. Regards Stéfan
On Thu, Mar 12, 2009 at 12:59 PM, Dag Sverre Seljebotn < dagss@student.matnat.uio.no> wrote:
(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?)
In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I
I almost always want the python version, even in C, because I want the results to lie in the interval [0,5) like a good modulus functions should ;) I suppose the question is : is '%' standing for the modulus or is it standing for the remainder in whatever version of division is being used. This is similar to the difference between the trunc and floor functions; I find using the floor function causes fewer problems, but it isn't the default. That said, I think it best to leave '%' with its C default and add a special modulus function for the python version. Changing its meaning in C-like code is going to confuse things. Chuck
2009/3/13 Charles R Harris <charlesr.harris@gmail.com>:
That said, I think it best to leave '%' with its C default and add a special modulus function for the python version. Changing its meaning in C-like code is going to confuse things.
This is Cython code, so I think there is an argument to be made that it is Python-like! Stéfan
2009/3/13 Charles R Harris <charlesr.harris@gmail.com>:
That said, I think it best to leave '%' with its C default and add a special modulus function for the python version. Changing its meaning in C-like code is going to confuse things.
This is Cython code, so I think there is an argument to be made that it is Python-like!
I'll just repeat what I've already said on the Cython mailing list: I think C types should behave like C types and Python objects like Python objects. If a C long suddenly starts to return double when divided by another C long, then that will be a major source of confusion on my part. If I want the behaviour of Python integers, Cython lets me use Python objects. I don't declare a variable cdef long if I want it to behave like a Python int. Sturla Molden
On Thu, Mar 12, 2009 at 17:45, Sturla Molden <sturla@molden.no> wrote:
2009/3/13 Charles R Harris <charlesr.harris@gmail.com>:
That said, I think it best to leave '%' with its C default and add a special modulus function for the python version. Changing its meaning in C-like code is going to confuse things.
This is Cython code, so I think there is an argument to be made that it is Python-like!
I'll just repeat what I've already said on the Cython mailing list:
I think C types should behave like C types and Python objects like Python objects. If a C long suddenly starts to return double when divided by another C long, then that will be a major source of confusion on my part. If I want the behaviour of Python integers, Cython lets me use Python objects. I don't declare a variable cdef long if I want it to behave like a Python int.
That may be part of the confusion. The expression "-1%5" has no variables. Perhaps Dag can clarify what he is asking about: # Constants? (No one uses just constants in expressions, # really, but consistency with the other choices will # affect this.) -1 % 5 # Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j # Python types? i = -1 j = 5 k = i % j # A mixture? cdef long i i = -1 j = 5 k = i % j When I do (2147483647 + 2147483647) in current Cython, to choose another operation, does it use C types, or does it construct PyInts? I.e., do I get C wraparound arithmetic, or do I get a PyLong? I recommend making % behave consistently with the other operators; i.e. if <x>+<y> uses C semantics, <x>%<y> should, too. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
Robert Kern wrote:
On Thu, Mar 12, 2009 at 17:45, Sturla Molden <sturla@molden.no> wrote:
2009/3/13 Charles R Harris <charlesr.harris@gmail.com>:
That said, I think it best to leave '%' with its C default and add a special modulus function for the python version. Changing its meaning in C-like code is going to confuse things. This is Cython code, so I think there is an argument to be made that it is Python-like!
I'll just repeat what I've already said on the Cython mailing list:
I think C types should behave like C types and Python objects like Python objects. If a C long suddenly starts to return double when divided by another C long, then that will be a major source of confusion on my part. If I want the behaviour of Python integers, Cython lets me use Python objects. I don't declare a variable cdef long if I want it to behave like a Python int.
Whether division returns float or not is an orthogonal and unrelated issue (and when it does, which is not the default, // is the C division operator). When we say that this affects division; what we mean is that -7 // 6 returns -2 in Python; so that (-7 // 6)*6 + (-7 % 6) == -2*6 + 5 == -7. With C behaviour of % and /, I believe -7 // 6 == -1. (And when I use // it is to be unambigious; by default you can use / as well for the same thing.)
That may be part of the confusion. The expression "-1%5" has no variables. Perhaps Dag can clarify what he is asking about:
# Constants? (No one uses just constants in expressions, # really, but consistency with the other choices will # affect this.) -1 % 5
# Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j
This one is what I'm really asking about.
When I do (2147483647 + 2147483647) in current Cython, to choose another operation, does it use C types, or does it construct PyInts? I.e., do I get C wraparound arithmetic, or do I get a PyLong?
C wraparound. Suggestions welcome :-)
I recommend making % behave consistently with the other operators; i.e. if <x>+<y> uses C semantics, <x>%<y> should, too.
-- Dag Sverre
On Fri, Mar 13, 2009 at 01:41, Dag Sverre Seljebotn <dagss@student.matnat.uio.no> wrote:
Robert Kern wrote:
That may be part of the confusion. The expression "-1%5" has no variables. Perhaps Dag can clarify what he is asking about:
# Constants? (No one uses just constants in expressions, # really, but consistency with the other choices will # affect this.) -1 % 5
# Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j
This one is what I'm really asking about.
My opinion on this is that C semantics have been explicitly requested, so they should be used. One possibility (that may be opening a can of worms) is to have two sets of operators, one that does "native" semantics (C for cdef longs, Python for Python ints) and one that does Python semantics even on cdef longs. I leave it to you to decide which one gets blessed with "%" and which has to use the alternate ("~%"? there's a whole PEP sitting around which goes over various options). -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
On Thu, Mar 12, 2009 at 11:34 PM, Robert Kern <robert.kern@gmail.com> wrote:
One possibility (that may be opening a can of worms) is to have two sets of operators, one that does "native" semantics (C for cdef longs, Python for Python ints) and one that does Python semantics even on cdef longs. I leave it to you to decide which one gets blessed with "%" and which has to use the alternate ("~%"? there's a whole PEP sitting around which goes over various options).
Without going into the whole pep 225 discussion, would it make sense for this particular case only, to consider instead a new %% operator? It could be the partner to the (/,//) pair that provide Python/C semantics for division, perhaps. That way, we'd know that the division-like operators come in 2 variants. We already know that the moment we do cdef i that thing will not behave like a python int (e.g., its overflow behavior becomes constrained to what happens inside of a finite bit-width, instead of having Python's auto-growth into arbitrary length ints). So it seems acceptable to me that once I cdef integer variables, I'll need to keep the C/Python semantics in mind for / and %, and having pairs (/,//), (%,%%) of operators to access each type of behavior sounds reasonable to me. Just a thought. Cheers, f
Fernando Perez wrote:
On Thu, Mar 12, 2009 at 11:34 PM, Robert Kern <robert.kern@gmail.com> wrote:
One possibility (that may be opening a can of worms) is to have two sets of operators, one that does "native" semantics (C for cdef longs, Python for Python ints) and one that does Python semantics even on cdef longs. I leave it to you to decide which one gets blessed with "%" and which has to use the alternate ("~%"? there's a whole PEP sitting around which goes over various options).
Without going into the whole pep 225 discussion, would it make sense for this particular case only, to consider instead a new %% operator?
This exact proposal was up on the Cython list. The fear was that if Python decides to use this operator for something else in the future... Please note that there are 3 different division operators: - / under Py3/future import, which always returns float ("truediv") - // (which is the same as / in Py2), which always floors the result, i.e. -7 // 6 == -2 - The C /, which truncates the result, i.e. -7 / 6 == -1 So there's no directly corresponding pair of // and %% (one would need to intrudoce /// or similar for C division in addition, in that case). Dag Sverre
On Fri, Mar 13, 2009 at 01:41, Dag Sverre Seljebotn
# Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j
This one is what I'm really asking about.
My opinion on this is that C semantics have been explicitly requested, so they should be used.
I agree with this. I feel that "cdef long i, j, k" is a request to "step into C". But here I feel the Cython team is trying to make me step into a broken C. Sturla Molden
Sturla Molden wrote:
On Fri, Mar 13, 2009 at 01:41, Dag Sverre Seljebotn
# Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j
This one is what I'm really asking about.
My opinion on this is that C semantics have been explicitly requested, so they should be used.
I agree with this. I feel that "cdef long i, j, k" is a request to "step into C". But here I feel the Cython team is trying to make me step into a broken C.
Well, first of all the Cython team as a whole is still undecided on the issue, notably project lead Robert Bradshaw is either undecided or leaning towards your view. There's been lot of feedback, and they tend to fall into two groups: - Declaring types means requesting C semantics - Declaring types means typing the Python language to make it faster So it's more about making it "typed Python" than "broken C" IMO. (Introducing a new set of types for "typed Python" is an idea that could please everybody, but I fear the confusion it would bring myself...) Interestingly the Sage list, Cython list and NumPy lists all seem about equally divided on the issue. Dag Sverre
Robert Kern wrote:
# Explicitly declared C types? cdef long i, j, k i = -1 j = 5 k = i % j This one is what I'm really asking about.
My opinion on this is that C semantics have been explicitly requested, so they should be used.
maybe ...
One possibility (that may be opening a can of worms) is to have two sets of operators, one that does "native" semantics (C for cdef longs, Python for Python ints) and one that does Python semantics even on cdef longs.
ouch! no. I think this is a case of practicality vs. purity. A common use case would be that a person starts out with their code in python, then moves it to cython, then adds the cdef, testing (or not!) as they go. The problem here is that yes, there are going to be differences when you apply a cdef, but a difference like this, that may very well not show up at all in tests (unless the user is aware enough of this particular issue to explicitly test for it). Now the code is broken in a subtle, and hard to find way that could turn up who knows when, with want data. This is kind of like the "new division" issue with python itself -- it is much better to simply be explicit: "/" means float division, "//" means integer division, regardless of the types of the operands. If you apply the same principle here, then we should one operator for "c style modulo", and one for "python style modulo", regardless of the types of the operands. -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
On Thu, 2009-03-12 at 19:59 +0100, Dag Sverre Seljebotn wrote:
(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?)
In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I
[ ] Get 4, because it should behave just like in Python, avoiding surprises when adding types to existing algorithms (this will require extra logic and be a bit slower)
[ ] Get -1, because they're C ints, and besides one isn't using Cython if one doesn't care about performance
Whatever we do, this also affects the division operator, so that one in any case will have a==(a//b)*b+a%b.
(Orthogonal to this, we can introduce compiler directives to change the meaning of the operator from the default in a code blocks, and/or make special functions for the semantics that are not chosen as default.)
I definitely fall into the "I prefer C semantics" crowd. Because my brain is in "C" mode whenever I write Cython. However, I totally understand the arguments from the other side, and I would not be upset if Cython went in that direction. You could say that I have my preference, but I can't make a strong argument for it. Chris
On Tue, May 4, 2010 at 12:20 PM, S. Chris Colbert <sccolbert@gmail.com>wrote:
On Thu, 2009-03-12 at 19:59 +0100, Dag Sverre Seljebotn wrote:
(First off, is it OK to continue polling the NumPy list now and then on Cython language decisions? Or should I expect that any interested Cython users follow the Cython list?)
In Python, if I write "-1 % 5", I get 4. However, in C if I write "-1 % 5" I get -1. The question is, what should I get in Cython if I write (a % b) where a and b are cdef ints? Should I
[ ] Get 4, because it should behave just like in Python, avoiding surprises when adding types to existing algorithms (this will require extra logic and be a bit slower)
[ ] Get -1, because they're C ints, and besides one isn't using Cython if one doesn't care about performance
Whatever we do, this also affects the division operator, so that one in any case will have a==(a//b)*b+a%b.
(Orthogonal to this, we can introduce compiler directives to change the meaning of the operator from the default in a code blocks, and/or make special functions for the semantics that are not chosen as default.)
I definitely fall into the "I prefer C semantics" crowd. Because my brain is in "C" mode whenever I write Cython. However, I totally understand the arguments from the other side, and I would not be upset if Cython went in that direction.
You could say that I have my preference, but I can't make a strong argument for it.
Chris
It seems I was a little late to the party. The mail client's sort-by-date was reversed. My apologies.
participants (10)
-
Charles R Harris
-
Chris Colbert
-
Christopher Barker
-
Dag Sverre Seljebotn
-
Fernando Perez
-
Gael Varoquaux
-
Robert Kern
-
S. Chris Colbert
-
Sturla Molden
-
Stéfan van der Walt