# Confusing difference: ^literal vs ^variable

**URL:** https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515
**Category:** General Usage
**Created:** [August 15, 2018, 5:26pm UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515 "2018-08-15T17:26:47Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)
#### Post date: [August 15, 2018, 5:26pm UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/1 "2018-08-15T17:26:47Z")

</div>

I’m confused by the difference when `^` is used with a literal vs a variable:

```julia
julia> p = -13;

julia> 3 ^ p
ERROR: DomainError with -13:
Cannot raise an integer x to a negative power -13.
Make x a float by adding a zero decimal (e.g., 2.0^-13 instead of 2^-13), or write 1/x^13, float(x)^-13, or (x//1)^-13
Stacktrace:
 [1] throw_domerr_powbysq(::Int64, ::Int64) at ./intfuncs.jl:176
 [2] power_by_squaring(::Int64, ::Int64) at ./intfuncs.jl:196
...

julia> 3 ^ -13
6.272254743863065e-7

julia> @code_llvm 3 ^ p

; Function ^
; Location: intfuncs.jl:220
define i64 @"julia_^_38072"(i64, i64) {
top:
  %2 = call i64 @julia_power_by_squaring_24844(i64 %0, i64 %1)
  ret i64 %2
}

julia> @code_llvm 3 ^ -13

; Function ^
; Location: intfuncs.jl:220
define i64 @"julia_^_38072"(i64, i64) {
top:
  %2 = call i64 @julia_power_by_squaring_24844(i64 %0, i64 %1)
  ret i64 %2
}

```

It’s surprising to me that although the code should do the same, something magically changes behaviour.

I found various issues concerning this topic, some of them even mentioning this exact behaviour ([https://github.com/JuliaLang/julia/pull/20637#issuecomment-280593009](https://github.com/JuliaLang/julia/pull/20637#issuecomment-280593009)) but it’s hard to decipher what has been discussed/decided/implemented/documented.

@StefanKarpinski Could you please explain the current thinking on this topic or link me to the right documentation?

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [August 15, 2018, 5:53pm UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/2 "2018-08-15T17:53:12Z")

</div>

That is intriguing…

```julia
julia> f() = 3 ^ -13
f (generic function with 1 method)

julia> g() = (p=-13; 3^p)
g (generic function with 1 method)

julia> @code_warntype f()
Body::Float64
1 1 ─ %1 = $(Expr(:foreigncall, "llvm.pow.f64", Float64, svec(Float64, Float64), :(:llvmcall), 2, 0.3333333333333333, 13.0, 13.0, 0.3333333333333333))::Float64
  └── return %1 │

julia> @code_warntype g()
Body::Union{}
1 1 ─ %1 = π (-13, Core.Compiler.Const(-13, false)) │
  │ invoke Main.:^(3::Int64, %1::Int64) │
  │ $(Expr(:unreachable)) │
  └── $(Expr(:unreachable))

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 15, 2018, 5:54pm UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/3 "2018-08-15T17:54:59Z")

</div>

[https://github.com/JuliaLang/julia/pull/24240](https://github.com/JuliaLang/julia/pull/24240)

---

<div class="post-metadata">

### Author: ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)
#### Post date: [August 16, 2018, 6:10am UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/4 "2018-08-16T06:10:17Z")

</div>

Is this documented somewhere for new users? (except the news-entry)

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 16, 2018, 8:00am UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/5 "2018-08-16T08:00:26Z")

</div>

That’s a good question. I’m not sure that it is, but it definitely should be. If you grep Julia’s doc directory for `literal_pow` and don’t for anything, that means that it’s not. If so, please do file a doc issue. I would do it but I’m on a phone and won’t have a chance for a while.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 16, 2018, 8:32am UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/6 "2018-08-16T08:32:59Z")

</div>

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 `x*x` and `x^-1` to be a syntax for `1/x`. These can both generally be implemented much more efficiently than calling a general power function—but in completely different ways. With sufficiently clever optimizations (constant propagation + power reduction), one can potentailly optimize `pow(x, 2)` into `x*x` 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.

---

<div class="post-metadata">

### Author: ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)
#### Post date: [August 16, 2018, 9:54am UTC](https://discourse.julialang.org/t/confusing-difference-literal-vs-variable/13515/7 "2018-08-16T09:54:47Z")

</div>

Thx, thats very helpful.  
Although `^` is documented I think this could be improved and therefore filed [https://github.com/JuliaLang/julia/issues/28685](https://github.com/JuliaLang/julia/issues/28685)
