
I was wondering if anyone else has felt the need for a leftward division operator in Python. That is, y\x in addition to x/y. Thus the operators: y \ x y \\ x Why the statement "y\x" is different from "x/y": 1. Opposite order of evaluation: This is important if evaluating one of the operands has side-effects. 2. In linear algebra, (Y**-1)*X is in general not equal to X*(Y**-1). Matrix and vector algebra in fundamental to computer graphics and scientific computing. 3. NumPy solves the lack of "\" operator by having a function np.linalg.solve. But using it in matrix expressions has the effect of mixing Pythonic infix operators with a Lisp-like prefix operator. Two other issues: 1. The expressions y /= x y //= x are evaluated in the same order as "y \ x", not "x / y". 2. The expressions y \= x y \\= x should perhaps be illegal due to implied side-effects on RHS. Sturla

In Python, \ has a very consistent meaning as "escape character." I would hate for that consistency to be broken by adding a new meaning to \. For example, right now x = loooooooooooooooooooong + "line" \ "something" is valid. But if \ were also an operator, would it mean something different than "line" \ "something"? As to the order of operations problem, why not just do x = eval_first y = eval_second r = y/x ?

Mike Graham, 17.07.2011 16:49:
No, it doesn't. This code would continue to work as before, but that's exactly the problem here. It would be impossible to use a backslash division operator at the end of a line even in a properly braced expression, as that would turn it into an escape operator. Stefan

On Sun, Jul 17, 2011 at 5:16 AM, Sturla Molden <sturla@molden.no> wrote:
1. Python evaluates operands in left to right fashion. Breaking this requires extremely good justification (The ternary operator is the only current exception that doesn't involve a closure, and that's only because the alternatives were all even worse). 2. Backslash is not a viable operator choice. Ever. (cf. Carl's answer) 3. The use case is far too narrow to be baked into the core language. If it's beyond high school mathematics, syntactic support within expressions is highly unlikely to ever be provided. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan, 17.07.2011 09:22:
It would still be evaluated left-to-right, as far as I understand Sturla. Note that he swapped the x and y operands in the two examples for \ and /. So both operators would go left-to-right, only the resulting division would be reversed in the backslash case, thus dividing by the operand that was evaluated *first*. That being said, I agree with the comments below.
Plus, I don't find this syntax very readable, but I guess that just sits on top of your above two arguments. Stefan

On Sat, Jul 16, 2011 at 3:16 PM, Sturla Molden <sturla@molden.no> wrote:
No, I haven't felt this need. As a former heavy Matlab user it crossed my mind, but I don't really feel we're missing anything. The function approach is just as clear and is more useful, in that different problems call for different linear algebra solution routines. I am not aware for any other good usage for such an operator.
If we did get an \ operator, why not make it work like the rest of Python? I don't see a compelling reason for this.
Note that neither one of these are typically written as / or \ in math.
This isn't a "Lisp-like prefix operator". Normal functions are incredibly common in Python, in fact moreso than operators. They carry the initial advantage that there can be many of them and that they needn't be binary; this advantage is applicable to the problem at hand, because I can do solve_triangular(x, y) or solve(x, y, sym_pos=True, overwrite_a=True). Mike

Sturla Molden wrote:
You have flipped the operator AND flipped the order of the operands, which makes it confusing to me. I find it easy to reason about this proposal if I stick to one change at a time. I presume that x\y will be equivalent to y/x, or 1/(x/y) if x and y are numbers. Is there a standard mathematical infix operator for this? Since x/y => x.__truediv__(y), then x\y => x.__rtruediv__(y). Once only I have wanted something close to this. It wasn't terribly compelling: I ended up writing the obvious helper function: def divide_by(x, y): return y/x It did cross my mind at the time that it would be neat if this had \ as the operator, but I've met enough people who get their forward and back slashes mixed up that I wouldn't want to add to their confusion. So I would not support using \ as the operator for this.
This is ambiguous to me. Taken literally, you mean that the right-hand operatand (x) will be evaluated before the left-hand operand (y) (the opposite of normal for Python). Is that what you mean? I don't see any justification for that. Even the exponentiation operator evaluates terms from left-to-right although the operator binds more strongly to the right:
As far as I know, right-to-left evaluation would be a major change to Python. Or do you mean that the \ operator has the same order of evaluation as other operators, but instead of writing this: tmp = denominator() # Evaluate this first, because it has side-effects. result = numerator()/tmp you can write this: result = denominator()\numerator() I don't think this is important enough to justify a new operator. After all, can't we say the same thing for every other non-commutative operator? y = subtrahend() # Evaluate this first, because it has side-effects. result = minuend() - tmp Do we need to introduce new "reversed" operators for subtraction, exponentiation, left and right binary shift, matrix multiplication, even for addition? (Because a type can define __add__ and __radd__ separately, there is no guarantee that a+b is commutative.) If not, why single out division?
Is this supposed to be a problem that needs fixing?
Surely y \= x would have the same meaning as all the other augmented assignments? It should be the same as y = y\x That is, if x and y are numbers, y \= x would be equivalent to y = x/y I don't see any reason to make that illegal. -- Steven

Den 17.07.2011 18:27, skrev Steven D'Aprano:
tmp = denominator() # Evaluate this first, because it has side-effects. result = numerator()/tmp
The order of the arguments is lost to the division operator.
you can write this:
result = denominator()\numerator()
Only for real numbers. result = denominator()\numerator() would be equivalent to tmp = 1/denominator() result = tmp * numerator() But please ignore this suggestion, I agree that it is a bad suggestion. There is a better solution for this particular problem, which is to make 1/x return a new type, so that (1/x)*y evalutes differenty from y*(1/x). So I am thinking of suggesting addition of an "inverted matrix" type to NumPy instead. Sturla

On Sun, Jul 17, 2011 at 6:39 PM, MRAB <python@mrabarnett.plus.com> wrote:
If there's a reverse division operator, then why not a reverse subtraction operator too? Or a reverse modulo operator?
The inspiration was Matlab's \ operator, which comes in handy when you have a matrix A and a vector b and want to solve "A * x = b". In Matlab this is spelled "x = A \ b" and in Python with numpy it is spelled something like numpy.linalg.solve(A, b). This is a fairly common operation in numerical programs. No similar history and utility is obvious for these other operators. That being said, solve(A, b) is fine as far as I can see. Mike

MRAB wrote:
If there's a reverse division operator, then why not a reverse subtraction operator too?
I don't think the issue arises much with subtraction, because it's uncommon to work with addition-like operations that are not commutative. As for modulo, it's not really the inverse of anything in the way that / is the inverse of *. If there were a reversed division operator, I would probably have used it in a library I wrote recently for coordinate transformations. In that domain it's conventional to write the transformation on the left and the thing being transformed on the right, and it's natural to want to write an inverse transformation the same way. The solution I ended up with was to write the transformation of V by the inverse of T as T.inv * V where the inv attribute is calculated on demand and cached. This corresponds somewhat to the way a mathematician would write -1 T * V -- Greg

In Python, \ has a very consistent meaning as "escape character." I would hate for that consistency to be broken by adding a new meaning to \. For example, right now x = loooooooooooooooooooong + "line" \ "something" is valid. But if \ were also an operator, would it mean something different than "line" \ "something"? As to the order of operations problem, why not just do x = eval_first y = eval_second r = y/x ?

Mike Graham, 17.07.2011 16:49:
No, it doesn't. This code would continue to work as before, but that's exactly the problem here. It would be impossible to use a backslash division operator at the end of a line even in a properly braced expression, as that would turn it into an escape operator. Stefan

On Sun, Jul 17, 2011 at 5:16 AM, Sturla Molden <sturla@molden.no> wrote:
1. Python evaluates operands in left to right fashion. Breaking this requires extremely good justification (The ternary operator is the only current exception that doesn't involve a closure, and that's only because the alternatives were all even worse). 2. Backslash is not a viable operator choice. Ever. (cf. Carl's answer) 3. The use case is far too narrow to be baked into the core language. If it's beyond high school mathematics, syntactic support within expressions is highly unlikely to ever be provided. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan, 17.07.2011 09:22:
It would still be evaluated left-to-right, as far as I understand Sturla. Note that he swapped the x and y operands in the two examples for \ and /. So both operators would go left-to-right, only the resulting division would be reversed in the backslash case, thus dividing by the operand that was evaluated *first*. That being said, I agree with the comments below.
Plus, I don't find this syntax very readable, but I guess that just sits on top of your above two arguments. Stefan

On Sat, Jul 16, 2011 at 3:16 PM, Sturla Molden <sturla@molden.no> wrote:
No, I haven't felt this need. As a former heavy Matlab user it crossed my mind, but I don't really feel we're missing anything. The function approach is just as clear and is more useful, in that different problems call for different linear algebra solution routines. I am not aware for any other good usage for such an operator.
If we did get an \ operator, why not make it work like the rest of Python? I don't see a compelling reason for this.
Note that neither one of these are typically written as / or \ in math.
This isn't a "Lisp-like prefix operator". Normal functions are incredibly common in Python, in fact moreso than operators. They carry the initial advantage that there can be many of them and that they needn't be binary; this advantage is applicable to the problem at hand, because I can do solve_triangular(x, y) or solve(x, y, sym_pos=True, overwrite_a=True). Mike

Sturla Molden wrote:
You have flipped the operator AND flipped the order of the operands, which makes it confusing to me. I find it easy to reason about this proposal if I stick to one change at a time. I presume that x\y will be equivalent to y/x, or 1/(x/y) if x and y are numbers. Is there a standard mathematical infix operator for this? Since x/y => x.__truediv__(y), then x\y => x.__rtruediv__(y). Once only I have wanted something close to this. It wasn't terribly compelling: I ended up writing the obvious helper function: def divide_by(x, y): return y/x It did cross my mind at the time that it would be neat if this had \ as the operator, but I've met enough people who get their forward and back slashes mixed up that I wouldn't want to add to their confusion. So I would not support using \ as the operator for this.
This is ambiguous to me. Taken literally, you mean that the right-hand operatand (x) will be evaluated before the left-hand operand (y) (the opposite of normal for Python). Is that what you mean? I don't see any justification for that. Even the exponentiation operator evaluates terms from left-to-right although the operator binds more strongly to the right:
As far as I know, right-to-left evaluation would be a major change to Python. Or do you mean that the \ operator has the same order of evaluation as other operators, but instead of writing this: tmp = denominator() # Evaluate this first, because it has side-effects. result = numerator()/tmp you can write this: result = denominator()\numerator() I don't think this is important enough to justify a new operator. After all, can't we say the same thing for every other non-commutative operator? y = subtrahend() # Evaluate this first, because it has side-effects. result = minuend() - tmp Do we need to introduce new "reversed" operators for subtraction, exponentiation, left and right binary shift, matrix multiplication, even for addition? (Because a type can define __add__ and __radd__ separately, there is no guarantee that a+b is commutative.) If not, why single out division?
Is this supposed to be a problem that needs fixing?
Surely y \= x would have the same meaning as all the other augmented assignments? It should be the same as y = y\x That is, if x and y are numbers, y \= x would be equivalent to y = x/y I don't see any reason to make that illegal. -- Steven

Den 17.07.2011 18:27, skrev Steven D'Aprano:
tmp = denominator() # Evaluate this first, because it has side-effects. result = numerator()/tmp
The order of the arguments is lost to the division operator.
you can write this:
result = denominator()\numerator()
Only for real numbers. result = denominator()\numerator() would be equivalent to tmp = 1/denominator() result = tmp * numerator() But please ignore this suggestion, I agree that it is a bad suggestion. There is a better solution for this particular problem, which is to make 1/x return a new type, so that (1/x)*y evalutes differenty from y*(1/x). So I am thinking of suggesting addition of an "inverted matrix" type to NumPy instead. Sturla

On Sun, Jul 17, 2011 at 6:39 PM, MRAB <python@mrabarnett.plus.com> wrote:
If there's a reverse division operator, then why not a reverse subtraction operator too? Or a reverse modulo operator?
The inspiration was Matlab's \ operator, which comes in handy when you have a matrix A and a vector b and want to solve "A * x = b". In Matlab this is spelled "x = A \ b" and in Python with numpy it is spelled something like numpy.linalg.solve(A, b). This is a fairly common operation in numerical programs. No similar history and utility is obvious for these other operators. That being said, solve(A, b) is fine as far as I can see. Mike

MRAB wrote:
If there's a reverse division operator, then why not a reverse subtraction operator too?
I don't think the issue arises much with subtraction, because it's uncommon to work with addition-like operations that are not commutative. As for modulo, it's not really the inverse of anything in the way that / is the inverse of *. If there were a reversed division operator, I would probably have used it in a library I wrote recently for coordinate transformations. In that domain it's conventional to write the transformation on the left and the thing being transformed on the right, and it's natural to want to write an inverse transformation the same way. The solution I ended up with was to write the transformation of V by the inverse of T as T.inv * V where the inv attribute is calculated on demand and cached. This corresponds somewhat to the way a mathematician would write -1 T * V -- Greg
participants (10)
-
Boris Borcic
-
Carl Johnson
-
Greg Ewing
-
Guido van Rossum
-
Mike Graham
-
MRAB
-
Nick Coghlan
-
Stefan Behnel
-
Steven D'Aprano
-
Sturla Molden