This really seems like a bug to me, but perhaps I’m missing some kind of obscure difference between (x, y) and x => y syntax…
import Base: ==, big
import IntervalArithmetic: Interval
struct Foo <: Real
v
end
# Necessary for printing
==(x::Foo, y::Float64) = x.v == y
big(x::Foo) = big(x.v)
# This works...
@show ("abc", Interval(Foo(0.0), Foo(1.0)))
# But this doesn't work...
@show "abc" => Interval(Foo(0.0), Foo(1.0))
What’s going on here? Why can I no haz arrow pairs?
They do different things, so I’m not sure why you expect to behave the same.
The difference is that a tuple just takes the two values as they are, in the stacktrace of the Pair constructor you can see convert(::Type{Interval{Foo}}, x::Interval{Foo}) is called, and that function fails because it internally tries to call an undefined method
I’m not aware of any other languages that make this distinction. In most languages I’ve experienced tuple is explicitly not a container of arbitrary size. That’s what distinguishes it from arrays etc. Instead it’s used as a value type. (Fwiw I’m coming from a background of Python, Haskell, Ocaml, F#, C++, Scala, etc but perhaps there are others I’m missing)
Practically speaking, Pair allows you to have the syntax => and dispatch on it without clashing with generic tuples, which are a much lower level concept. Is that enough of a distinction? As I’m trying to say, they have different semantics.
Sure, but scala also offers the x -> y syntax and just desugars it into a pair (x, y). The one thing that makes some sense to me is that tuples are covariant but Pairs are invariant. But even then I don’t understand why make Pairs invariant? Are they mutable?
The argument that this is obviously necessary in the first place seems to be invalidated by the fact that there exist so many extremely successful and well-considered language designs that don’t have separate pair and tuple types. Why add complexity?
All paratetric types in julia are invariant other than Tuple. This is largely for historical reasons as far as I understand. Tuple is a very special type that you couldn’t implement in the language itself.
Most languages don’t have multiple dispatch, so the name of a type matters less in those languages. This is only extra complexity if you come to julia with baggage from other languages. They’re just different types.
It’s like asking why Complex{Int}(1, 2) is a different type from Rational{Int}(1, 2). Sure, they’re both parametric structs with identical layouts, but they have completely different, unrelated semantic meanings.