-
-
Couldn't load subscription status.
- Fork 5.7k
Description
There are four methods with @assume_effects :total applied to the entire method in base/irrationals.jl:
Line 55 in 6e5e87b
| @assume_effects :total function Rational{T}(x::AbstractIrrational) where T<:Integer |
Lines 70 to 71 in 6e5e87b
| @assume_effects :total function (t::Type{T})(x::AbstractIrrational, r::RoundingMode) where T<:Union{Float32,Float64} |
Lines 113 to 120 in 6e5e87b
| @assume_effects :total function rationalize(::Type{T}, x::AbstractIrrational; tol::Real=0) where T | |
| return rationalize(T, big(x), tol=tol) | |
| end | |
| @assume_effects :total function lessrational(rx::Rational{<:Integer}, x::AbstractIrrational) | |
| # an @assume_effects :total version of `<` for determining if the rationalization of | |
| # an irrational number required rounding up or down | |
| return rx < big(x) | |
| end |
Issues:
- The
:totaleffect is too powerful and not future-proof. I guess what's actually desired is just:foldable. - It's not valid to apply
@assume_effectsto the::AbstractIrrationalmethods, because users may define custom subtypes ofAbstractIrrational, and thus calls likeBigFloat(::AbstractIrrational)orbig(::AbstractIrrational)may execute arbitrary code. That said ... - It's not valid to apply
@assume_effectseven just for::Irrational, because users may define custom subtypes ofIrrational! Example:
# in a user package
struct IrrationalSymbol end
function big(::Irrational{IrrationalSymbol})
execute_arbitrary_code()
endThis seems perfectly legal, or at least it's not type piracy.
The solution seems simple: define a Union of all known irrational constants, something like the following, then dispatch on it for methods that have @assume_effects, instead of on AbstractIrrational or on Irrational:
const _KnownIrrational = (ℯ, π, MathConstants.γ, MathConstants.catalan, MathConstants.φ)This will ensure calls involving the known constants are foldable, and allow the unsafe @assume_effects annotations to be deleted. Will make a PR later.