As Stephan has already said you most likely do not want ANY. You want Any. ANY are for those where you will call a function with a very large number of parameters and don't want to recompile the function for each call with a new type.
On Friday, January 8, 2016 at 8:00:55 PM UTC+1, Jamie Brandon wrote: > > > 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 <[email protected] > <javascript:>> wrote: > > On Fri, Jan 8, 2016 at 1:12 PM, 'Jamie Brandon' via julia-users > > <[email protected] <javascript:>> 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. >
