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?