Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document literal_pow #28685

Open
laborg opened this issue Aug 16, 2018 · 3 comments
Open

Document literal_pow #28685

laborg opened this issue Aug 16, 2018 · 3 comments
Labels
docs This change adds or pertains to documentation feature Indicates new feature / enhancement requests

Comments

@laborg
Copy link
Contributor

laborg commented Aug 16, 2018

As discussed in https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/5 it would be good if this is documented somewhere. The explanation of @StefanKarpinski in this thread will be helpful:

This was a controversial change and there are still many people who are not entirely comfortable with it. The starting point is that people do not really often expect or want x^2 and x^-1 to be pow(x, 2) and pow(x, -1), respectively. Rather, people want x^2 to be syntax for xx. The latter can generally be implemented much more efficiently than calling a general power function. With sufficiently clever optimizations (constant propagation + power reduction), one can potentailly optimize pow(x, 2) into xx but it would be even better if we didn’t have to do such a clever optimization in the first place. It’s been a fairly common and successful strategy in the design of Julia to arrange things so that you can get great performance in a straightforward way without need for clever optimizations instead of trying to make the optimizers smarter. So what this design does is it causes x^n where n is a literal integer value to call Base.literal_pow(x, Val(n)), which allows us to specialize the syntax on individual literal values like 2 or -1. This allow us to make x^2 actually mean x*x instead of needing to try to optimize it to that. It also allows us to make negative literal exponents work without introducing a type instability in the general ^ function. And indeed, we used to get regular complaints from new users that 2^-1 doesn’t return 0.5 as they would expect, instead giving them a domain error because of the negative exponent. There are good reasons for it but users don’t care about involved language design reasons, they just want it to work. A way to think about this is that ^2 is its own operator, as is ^3 and ^-1, and so on. Hopefully that helps.

#24240

@fredrikekre fredrikekre added the docs This change adds or pertains to documentation label Aug 16, 2018
@laborg
Copy link
Contributor Author

laborg commented Aug 16, 2018

Mhm. It is basically documented in ^:

If y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on
the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.)

But from that I think it's not clear that this compile-time specialization results in unexpected behaviour (see discourse thread).

@fredrikekre
Copy link
Member

Maybe we can add it as a FAQ?

@laborg
Copy link
Contributor Author

laborg commented Aug 16, 2018

As a naive user I expected to find something in the Mathematical Operations and Elementary Functions - Arithmetic Operators section of the manual. I think this is a section everybody new to Julia will read at least once, so it might be a good place to raise awareness and point to further information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This change adds or pertains to documentation feature Indicates new feature / enhancement requests
Projects
None yet
Development

No branches or pull requests

3 participants