Unions make me cry

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Unions make me cry

Alireza Nejati
When displaying methods, are there any plans to replace all the Union{}s with something a little easier to read?

Stuff like this can be a real eyesore:

rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice, ::Type{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}) at random.jl:38
Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Tomas Lycken

This specific case could be somewhat mitigated by declaring the method as rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice, ::Type{T}), since that would reduce the number of arguments (PR, maybe?) but it’s quite difficult to formulate a general solution. Reducing the current declaration to the simplified, would entail looking at all combinations of type parameters and see if they have a common ancestor that also doesn’t have any subtypes outside the set of included parameters - the number of combinations explodes quite quickly with the number of parameters…

// T

On Thursday, October 29, 2015 at 7:32:32 AM UTC+1, Alireza Nejati wrote:

When displaying methods, are there any plans to replace all the Union{}s with something a little easier to read?

Stuff like this can be a real eyesore:

rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice, ::Type{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}) at random.jl:38

Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Alireza Nejati
In reply to this post by Alireza Nejati
I would be satisfied with a solution that simply checked the entire set to see if it has a monophyletic common ancestor. And if it doesn't, have an option where full display of unions can be suppressed and maybe only expanded if the user selects a particular one.
Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Rafael Fourquet
In reply to this post by Tomas Lycken
> This specific case could be somewhat mitigated by declaring the method as
> rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of
> the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> ::Type{T}),

Then this would in turn make a call to read(read{T<:Integer}(s::IO,
::Type{T<:Integer}), which assumes that an `Integer` has a
bitstype-like layout (not compatible with e.g. BigInt). I guess this
could be done for consistency... this enable a sensible fallback in
general, but also has effects that I dislike, in this case
rand(RandomDevice(), BigInt) would produce random BigInt of size 16
bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
unexpected.

But, isn't it possible to at least print only once the Union content?
(e.g. `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice,
::Type{T})`)
Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
IntTypes}}(rd, ::Type{T})) and print that name.
Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Stefan Karpinski
This is definitely an annoyance with longer method signatures. Not sure what the best solution is though...

On Thu, Oct 29, 2015 at 7:18 AM, Rafael Fourquet <[hidden email]> wrote:
> This specific case could be somewhat mitigated by declaring the method as
> rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of
> the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> ::Type{T}),

Then this would in turn make a call to read(read{T<:Integer}(s::IO,
::Type{T<:Integer}), which assumes that an `Integer` has a
bitstype-like layout (not compatible with e.g. BigInt). I guess this
could be done for consistency... this enable a sensible fallback in
general, but also has effects that I dislike, in this case
rand(RandomDevice(), BigInt) would produce random BigInt of size 16
bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
unexpected.

But, isn't it possible to at least print only once the Union content?
(e.g. `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice,
::Type{T})`)
Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
IntTypes}}(rd, ::Type{T})) and print that name.

Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

John Myles White
I doubt there's any solution to printing out ad hoc unions in a useful way without ellipses. Always working with named unions is one heavy-handed solution that also benefits from some useful abstraction layers.

 -- John

On Oct 29, 2015, at 10:33 AM, Stefan Karpinski <[hidden email]> wrote:

This is definitely an annoyance with longer method signatures. Not sure what the best solution is though...

On Thu, Oct 29, 2015 at 7:18 AM, Rafael Fourquet <[hidden email]> wrote:
> This specific case could be somewhat mitigated by declaring the method as
> rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of
> the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> ::Type{T}),

Then this would in turn make a call to read(read{T<:Integer}(s::IO,
::Type{T<:Integer}), which assumes that an `Integer` has a
bitstype-like layout (not compatible with e.g. BigInt). I guess this
could be done for consistency... this enable a sensible fallback in
general, but also has effects that I dislike, in this case
rand(RandomDevice(), BigInt) would produce random BigInt of size 16
bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
unexpected.

But, isn't it possible to at least print only once the Union content?
(e.g. `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice,
::Type{T})`)
Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
IntTypes}}(rd, ::Type{T})) and print that name.


Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Tom Breloff
One thing that always bugs me, but may be hard to implement...  if I declare a typealias for some complex Union or parameter combination, it would be really nice if the default print/show would print that typealias name instead of the thing it is aliasing.  I guess the implementation would require storing a map from signature to typealias name and checking that map when showing.  Is this reasonable?

On Thu, Oct 29, 2015 at 1:38 PM, John Myles White <[hidden email]> wrote:
I doubt there's any solution to printing out ad hoc unions in a useful way without ellipses. Always working with named unions is one heavy-handed solution that also benefits from some useful abstraction layers.

 -- John

On Oct 29, 2015, at 10:33 AM, Stefan Karpinski <[hidden email]> wrote:

This is definitely an annoyance with longer method signatures. Not sure what the best solution is though...

On Thu, Oct 29, 2015 at 7:18 AM, Rafael Fourquet <[hidden email]> wrote:
> This specific case could be somewhat mitigated by declaring the method as
> rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of
> the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> ::Type{T}),

Then this would in turn make a call to read(read{T<:Integer}(s::IO,
::Type{T<:Integer}), which assumes that an `Integer` has a
bitstype-like layout (not compatible with e.g. BigInt). I guess this
could be done for consistency... this enable a sensible fallback in
general, but also has effects that I dislike, in this case
rand(RandomDevice(), BigInt) would produce random BigInt of size 16
bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
unexpected.

But, isn't it possible to at least print only once the Union content?
(e.g. `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice,
::Type{T})`)
Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
IntTypes}}(rd, ::Type{T})) and print that name.



Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Jameson Nash
In reply to this post by John Myles White
Talking to Jeff about this some time back (for ByteString), the problem is that you often want ByteString to be written as Union{...} so that it is easy to introspect (e.g. when it is typed at the REPL), and the condensed syntax is therefore only useful sometimes.

One thing that would help the case above is to have show thread a context argument through everywhere. This would help limit the double printing of typevars, but also could be used for show_limited and such....

I'll see if I can put together a PoC PR.

On Thu, Oct 29, 2015 at 1:38 PM John Myles White <[hidden email]> wrote:
I doubt there's any solution to printing out ad hoc unions in a useful way without ellipses. Always working with named unions is one heavy-handed solution that also benefits from some useful abstraction layers.

 -- John

On Oct 29, 2015, at 10:33 AM, Stefan Karpinski <[hidden email]> wrote:

This is definitely an annoyance with longer method signatures. Not sure what the best solution is though...

On Thu, Oct 29, 2015 at 7:18 AM, Rafael Fourquet <[hidden email]> wrote:
> This specific case could be somewhat mitigated by declaring the method as
> rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T}) instead of
> the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> ::Type{T}),

Then this would in turn make a call to read(read{T<:Integer}(s::IO,
::Type{T<:Integer}), which assumes that an `Integer` has a
bitstype-like layout (not compatible with e.g. BigInt). I guess this
could be done for consistency... this enable a sensible fallback in
general, but also has effects that I dislike, in this case
rand(RandomDevice(), BigInt) would produce random BigInt of size 16
bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
unexpected.

But, isn't it possible to at least print only once the Union content?
(e.g. `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(rd::RandomDevice,
::Type{T})`)
Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
IntTypes}}(rd, ::Type{T})) and print that name.


Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Tim Holy
I also wonder whether it would make sense to provide more tools:

mt = methods(foo!)
mtsel = filter(m->hastype(m, SparseMatrixCSC) && hastype(m, Array), mt)
print(mtsel, format=:tree)

foo!(x::A, y::B)
    A::Array{C,2}
        C::Union{Float32,Float64,Complex{D},Complex{E}}
            D::Float32
            E::Float64
    B::SparseMatrixCSC{F,G}
        F<:Any
        G<:Integer

foo!(x::A, y::B, [nmax=1])
    ...


--Tim

> >
> > This is definitely an annoyance with longer method signatures. Not sure
> > what the best solution is though...
> >
> > On Thu, Oct 29, 2015 at 7:18 AM, Rafael Fourquet <
> >
> > [hidden email]> wrote:
> >> > This specific case could be somewhat mitigated by declaring the method
> >>
> >> as
> >>
> >> > rand{T<:Union{Bool,Signed,Unsigned}}(rd::RandomDevice ::Type{T})
> >>
> >> instead of
> >>
> >> > the current rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice,
> >> >
> >> > ::Type{T}),
> >>
> >> Then this would in turn make a call to read(read{T<:Integer}(s::IO,
> >>
> >> ::Type{T<:Integer}), which assumes that an `Integer` has a
> >>
> >> bitstype-like layout (not compatible with e.g. BigInt). I guess this
> >> could be done for consistency... this enable a sensible fallback in
> >> general, but also has effects that I dislike, in this case
> >> rand(RandomDevice(), BigInt) would produce random BigInt of size 16
> >> bytes typically, as sizeof(BigIng) == 16, which is too arbitrary and
> >> unexpected.
> >>
> >> But, isn't it possible to at least print only once the Union content?
> >> (e.g.
> >> `rand{T<:Union{Bool,Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,U
> >> Int64,UInt8}}(rd::RandomDevice,>>
> >> ::Type{T})`)
> >>
> >> Or have standard names for common Unions (e.g.: `rand{T<:Union{Bool,
> >> IntTypes}}(rd, ::Type{T})) and print that name.

Reply | Threaded
Open this post in threaded view
|

Re: Unions make me cry

Alireza Nejati
In reply to this post by Alireza Nejati
Tim, that looks really great. You could also choose how deep to expand the types (for a quick check of methods, only expand it 0-1 levels deep) and whether to fully expand Unions above a certain size or abbreviate them with ellipses.