Exponentiation operator has unexpected behaviour

Hi
I was exploring BigInt support and discovered a possible inconsistency in the exponentiation operator.
Here is a code snippet to see what i mean.

puts 2**2**2**2
expected output 65536 actual output 256

I think its more intuitive to interpret this as (2**(2**(2**2))) that is also how
Ruby, Python and Javascript behave.

Thanks

found this.
https://codeplea.com/exponentiation-associativity-options

Looks like there is no agreement on the associativity of exponentiation operator. But right-associative seems to be more common.

I sent a PR to fix this. Let’s hope it goes in before 1.0

4 Likes

Thank you. One less surprise for people coming to Crystal

Moving the discussion of the unary - operator and exponentiation ** from the issue to this thread.

I understand the benefit that the lexer treats directly the - prefix and returns -2 as a literal.
Luckily the -a ** 2 is consistent with this and is parsed as (-a) ** 2, as in (-2) ** 2.

The effect is that the unary and binary - operators have different precedence w.r.t. exponentiation.
0 - a ** 2 == - (a ** 2) .

Maybe there is nothing wrong with that, the fact that the parsing of -a ** 2 is consistent leaves me satisfied enough.

Unless the lexer & parser are changed in a way that will impact a bit in the performance what is left is to document in https://github.com/crystal-lang/crystal/wiki/Crystal-for-Rubyists the difference from Ruby.

Any other thoughts?