To clarify I'm looking for the paramaterized types behave consistently with 
non paramaterised types. That is not the case at the moment.

abstract x
type a <: x end
type b <: x end
type c <: x end
typeof( [ a(),b(),c() ]) # Array{x,1}

If I have paramaterized types with no common super class then Any would 
seem to be a reasonable answer given the current state of the language. 
If the language is extended to support Wow{ Int64,_ } and Wow{ _, Int64 } 
etc then I can see the argument to collapse to common types.  


On Wednesday, April 1, 2015 at 3:55:42 PM UTC-4, Jeff Bezanson wrote:
>
> I think in this case we want a union-free join. Otherwise the type 
> could be as big as the result value. 
>
> I also think many people would find it surprising if 
>
> typejoin(Wow{X,X}, Wow{Y,Y}) = Wow 
>
> but 
>
> typejoin(Wow{Int,String}, Wow{Int, Float64}) = Foo{Int} 
>
> That rule basically gives higher priority to the parameters, when I 
> would expect the type name to have higher priority. The best thing 
> would be to keep the join minimal and use Stefan's suggestion of 
> Wow{Int,_}. 
>
> On Wed, Apr 1, 2015 at 3:47 PM, Michael Francis <[email protected] 
> <javascript:>> wrote: 
> > @Jeff - I'd expect this behavior - e.g. I'd get Any or Wow{K,V} if there 
> > were no common super type. The other option would be to generate a 
> union( 
> > Wow(W,X), Wow{Y,Y} ) in those cases ... not sure of the penalty of that 
> > though. In the example I gave I'd expect Foo{Int64} as this is a common 
> > super type. 
> > 
> > On Wednesday, April 1, 2015 at 2:55:21 PM UTC-4, Stefan Karpinski wrote: 
> >> 
> >> I was actually arguing in the other direction – if leading type 
> parameters 
> >> match, narrow those in the typejoin. That would make 
> >> typejoin(Woo{Int,Int},Woo{Int,Float64}) == Woo{Int}. You could also do 
> that 
> >> for non-leading type parameters but that seems less obvious somehow. 
> That 
> >> would mean that typejoin(Woo{Int,Int},Woo{Float64,Int}) == Woo{*,Int} 
> where 
> >> we don't currently have an input syntax for that last type (but we can 
> >> create it using a type alias). 
> >> 
> >> On Wed, Apr 1, 2015 at 2:16 PM, Jeff Bezanson <[email protected]> 
> wrote: 
> >>> 
> >>> Yes, arguably typejoin should just walk up the hierarchy and not try 
> >>> to do fancier joins. However if there are no parameters in common, 
> >>> e.g. 
> >>> 
> >>> a = Wow{W, X}() 
> >>> b = Wow{Y, Z}() 
> >>> 
> >>> then the result would be Any. 
> >>> 
> >>> On Wed, Apr 1, 2015 at 11:45 AM, Stefan Karpinski <
> [email protected]> 
> >>> wrote: 
> >>> > Arguably typejoin should do that. 
> >>> > 
> >>> > On Wed, Apr 1, 2015 at 11:35 AM, Michael Francis <[email protected]> 
>
> >>> 
> >>> > wrote: 
> >>> >> 
> >>> >> In this instance I'm happy to have the abstract type as the 
> promoted 
> >>> >> type. 
> >>> >> E.g. I would like to see this be Array{Foo{Int64},1} and not 
> >>> >> Array{Foo{K},1} 
> >>> >> Can I satisfy this with a promote rule ? 
> >>> >> 
> >>> >> On Wednesday, April 1, 2015 at 11:29:08 AM UTC-4, Stefan Karpinski 
> >>> >> wrote: 
> >>> >>> 
> >>> >>> This is computed by the promote_type and typejoin functions 
> defined 
> >>> >>> in 
> >>> >>> promotion.jl: 
> >>> >>> 
> >>> >>> https://github.com/JuliaLang/julia/blob/master/base/promotion.jl 
> >>> >>> 
> >>> >>> 
> >>> >>> promote_type tries to find a single concrete type to convert a 
> >>> >>> collection 
> >>> >>> of types to. As a fallback, if it can't do that, it calls typejoin 
> on 
> >>> >>> the 
> >>> >>> types, which walks up the type hierarchy and tries to find a 
> common 
> >>> >>> abstract 
> >>> >>> supertype of its arguments. Since these types don't have any 
> >>> >>> promote_rule 
> >>> >>> methods, all examples fall back on typejoin, which exhibits the 
> >>> >>> behavior 
> >>> >>> you're seeing here: 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a)) 
> >>> >>> Wow{Int64,Int64} 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a),typeof(b)) 
> >>> >>> Wow{K,V} 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a),typeof(c)) 
> >>> >>> Foo{Int64} 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a),typeof(b),typeof(c)) 
> >>> >>> Foo{Int64} 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a),typeof(c),typeof(b)) 
> >>> >>> Foo{Int64} 
> >>> >>> 
> >>> >>> julia> typejoin(typeof(a),typeof(b),typeof(c),typeof(d)) 
> >>> >>> Foo{K} 
> >>> >>> 
> >>> >>> 
> >>> >>> One way to hook into this system and get different results is to 
> >>> >>> define 
> >>> >>> promote_rule methods to determine what "wins" when you promote 
> >>> >>> different Wow 
> >>> >>> and Foo types together. For example, you could define this 
> (requires 
> >>> >>> a 
> >>> >>> restart dues to #265): 
> >>> >>> 
> >>> >>> Base.convert{K,V}(::Type{Wow{K,V}}, x::Wow) = Wow{K,V}() 
> >>> >>> 
> >>> >>> Base.promote_rule{K1,V1,K2,V2}(::Type{Wow{K1,V1}}, 
> >>> >>> ::Type{Wow{K2,V2}}) = 
> >>> >>>     Wow{promote_type(K1,K2),promote_type(V1,V2)} 
> >>> >>> 
> >>> >>> 
> >>> >>> After that [a, b] constructs an Array{Wow{Int64,Float64},1} 
> instead 
> >>> >>> of an 
> >>> >>> Array{Wow,1}. The conversion method is a bit odd here since Wow 
> >>> >>> doesn't have 
> >>> >>> any fields, but you would do the appropriate conversions if there 
> >>> >>> were 
> >>> >>> fields. If there's some appropriate way to pick a common type 
> between 
> >>> >>> Wow 
> >>> >>> and Foo objects, that can also have promote_rules. 
> >>> >>> 
> >>> >>> 
> >>> >>> On Wed, Apr 1, 2015 at 11:02 AM, Michael Francis <
> [email protected]> 
> >>> >>> wrote: 
> >>> >>>> 
> >>> >>>> If I run the following, I get the results show to the right (in 
> >>> >>>> comments), it appears array construction fails to raise to the 
> >>> >>>> common 
> >>> >>>> parent type under certain conditions, is there a way round this? 
> >>> >>>> Alternatively where is this code implemented ? 
> >>> >>>> 
> >>> >>>> abstract Foo{K} 
> >>> >>>> type Wow{K,V} <: Foo{K} end 
> >>> >>>> type Bar{K,V} <: Foo{K} end 
> >>> >>>> 
> >>> >>>> a = Wow{Int64, Int64}() 
> >>> >>>> b = Wow{Int64, Float64}() 
> >>> >>>> c = Bar{Int64, Int64}() 
> >>> >>>> d = Bar{Int64, String}() 
> >>> >>>> 
> >>> >>>> println( "******" ) 
> >>> >>>> println( typeof( [ a ]))          #Array{Wow{Int64,Int64},1} 
> >>> >>>> println( typeof( [ a, b ]))       #Array{Wow{K,V},1} 
> >>> >>>> println( typeof( [ a, c ]))       #Array{Foo{Int64},1} 
> >>> >>>> println( typeof( [ a, b, c ]))    #Array{Foo{Int64},1} 
> >>> >>>> println( typeof( [ a, c, b ]))    #Array{Foo{Int64},1} 
> >>> >>>> println( typeof( [ a, b, c, d ])) #Array{Foo{K},1} 
> >>> >>> 
> >>> >>> 
> >>> > 
> >> 
> >> 
> > 
>

Reply via email to