Excellent, thanks to you all. `similar` is what I need (this puts the burden on the type creator, which is fine by me ;-)
On Wed, 2015-04-22 at 15:43, Andreas Noack <[email protected]> wrote: > This problem is quite common in the LinAlg code. We have two type of > definitions to handle the conversion of the element types. First an idea > due to Jeff as implemented in > > https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/triangular.jl#L20 > > and > > https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/symmetric.jl#L34 > > These create maybe-aliased objects which can be problem in the destructive > linalg functions so therefore Simon Kornblith invented copy_oftype which > you can see example of here > > https://github.com/JuliaLang/julia/blob/237cdab7100b29a6769313391b1f8d2563ada06e/base/linalg/symmetric.jl#L34 > > Notice that it requires two method definitions for each type. > > 2015-04-22 8:57 GMT-04:00 Tim Holy <[email protected]>: > >> As Jeff says...this is why `similar` exists. >> >> --Tim >> >> On Wednesday, April 22, 2015 10:03:02 AM Mauro wrote: >> > Thanks Jameson and here the context: >> > >> > # Initializes an array which has a's container but b's eltype >> > function f(a::AbstractVector, b::AbstractVector) >> > Eb = eltype(b) # this is type-stable >> > Ca = typeof(a).name.primary # this is not type-stable >> > return Ca(Eb, 5) # assumes Ca supports the normal Array >> > constructor end >> > >> > The last line would probably better use copy+convert but for that I >> > still need to make Ca{Eb,1}. Note that Ca is always a leaftype and I >> > don't want to climb the type hierarchy, so I think your remark about the >> > subtypes does not apply. >> > >> > Here the typed code: >> > julia> @code_warntype f([1,2], [1.]) >> > Variables: >> > a::Array{Int64,1} >> > b::Array{Float64,1} >> > Eb::Type{Float64} >> > Ca::Type{T} # <--- >> > >> > Body: >> > begin # none, line 3: >> > Eb = Float64 # line 4: >> > Ca = >> > >> (top(getfield))((top(getfield))(typeof(a::Array{Int64,1})::Type{Array{Int64 >> > ,1}},:name)::TypeName,:primary)::Type{T} # line 5: return >> > (Ca::Type{T})(Eb::Type{Float64},5)::Any >> > end::Any >> > >> > Thanks! >> > >> > On Tue, 2015-04-21 at 22:56, Jameson Nash <[email protected]> wrote: >> > > Your question presupposes that you can write useful generic code with >> the >> > > return result, but does not provide any context on your problem. When a >> > > similar question was asked previously on the mailing list, I recall >> > > pointing out that the code the author was attempting to write was not >> > > going >> > > to function as intended. Perhaps you can provide some more context? >> > > >> > > The observation that I am making is that you cannot arbitrarily pick >> apart >> > > a type and expect everything to line up afterwards. For example, it is >> > > possible to have the following: >> > > abstract AbstractTy{A,B} >> > > type Ty1 <: AbstractTy{Int, Float64} end >> > > type Ty2{B,A} <: AbstractTy{A,B} end >> > > >> > > So you can't generically reconstruct some arbitrary subtype by some >> > > generic >> > > rearrangement of its type parameters. >> > > >> > > On Tue, Apr 21, 2015 at 4:34 PM Mauro <[email protected]> wrote: >> > >> I have a parameterized type and want to get the primary-type. For >> > >> example, I got >> > >> >> > >> a = Array{Int,2} >> > >> >> > >> is there a type-stable way to get Array? This is non-type stable: >> > >> >> > >> f(t::Type) = t.name.primary >> > >> >> > >> as the inferred return type is Type. >> > >> >> > >> This does not work: >> > >> >> > >> f{T, S}(::Type{T{S...}}) = T >> > >> >> > >> Any ideas? Thanks, M >> >>
