-
Notifications
You must be signed in to change notification settings - Fork 8
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
Implement tau==2pi (in type-stable manner) #28
Conversation
I don't think I like this. This should be implemented in julia core for all irrational numbers if there is consensus on such change, I don't see why tau should be special in this regard :) |
I'd have no problems making a proposal to Base, but what exactly would you suggest the change to be? Here we're allowing two |
Codecov Report
@@ Coverage Diff @@
## master #28 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 2 2
Lines 61 67 +6
=====================================
+ Hits 61 67 +6
Continue to review full report at Codecov.
|
Note: while I was at it, I took the opportunity to reorganize the test script and start using the |
I would split the reorganization of tests from this PR, that change is unrelated and unquestionable |
Good point. I've rebuilt the testset reorganization changes independently, in #29. I'll rebase this branch over it so that it contains only the equality changes. |
A possibility could be ==(x::Irrational, y::T) where {T<:AbstractFloat} = T(x) == y
==(x::T, y::Irrational) where {T<:AbstractFloat} = x == T(y) In this way: julia> pi == 3.1415927f0
true
julia> 3.141592653589793 == pi
true
julia> 3.141592653589794 == pi
false
julia> pi == big"3.141592653589793238462643383279502884197169399375105820974944592307816406286198"
true But speaking for myself I find the argument "an Irrational can't be equal to any decimal number with finite representation" pretty compelling. |
I see, so every irrational would be equal to (various representations of) itself. I will collect some information from previous discussions, and submit a PR later. In the meantime, I've rebased this PR to cleanup the changes after the merging of #29. I suppose this change (making 2pi equal to tau) can be handled separately to making every irrational equal to itself, since with this change the original inequality definition remains in place for any other combination. The exception for tau==2pi is IMO justifiable, given that this is precisely how these two constants are defined -- them not being equal is more likely to cause confusion than the fact that an irrational number is considered equal to what is technically a finite representation. The latter only trips the user if they're analyzing the underlying representation of their code from the point of view of how the computer handles it, rather than whatever conceptual algorithm they're implementing. Even then, that surprise is not likely to cause practical issues, since this change has no performance implications (that I'm aware of). |
So you're saying that |
You know what I mean :P (edit: just for the sake of completeness: |
As you write in the document, in julia 2π is rational because of rounding. So 2π!=tau, in the same way as
I would not do an ad hoc fix to this by redefining equality. |
Thanks for your input, @mschauer :)
Yes, and this is a technical implementation artifact, not a deliberate choice. The current inequality is actually based on mixing two extremes of the abstraction spectrum: one based on the low-level technical limitations of floating point number representation, and another based on the high-level mathematical properties of irrational numbers. I'm not entirely convinced that combining these two concepts, from very distinct (almost opposite) abstraction levels, as premises for reaching the conclusion of inequality (and going out of our way to manually define such inequality, which otherwise the promotion mechanism would handle as one would intuitively expect) is a sound choice.
That was exactly what was done in JuliaLang/julia#9198, though: defining an override to the equality method (and a hardcoded one at that!), so that it returned the the result it should. according to the author of that change. The solution presented here has exactly the same kind of rationale (ensuring the result of One objection I'm willing to concede to is that perhaps a more perfect way to do this could be found -- but until an implementation plan is defined, and considering that this change maintains type stability and has no performance impact (nor it affects the strict inequality for all other Irrational comparisons), I'm inclined to go ahead and merge in honor of Tau day tomorrow. We can always replace this implementation with something better down the road, and I'm very much open to that. |
After your change either
with
if you do not recompile <=) |
src/Tau.jl
Outdated
import Base.== | ||
=={T<:Real}(::Irrational{:τ}, n::T) = n == 2*T(π) | ||
=={T<:Real}(n::T, ::Irrational{:τ}) = n == 2*T(π) | ||
=={T<:Real}(::Irrational{:π}, n::T) = n == T(τ)/2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 20, 21, and 29 are acts of type-piracy of Base's types.
This isn't actually true, it is a deliberate choice not making arithmetic operations for Taking the risk of repeating myself, I'm against such change, it should be either done in Base or not done at all here. |
Good point @mschauer, I had forgotten about that. This is not exclusive to this PR, though -- comparison operators are broken for all Irrationals (and I've been meaning to submit a fix for that, but haven't had the time yet). Until the inequality operators are fixed for Irrationals in general, I don't think it's unreasonable to ignore them in Tau.jl for now. |
@giordano I understand. I was hoping we could get this merged for Tau day, but I guess it'll have to wait for next year. I'll propose changes to Base before insisting further on this. |
@waldyrious Thanks, I think that is a good idea. |
Anyway a new version of Tau.jl can still be tagged today, there have been quite some changes and fixes since last version ;-) |
This is done using the old method signature syntax, to remain compatible with 0.5
Good point, @giordano. I'll go ahead and tag a new version. Hopefully we can get it merged to METADATA.jl still today :) |
I actually kinda like the proposal to have ==(x::Irrational, y::T) where {T<:AbstractFloat} = T(x) == y
==(x::T, y::Irrational) where {T<:AbstractFloat} = x == T(y) but if that never ends up in Base, then I'd argue that you just want to warn people that julia> τ == 2π
false is the wrong comparison to make and instead they should do the comparison julia> 1τ == 2π
true |
I'll close this PR as it is quite old, has conflicts with the main branch, and uses outdated syntax. Regarding the proposed change, IMO Tau should be consistent with base, and the policy there hasn't changed (I think this policy is reasonable). Apart from the checks julia> 1τ == 2π
true or julia> Float64(τ) == 2π
true based on julia> using IrrationalConstants
julia> τ == twoπ
true Both constants are even identical objects 🙂 |
Not sure why I was focused on overriding
*
all this time. Writing the tau-2pi-equality.md document helped me get a better grasp of the problem, and I realized that adding custom methods for==
not only makes more sense, but is also simpler -- and type-stable :)