-
Notifications
You must be signed in to change notification settings - Fork 71
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
Lack of convert(::Interval{T}, a::Real)
#580
Comments
Thank you for the feedback! 🙂 Automatic conversion/promotion is dangerous since it leads to intractable silent errors. Typically, conversion issues arise when someone is relying on a code (often thought out for floating-points arithmetic) and use Also, you are right that we perform an implicit conversion by allowing mixing So,
May I ask why you need to convert the
Yes but note that interval arithmetic has specificities that often plays poorly with generic code, @Kolaru gave a nice example recently: function f(x, y)
if x == y
return 1
else
return exp(x - y)
end
end |
In my case, this is similar to symbolic computation, when I write
I am well aware of that, and this is mostly related to boolean tests. In
Forbidding conversions prevents mistakes by forbidding generic programming! This is too high of a cost. This is like forbidding cars to prevent car accidents. (Promotion is tricky, I really think it should be separated from conversion.) Practical case: a library for arithmetic circuitsOn the one hand, we have On the other hand, we have In the middle, we have some user wanting to use the latter with the former.
What can the user do? Is #568 a solution?I understand that an interval computation is only as safe and meaningful as the input is. So this is a reason to force the user to explicitly write In the end, it should be acknowledged that no type system will ensure mathematical soundness. A bit of type constraints helps a lot with stupid but common mistakes, but a some point there are diminishing returns and the cost in terms of usability and interoperability is always higher. |
When we discuss these aspects, I found that we tend to circle back to "why not just use decorated intervals". Whenever |
I know I am late to the debate (see #558), but I faced the problem of missing conversions in my project. I am implementing arithmetic circuits, so there is a type
T
for constants, typicallyInterval{Float64}
, but anything with+
and*
defined is fine. To be easily usable, we need to convert the user-provided constants (typicallyInt
) toT
. Why would this work for literally any number type on earth and fail forInterval{Float64}
?I understand that promotion is tricky, but conversion is not! The
interval
method, in the forminterval(T, a)
, is a conversion function. So the conversion function exists! It seems very wrong for a Julia library to refuse to fit the general conversion system. Is think thatconvert(::Type{Interval{T}}, a::Real) = interval(T, a)
orInterval{T}(a::Real) = interval(T, a)
are not wrong in any way.The pro of the PR #558 is “enforce the splitting between
Interval
andNumber
by preventing all conversion except betweenIntervals
”. In the future, will you also refuse to compile2*interval(0.0,1.0)
because2
is not an interval? After all, this is a kind of implicit conversion. #558 mentions a debate on the matter in #555, but I don't see it.Concrete example
I understand that you are not fond of promoting the elements of
[1, 2, 3, 4, interval(5., 6.)]
to anything. So I am fine with the current behaviorBut what about
Interval{Float64}[1, 2, 3, 4, interval(5., 6.)]
?The user is explicitly telling you he wants a conversion. Why would you force him into non-generic code? Why refusing the
convert
mechanism? It is simple and non surprising (as opposed to the promotion system).Current solutions (for me)
interval(-40)*x^4-interval(10)*x^2*y-interval(7)*y^3-interval(17)*x^2-interval(75)*x*y+interval(71)*x-interval(44)
instead of-40*x^4-10*x^2*y-7*y^3-17*x^2-75*x*y+71*x-44
. This is unsustainable. For example, I cannot copy-paste a polynomial that I computed in some computer algebra system.convert(::Type{Interval{T}}, a::Real) = interval(T, a)
and life is good for me, but we know that type piracy is not good in the long term with problems of software composability.convert(T, a)
withone(T)*a
. It works, but it is so ugly...The text was updated successfully, but these errors were encountered: