Jamie, that diary of yours is great reading, btw. I'm pretty intrigued by
the mystery of why the Julia version is 2x slower. I would be very
interested in getting to the bottom of that.

On Fri, Jan 8, 2016 at 2:37 PM, Stefan Karpinski <[email protected]>
wrote:

> Setting the fix-size mutable array thing aside, one thing that's glaringly
> wrong about these examples is that even if parametric types were covariant,
> this wouldn't make sense because 4 <: Any is never going to be true because
> 4 is not a type, it's a value:
>
> julia> 4 <: Any
> ERROR: TypeError: subtype: expected Type{T}, got Int64
>  in eval at ./boot.jl:265
>
>
> The fact that you can write NTuple{Any,Int} at all seems to be a bug:
>
> julia> NTuple{Any,Int}
> ERROR: TypeError: NTuple: in parameter 1, expected Int64, got Type{Any}
>  in eval at ./boot.jl:265
>
> julia> NTuple{ANY,Int}
> NTuple{ANY,Int64}
>
>
> I'm not sure what's going on with that, but I've filed an issue: #14607
> <https://github.com/JuliaLang/julia/issues/14607>.
>
> On Fri, Jan 8, 2016 at 2:00 PM, 'Jamie Brandon' via julia-users <
> [email protected]> 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]>
>> wrote:
>> > On Fri, Jan 8, 2016 at 1:12 PM, 'Jamie Brandon' via julia-users
>> > <[email protected]> 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