> If you don't want to specialize on the length of the array why include it in 
> the type at all?

I built a HAMT using normal Julia arrays and found that the extra size
and extra pointer hop made them around 2x larger and 4x slower than
the totally naive Rust equivalent. (If you want excruciating amounts
of detail, see https://github.com/jamii/imp/blob/master/diary.md#baseline).
I'm now trying to implement fixed-length mutable arrays, much like
https://github.com/JuliaLang/julia/issues/12447

type NArray{N,T}
  contents::NTuple{N,T}
end

If I take the size out it will just box the ntuple.

I can work around the constructor. I'm more interested in
understanding how ANY affects variance so I know in what cases I can
use it:

julia> NTuple{4, Int64} <: NTuple{ANY, Int64}
true
julia> Hamt.NArray{4,Int64} <: Hamt.NArray{ANY,Int64}
true

julia> Type{NTuple{4,Int64}} <: Type{NTuple{ANY,Int64}}
true
julia> Type{Hamt.NArray{4,Int64}} <: Type{Hamt.NArray{ANY,Int64}}
false

julia> Tuple{NTuple{4,Int64}} <: Tuple{NTuple{ANY,Int64}}
true
julia> Tuple{Hamt.NArray{4,Int64}} <: Tuple{Hamt.NArray{ANY,Int64}}
true

julia> Vector{NTuple{4,Int64}} <: Vector{NTuple{ANY,Int64}}
true
julia> Vector{Hamt.NArray{4,Int64}} <: Vector{Hamt.NArray{ANY,Int64}}
false

>> julia> arr = Hamt.NArray{10, Int64}()
>> ERROR: MethodError: `convert` has no method matching
>> convert(::Type{Hamt.NArray{10,Int64}})
>> This may have arisen from a call to the constructor
>> Hamt.NArray{10,Int64}(...),
>> since type constructors fall back to convert methods.
>> Closest candidates are:
>>   convert{T}(::Type{T}, ::T)
>>   Hamt.NArray{N,T}(, ::Any)
>>   call{T}(::Type{T}, ::Any)
>>  in call at essentials.jl:57
>>
>> julia> arr = Hamt.Array{Int64}()
>> ERROR: argument is an abstract type; size is indeterminate
>>  in call at /home/jamie/code/imp/src/Hamt.jl:23
>>
>> I have this doing exactly what I want with the bare types eg:
>>
>> Base.getindex{T}(narray::NArray{ANY,T}, ix::Integer)
>>
>> I'm just struggling getting the same behaviour from the constructor
>> because of the way Type varies.
>
>
> So one issue here is that using ANY like this doesn't mean what you want it
> to – it means that the first parameter of  NArray is the literal value ANY.
> So when you write call{T}(t::Type{Array{T}}) it literally means
> call{T}(t::Type{NArray{ANY,T}}) – which is not what you want. Instead, you'd
> want a typealias like this:
>
> typealias TArray{T,n} NArray{n,T}
>
> call{T}(t::Type{TArray{T}}) = ...
>
>
> But I'm getting a little confused about what you're trying to accomplish
> with that type parameter for the number of elements in the first place.

On 8 January 2016 at 18:23, Stefan Karpinski <ste...@karpinski.org> wrote:
> On Fri, Jan 8, 2016 at 1:12 PM, 'Jamie Brandon' via julia-users
> <julia-users@googlegroups.com> wrote:
>>
>> > Yes, it's like any other parametric type that way.
>>
>> Are tuples treated specially? eg:
>
>
> Yes, tuples types are covariant while everything else is invariant.
>
>> > ANY is a hack to let you hint to the compiler that it should not
>> > specialize a method on an argument.
>>
>> That's exactly what I'm trying to achieve. I really don't want my
>> array functions to specialize on the length of the array :)
>
>
> If you don't want to specialize on the length of the array why include it in
> the type at all?
>
>>
>> > Currently you have to use a typealias...
>>
>> I'm not having any luck with this.
>>
>> typealias Array{T} NArray{ANY,T}
>>
>> call{T}(t::Type{Array{T}}) = begin
>>   tp = pointer_from_objref(t)
>>   size = sizeof(t)
>>   ...
>> end
>>
>> julia> arr = Hamt.NArray{10, Int64}()
>> ERROR: MethodError: `convert` has no method matching
>> convert(::Type{Hamt.NArray{10,Int64}})
>> This may have arisen from a call to the constructor
>> Hamt.NArray{10,Int64}(...),
>> since type constructors fall back to convert methods.
>> Closest candidates are:
>>   convert{T}(::Type{T}, ::T)
>>   Hamt.NArray{N,T}(, ::Any)
>>   call{T}(::Type{T}, ::Any)
>>  in call at essentials.jl:57
>>
>> julia> arr = Hamt.Array{Int64}()
>> ERROR: argument is an abstract type; size is indeterminate
>>  in call at /home/jamie/code/imp/src/Hamt.jl:23
>>
>> I have this doing exactly what I want with the bare types eg:
>>
>> Base.getindex{T}(narray::NArray{ANY,T}, ix::Integer)
>>
>> I'm just struggling getting the same behaviour from the constructor
>> because of the way Type varies.
>
>
> So one issue here is that using ANY like this doesn't mean what you want it
> to – it means that the first parameter of  NArray is the literal value ANY.
> So when you write call{T}(t::Type{Array{T}}) it literally means
> call{T}(t::Type{NArray{ANY,T}}) – which is not what you want. Instead, you'd
> want a typealias like this:
>
> typealias TArray{T,n} NArray{n,T}
>
> call{T}(t::Type{TArray{T}}) = ...
>
>
> But I'm getting a little confused about what you're trying to accomplish
> with that type parameter for the number of elements in the first place.

Reply via email to