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

InteractiveUtils methods show incorrect method for negative powers #43337

Closed
BioTurboNick opened this issue Dec 5, 2021 · 6 comments · Fixed by #53713
Closed

InteractiveUtils methods show incorrect method for negative powers #43337

BioTurboNick opened this issue Dec 5, 2021 · 6 comments · Fixed by #53713

Comments

@BioTurboNick
Copy link
Contributor

julia> @code_typed true ^ -1
CodeInfo(
1%1 = Base.slt_int(p, 0)::Bool
└──      goto #5 if not %1
2%3 = Base.not_int(x)::Bool
└──      goto #4 if not %3
3 ─      invoke Base.throw_domerr_powbysq(_2::Bool, _3::Int64)::Union{}
└──      unreachable
4nothing::Nothing
5%8 = (p === 0)::Bool%9 = Base.or_int(%8, x)::Bool
└──      goto #6
6return %9
) => Bool

# as expected
julia> a = true ^ 1; println(a, " ", typeof(a))
true Bool

# ???
julia> a = true ^ -1; println(a, " ", typeof(a))
1.0 Float64

# strangely, these forms work
julia> a = true ^ Int64(-1); println(a, " ", typeof(a))
true Bool
julia> a = true ^ -Int64(1); println(a, " ", typeof(a))
true Bool
@Seelengrab
Copy link
Contributor

Seelengrab commented Dec 5, 2021

I think the difference to true ^ Int(1) is due to literal integer powers being handled specially during parsing - it's the only time we truly know what function to apply and since true isa Number, it gets promoted and computed as inv(true), which is 1.0. Exponentiation with literals being quasi type unstable is known.

@BioTurboNick
Copy link
Contributor Author

Ahh interesting. Okay. Why are they handled specially?

@BioTurboNick
Copy link
Contributor Author

BioTurboNick commented Dec 5, 2021

So is the issue just that inv(x::Bool) = x should be defined?

Oh, I see, it's because false (0) to a negative power is Inf. I suppose the alternative is to error, but maybe that would cause more issues?

Answering my own question - 1) because it's more efficient, and 2) Needs special handling to be mathematically correct?

@BioTurboNick
Copy link
Contributor Author

Although, I guess that leaves the question of why InteractiveUtils doesn't show the correct method lowering.

@BioTurboNick BioTurboNick reopened this Dec 5, 2021
@BioTurboNick BioTurboNick changed the title power_by_squaring for Bool with negative int literal produces Float64 value InteractiveUtils methods show incorrect method for negative powers Dec 5, 2021
@BioTurboNick
Copy link
Contributor Author

I guess this is a duplicate of #21014.

@Seelengrab
Copy link
Contributor

It's handled specially because we can, at parse time, figure out that the exponent is negative (it's a literal after all, the type can't magically change) and thus the result will be a Float64. This makes it stable by not going through the regular ^. x^(-y) will after all always be 1/(x^y), with some edge case caveats.

mbauman added a commit that referenced this issue Apr 3, 2024
…w` case. (#53713)

The macros `@which`, `@edit`, `@functionloc`, `@less` from `InteractiveUtils`, if
applied to the case of literal powers, like `a^12` or `2^-1` used to direct the
user to function `^`, while the compiler generates code for `Base.literal_pow`.

Now the user is shown the code the compiler generates.

Fixes #53691
Fixes #43337
Fixes #21014

Co-authored-by: Matt Bauman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants