> >I ran into a problem with exponentiation in Tcl 8.5.0:
> >expr {-2**2} gives 4 where I would expect -4 as an answer.
> Personally, I would expect -2**2 to parse as (-2)**2, > which was positive when I was at school; if I wanted > to get -4 I would probably ask for -(2**2).
> Of course, as I get older my grip on maths gets shakier, > so I could be wrong... > -- > Jonathan Bromley, Consultant
> > >I ran into a problem with exponentiation in Tcl 8.5.0:
> > >expr {-2**2} gives 4 where I would expect -4 as an answer.
> > Personally, I would expect -2**2 to parse as (-2)**2, > > which was positive when I was at school; if I wanted > > to get -4 I would probably ask for -(2**2).
> > Of course, as I get older my grip on maths gets shakier, > > so I could be wrong... > > -- > > Jonathan Bromley, Consultant
On Fri, 22 May 2009 04:50:43 -0700 (PDT), Arjen Markus wrote: > I expect -2**2 to parse as: -(2**2) [...] >Furthermore, I would expect that "0-expression" and > "-expression" give the same value, but: > expr {0-2**2} gives -4 >and > expr {-2**2} gives 4
>It may be my Fortran background, but I find the current parsing >somewhat disconcerting.
Fascinating. From various languages, I would expect monadic operators to bind more tightly than any dyadic operator. Monadic - is not the same as dyadic -; it isn't a shorthand for "0-" (not in my lexicon, anyway). I'd forgotten the Fortran behaviour.
I assume Tcl was guided by C, but I don't know C sufficiently intimately to be sure of its rules. I've learnt too many different languages in my time, and don't trust my increasingly flaky memory to hold operator precedence tables; parentheses are my friends. -- Jonathan Bromley, Consultant
You got tripped by coming from Fortran, where unary operations bind less tightly than exponentiation (and, puzzlingly, than multiplication and division). Tcl is not Fortran, and its precedences are slightly different. Other differences to watch out for:
- Fortran binds .EQ. and .GE. equally to .LT., .LE., .GE., .GT. . Tcl treats them equally. - Fortran binds // more loosely than addition and subtraction. Tcl considers % as equal to * and / - Tcl's & and | bind more tightly than && and || - Fortran associates ** from right to left. Tcl associates it from left to right. (I am on record as having been opposed to that decision, but I take it as made.)
Please excuse my dear Aunt Sally.*
-- 73 de ke9tv/2, Kevin
* For non-English speakers, and those who have forgotten high-school algebra, it's an old mnemonic: 'parentheses, exponents, multiplication, division, addition, subtraction'.)
> You got tripped by coming from Fortran, where unary > operations bind less tightly than exponentiation (and, > puzzlingly, than multiplication and division). Tcl > is not Fortran, and its precedences are slightly > different. Other differences to watch out for:
> - Fortran binds .EQ. and .GE. equally to .LT., > .LE., .GE., .GT. . Tcl treats them equally. > - Fortran binds // more loosely than addition > and subtraction. Tcl considers % as equal > to * and / > - Tcl's & and | bind more tightly than && and || > - Fortran associates ** from right to left. > Tcl associates it from left to right. (I am > on record as having been opposed to that > decision, but I take it as made.)
> Please excuse my dear Aunt Sally.*
> -- > 73 de ke9tv/2, Kevin
> * For non-English speakers, and those who have forgotten > high-school algebra, it's an old mnemonic: > 'parentheses, exponents, multiplication, division, addition, > subtraction'.)
Okay, from all the responses, it seems that -$y**2 should indeed be interpreted as (-$y)**2 and not as -($y**2).
Still, I interpret the following mathematical (!) expression exp(- y**2) as:
exp(-y**2) = exp(-(y*y)) = 1/exp(y*y)
in that sense a unary minus is binding less closely than exponentiation (well, if you write it like: 2 -y e
that does make sense :).
As for the right/left association of **, I seem to remember that we corrected that, the left associativity being the easy way to implement **. Indeed:
> You got tripped by coming from Fortran, where unary > operations bind less tightly than exponentiation (and, > puzzlingly, than multiplication and division). Tcl > is not Fortran, and its precedences are slightly > different. Other differences to watch out for:
> - Fortran binds .EQ. and .GE. equally to .LT., > .LE., .GE., .GT. . Tcl treats them equally. > - Fortran binds // more loosely than addition > and subtraction. Tcl considers % as equal > to * and / > - Tcl's & and | bind more tightly than && and || > - Fortran associates ** from right to left. > Tcl associates it from left to right. (I am > on record as having been opposed to that > decision, but I take it as made.)
> Please excuse my dear Aunt Sally.*
> -- > 73 de ke9tv/2, Kevin
> * For non-English speakers, and those who have forgotten > high-school algebra, it's an old mnemonic: > 'parentheses, exponents, multiplication, division, addition, > subtraction'.)
As it happens, I found in a book on AWK that I am reading that that language puts exponentiation before unary minus too.
I am not sure about the precedences in Fortran you cite - // is a string operation and can not be mixed with + or -, in Fortran % is done via the mod (or modulo) function (depending on what you want done with negative arguments) and the binary operations & and | are also done with functions.
Whether unary minus is tying less tightly than * or /, I do not know. How would "x* -y" be interpreted? (One tiny experiment suggests: x*(-y), but that is hardly proof of anything ;)).
On May 23, 6:22 am, Donald Arseneau <a...@triumf.ca> wrote:
> In written algebra -x² = x² implies x = 0. It is a mistake > for Tcl to bind the unary minus more tightly than exponentiation.
In written algebra -x² = x² is an equation, not a programming assignment statement. It is perfectly fine for x to equal zero, since the point is to solve for x in -x² = x².
Anyway, there is no "logic" involved in the associativity rules in a programming language. I don't even think that ** has a valid meaning in C. But every language should provide a method to indicate the desired parse/calculation order. If not, that would be a very serious bug, as some expressions could not be represented by the language. Tcl, like many languages, uses ( and ) to group sub-expressions and enforce the desired calculation order.
bauersa...@siemens.com> wrote: > Arjen Markus schrieb:
> > How would "x* -y" be interpreted? (One tiny experiment > > suggests: x*(-y), but that is hardly proof of anything ;)).
> How else could it? * is not optionally an unary postfix operator... :^)
True, I actually find such expressions a bit hard to read ... I later tried to examine it more closely using derived types and user-defined versions of the operations, so that I could write a message when the operation was run.
From that experiment I conclude: Kevin is quite right: unary minus comes later than multiplication, at least in -x*y.
In x*-y the unary minus comes first, but the compiler I used warned that support for the sequence *- is an extension ...
I tried to find situations where it matters whether unary minus comes before multiplication or after, mathematically I do not think that there is a difference (at least with ordinary numbers).
My, these are subtle issues! (In C these are more complicated than in Fortran, as Fortran distinguishes logicals and integers, so that x > y == z is not possible, at least not without jumping a hoop or two)
On May 23, 8:11 am, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> On May 23, 6:22 am, Donald Arseneau <a...@triumf.ca> wrote:
> > In written algebra -x² = x² implies x = 0. It is a mistake > > for Tcl to bind the unary minus more tightly than exponentiation.
> Anyway, there is no "logic" involved in the associativity rules in a > programming language. I don't even think that ** has a valid meaning > in C. But every language should provide a method to indicate the > desired parse/calculation order.
Probably the best argument for unary - binding more tightly that ** is that the sign of a number is part of the number, it isn't an operator. -2 is a negative number. In the expression 0-2, two is a positive integer. If the result was calculated, you would probably choose to write the expression as (0-x)**2 and not 0-x**2.
> On May 23, 8:11 am, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> > On May 23, 6:22 am, Donald Arseneau <a...@triumf.ca> wrote:
> > > In written algebra -x² = x² implies x = 0. It is a mistake > > > for Tcl to bind the unary minus more tightly than exponentiation.
> > Anyway, there is no "logic" involved in the associativity rules in a > >programminglanguage. I don't even think that ** has a valid meaning > > in C. But every language should provide a method to indicate the > > desired parse/calculation order.
> Probably the best argument for unary -bindingmore tightly that ** is > that thesignof a number is part of the number,itisn't an operator. > -2 is a negative number. In the expression 0-2, two is a positive > integer. If the result was calculated, you would probably choose to > write the expression as (0-x)**2 and not 0-x**2.
No, I do not agree: -$x**2 is computed as (-$x)**2 now, regardless of the sign of the number that the variable x holds. If x would have the value -2, then this would expand to --2**2. expr "-$x**2" still gives 4.
The whole issue arises only because exponentiation has a higher precedence than multiplication. A unary minus can also be seen as an implicit multiplication by -1, in which case -$x**2 would become: -1*$x**2.
On May 23, 8:11 am, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> On May 23, 6:22 am, Donald Arseneau <a...@triumf.ca> wrote:
> > In written algebra -x² = x² implies x = 0. It is a mistake > > for Tcl to bind the unary minus more tightly than exponentiation.
> In written algebra -x² = x² is an equation, not a programming > assignment statement. It is perfectly fine for x to equal zero, since > the point is to solve for x in -x² = x².
You are missing the point entirely!
In written algebra (what passes for "real life" here) the negation applies to the whole x² not the the x alone. Tcl should emulate the long-standing traditions of algebra for expr syntax.
Tcl's rules have made -x² = x² (-$x**2 == $x**2) an identity for all x, whereas in algebra that equality only holds for x = 0.
> Anyway, there is no "logic" involved
Not logic, but tradition and expectation. You wouldn't swap the meaning of + and - on a whim, would you?
> Probably the best argument for unary - binding more tightly that ** is > that the sign of a number is part of the number, it isn't an operator. > -2 is a negative number.
But unary - *IS* an operator outside of tcl, as demonstrated by the - x² example: x is squared, whether it is positive or negative, then the result is negated.
Now this brings us to a really messy bit, and I don't know if this was the deciding factor in the decision. eias.
set x 2 expr { $x**2 } expr $x**2 set x -2 expr { $x**2 } expr $x**2
Arjen Markus wrote: > I ran into a problem with exponentiation in Tcl 8.5.0:
> expr {-2**2} gives 4 where I would expect -4 as an answer.
See TIPs 123 and 274 and Tcl Patch 655176 (re-exposed for sake of this reference).
From TIP 123: "The precedence of the exponentiation operator is thus higher than the multiplication, division and remainder operations and lower than the unary operations, in accordance with common definitions."
You might ask Arjen Markus what rationale he had for proposing that precedence rule. :)
> In article <7260d1dc-6741-4930-b0c8-91405a832...@p6g2000pre.googlegroups.com>, > Donald Arseneau <a...@triumf.ca> wrote:
> >Now this brings us to a really messy bit, and I don't know if this > >was the deciding factor in the decision. eias.
> >set x 2 > >expr { $x**2 } > >expr $x**2 > >set x -2 > >expr { $x**2 } > >expr $x**2 > What's the messy bit? As a mathematician, EIAS seems > like a good deal to me; I *want*
> -2 ** 2
> to evaluate to
> +4.
WHAT!? I am aghast! As a mathematician, do you want -2² to equal 4? You must be disappointed, because -2² = -4. If you mean (-2)² then you must write it that way, with parentheses, and then you get 4. I don't see how there can be any confusion or disagreement on this issue, because algebraic notation is thoroughly standardized on this interpretation.
For creating the ** operator in Tcl expr, indeed any expr syntax, it would be best to maintain as close an analogy with written algebraic expressions as possible. The current ** operator does violate that.
But I see that eias and history have forced the current choice. Eias says that expr syntax should work the same if the variables are substituted textually before the expr is evaluated, which means $x**2 must give the same result as -2**2, when $x == 2. That forces negation to be more tightly bound to a number than anything else.
The history is that unary negation was of higher precedence than multiplication, and that old order can't be changed. I think this just gets back to the eias issue again, as the original motivation for that operator precedence.
Although the current choice may be forced, it is still an ugly wart.
> Arjen Markus wrote: > > I ran into a problem with exponentiation in Tcl 8.5.0:
> > expr {-2**2} gives 4 where I would expect -4 as an answer.
> See TIPs 123 and 274 and Tcl Patch 655176 (re-exposed for > sake of this reference).
> From TIP 123: "The precedence of the exponentiation operator > is thus higher than the multiplication, division and > remainder operations and lower than the unary operations, > in accordance with common definitions."
> You might ask Arjen Markus what rationale he had for proposing > that precedence rule. :)
> DGP
I have looking at the context of that sentence: he never considered the issue of -$x**2 :}.
According to the examples given, it all had to do with expressions like:
$x ** -1
This is a rather awkward oversight, in both our ever so humble opinions.
> On 24 mei, 17:28, Don Porter <dgpor...@verizon.net> wrote:
> > Arjen Markus wrote: > > > I ran into a problem with exponentiation in Tcl 8.5.0:
> > > expr {-2**2} gives 4 where I would expect -4 as an answer.
> > See TIPs 123 and 274 and Tcl Patch 655176 (re-exposed for > > sake of this reference).
> > From TIP 123: "The precedence of the exponentiation operator > > is thus higher than the multiplication, division and > > remainder operations and lower than the unary operations, > > in accordance with common definitions."
> > You might ask Arjen Markus what rationale he had for proposing > > that precedence rule. :)
> > DGP
> I have looking at the context of that sentence: he never considered > the issue of -$x**2 :}.
> According to the examples given, it all had to do with expressions > like:
> $x ** -1
> This is a rather awkward oversight, in both our ever so humble > opinions.
I would not be so harsh. Your only oversight IMO is just not to have untangled the knot generated by having unary minus separate (in priorities) from substraction. Indeed I believe we should have given higher strength to the intuitive expectation that 0-X == -X.
As it turns out, putting the whole group of unary ops on top is a very strange decision. It often goes unnoticed because the only really interesting one for computations (unary minus) happens to commute with * and / which come immediately afterwards in priority. So the fact that -3*4 parses as (-3)*4 is hidden. However, it does not commute with the modulo operator, in the same prio class as * and /, so we can generate another example of this awkward ordering without using exponentiation:
expr {-3%4} --> 1 expr {0-3%4} --> -3
So you can see that certainly you have absolutely no reproach to fear !!! Of course it is way too late to change that. I don't want a 2nd Chernobyl or Challenger disaster coming from Tcl aesthetics :-P
On May 25, 12:05 pm, Alexandre Ferrieux <alexandre.ferri...@gmail.com> wrote:
> It often goes unnoticed because the only really interesting one for > computations (unary minus) happens to commute with * and / which come > immediately afterwards in priority.
Uh, for floating-point yes, but of course, as the modulo case suggests, unary minus does not even commute with integer division:
expr {-3/4} --> -1 expr {0-3/4} --> 0
Again we have really trivial examples that already violate intuition. Sad and irreversible.
Alexandre Ferrieux wrote: > Uh, for floating-point yes, but of course, as the modulo case > suggests, unary minus does not even commute with integer division:
> expr {-3/4} --> -1 > expr {0-3/4} --> 0
For what it's worth, C gets that one wrong as well, making me wonder whether that's a subtle reason that C never added **. The modular and integer arithmetic issues are considerably more subtle, since the operations in question are far more often used with unsigned (or at least nonnegative) quantities.
This issue is another one to put on the list with 'death to octal' and 'creative writing': The list in question is "those changes that will probably fix more bugs than they introduce, because existing behaviour is surprising." That's one level down from "I don't have any code that depends on the surprising behaviour, but someone *else* might, so let's not fix it."
The thing that this is really awkward for is polynomials with a leading factor of -1. -x**4 + 4. * x**3 - 6. * x**2 + 4. * x - 1 Yes, I know this is a bad example, anyone sane would write -(x-1)**4 OOPS! I mean -((x-1)**4) This is very bad, it's right up there with making exponentiation left-associative. (And I checked the code: we correctly make it right-associative. But the manual lies. Can we please fix the documentation and not the code for that one?)
On May 25, 1:14 am, Donald Arseneau <a...@triumf.ca> wrote:
> On May 24, 5:39 am, cla...@lairds.us (Cameron Laird) wrote:
As a mathematician, EIAS seems
> > like a good deal to me; I *want*
> > -2 ** 2
> > to evaluate to
> > +4.
> WHAT!? I am aghast! As a mathematician, do you want -2² to > equal 4? You must be disappointed, because -2² = -4. If you > mean (-2)² then you must write it that way, with parentheses, > and then you get 4. I don't see how there can be any confusion > or disagreement on this issue, because algebraic notation is > thoroughly standardized on this interpretation.
You seem to think that mathematicians don't think of -2 as a distinct number which could be multiplied by itself.
If squaring -2 requires (-2)**2, then so should 2: (2)**2. But mathematics is not programming language. In a Tcl expression all variables have known values. In a mathematical equation, the x's and y's are unknowns. In mathematics, -x^2 is not an equation, it is meaningless, but -2 is a negative number.
In a mathematical equation like y = x^2 - 2x + 1, the implied meaning is that each power of x is preceded by a coefficient. The coefficient has an associated sign. The above can be factored to y = (x - 1)(x - 1) = (x - 1)^2. Somehow mathematicians know how to square (x - 1) correctly.
What result should Tcl return for this example: -2**0.5?