Issue 1:
When method extension coupled with multiple dispatch mechanism, we tend to be always find ourselves in the loop of continuing adding disambiguating methods. Seriously, this is unsustainable in the long run.

Consider the following:

# suppose this is defined in base

type A <: BaseT end

+(::A, ::A) = println("A + A") # this needs to be in front
+(::A, ::BaseT) = println("A + BaseT")
+(::BaseT, ::A) = println("BaseT + A")

If someone want to write a package that extends BaseT, he will need to write

module modB
import Base: BaseT, A, +

type B <: BaseT end

# for the second type, you have to put three methods in front
# in order to reduce ambiguity
+(::A, ::B) = println("A and B")
+(::B, ::A) = println("B and A")
+(::B, ::B) = println("B and B")

+(::B, ::BaseT) = println("B and BaseT")
+(::BaseT, ::B) = println("BaseT and B")
end

If there are n subtypes of BaseT in the Base, O(n^2) disambiguating methods need to be added.

What's worse, if another one independently creates another package that extends BaseT, as below:

module modC
import Base: BaseT, A, +

type C <: BaseT end

+(::A, ::C) = println("A and C")
+(::C, ::A) = println("C and A")
+(::C, ::C) = println("C and C")

foo(::C, ::BaseT) = println("C and BaseT")
foo(::BaseT, ::C) = println("BaseT and C")
end

Then when one want to import both packages (even without using, just import), there will be ambiguities warnings about +(B, C) etc.

This issue has caused a lot of headaches for packages that try to define their own customized array types, for example:

JuliaStats/DataArrays.jl#51

JuliaStats/DataArrays.jl#77

Images and some other packages also encounter such problems.

Whereas this might be solved by continuously adding disambiguating methods, problems still exist (or even worse) when you use two or more of these packages together.

Are we going to add disambiguating methods for every pair of array types residing in different packages?

Just try the following, you will see screens full of ambiguities warnings (though just importing either one will be fine):

import DataArrays
import Images

We seriously need a fundamental solution to this.

Issue 2:
Branching this Issue off of the conversation here: #30445 (comment)

Reproducing it in this Issue:

Also, I wanted to ask: Does anyone know why signed takes x::Unsigned, but unsigned takes x::BitSigned? I'm guessing it's to prevent BigInt from falling under the reinterpret implementation. I'm currently just copying that in the ::Type{T} definitions -- does that seem reasonable?

yes -- the set difference is the presence/absence of BigInt

also Signed is an abstract type, BitSigned is a Union (in this context it is immaterial pbly).

Now that you mention it, it is a little weird, because there's nothing about the docstring for Unsigned that specifies it needs to be isprimitivetype. Nothing stops me from defining

struct WeirdUnsigned <: Unsigned
msg::String
val::UInt16
end
WeirdUnsigned(x::Int) = WeirdUnsigned("missing", UInt16(x))
Base.Signed(x::WeirdUnsigned) = signed(x.val)

julia> signed(WeirdUnsigned(4))
ERROR: bitcast: expected primitive type value for second argument
Stacktrace:
[1] reinterpret at ./essentials.jl:381 [inlined]
[2] signed(::WeirdUnsigned) at ./int.jl:162
[3] top-level scope at none:0

Of course this isn't a catastrophe: the error is sensible and one could always provide a more specialized definition. (If it returned a borked answer, that would be a genuine problem.) But of course the same could be said of Signed, and reinterpret(UInt, BigInt(4)) throws the same error.

Yeah, that's exactly the sort of thing I was referring to. Thanks for including an example.

Of course this isn't a catastrophe: the error is sensible and one could always provide a more specialized definition. (If it returned a borked answer, that would be a genuine problem.) But of course the same could be said of Signed, and reinterpret(UInt, BigInt(4)) throws the same error.

Totally, I agree. But I think that it's the inconsistency with unsigned() that's a little weird. I think either we should change this to also accept only BitUnsigned, so that you'd get the correct behavior above, OR we should loosen unsigned() to accept any kind of Signed, and just add an extra overload for BigInt, exactly as you'd have to do for WeirdUnsigned above. Does that seem reasonable to you?