Although in this case - I'm digging into the 'standard' interface provided 
by DataType, but I agree this does not seem correct. I'm going to submit a 
pull request so that the methods for assoitaive for keytype and valtype are 
exported which resolves this specific issue. The type stable generated 
function may not be a bad idea to have in the toolkit. 

On Thursday, September 3, 2015 at 10:36:27 AM UTC-4, Jarrett Revels wrote:
>
> Though how would one correctly access the 'nth' elements type ?  
>> It brings up a question regarding parameterized types, how should (or 
>> should) one access/refer to the parameters of the type rather than an 
>> instance. It seems like a bad (queezy) practice to dig into the parameters 
>> of a type?
>
>
> It's generally bad practice to access fields of objects that aren't 
> "yours." In the case of the keytype function you defined, for example, it 
> causes type instability. The more Julian (and type stable way) to define 
> such a function is:
>
>     keytype{K,V}(::Type{Dict{K,V}}) = K
>     keytype(dict::Dict) = keytype(typeof(dict))
>
> If you *really* need a general, type stable way to access the nth 
> parameter of a type, your best bet will probably be doing something like 
> this:
>
>    @generated function getparam{T,n}(::Type{T}, ::Type{Val{n}})
>        P = T.parameters[n]
>        return :($P)
>    end
>
> Though be warned: naive callers of this method might call it in a type 
> unstable manner anyway by passing the index "n" from the value domain 
> rather than the type domain.
>
> Best,
> Jarrett
>
> On Thursday, September 3, 2015 at 10:04:22 AM UTC-4, Michael Francis wrote:
>>
>> I will likely do so, it's quite a common action to take. 
>>
>> Fortunately with typeof( ( 1,2 ) ) == Tuple{Int64,Int64} there is a 
>> significantly greater consistency in 0.4 vs 0.3 
>>
>> Though how would one correctly access the 'nth' elements type ?  
>>
>> It brings up a question regarding parameterized types, how should (or 
>> should) one access/refer to the parameters of the type rather than an 
>> instance. It seems like a bad (queezy) practice to dig into the parameters 
>> of a type?
>>
>> On Thursday, September 3, 2015 at 9:41:18 AM UTC-4, Tim Holy wrote:
>>>
>>> base/dict.jl defines keytype and valtype, but they are not exported. You 
>>> could 
>>> file a pull request that exports them (it would be a 2-line patch, 
>>> though you 
>>> might want to add a test to make sure they stay exported). 
>>>
>>> --Tim 
>>>
>>> On Thursday, September 03, 2015 06:37:02 AM Michael Francis wrote: 
>>> > In the short term I have defined the following in the offending 
>>> package for 
>>> > v0.4 only 
>>> > 
>>> > function keytype( dict ) 
>>> >  return eltype( dict ).parameters[1] 
>>> > end 
>>> > 
>>> > I agree that a standard protocol of accessing the key and value types 
>>> of a 
>>> > pair / associative is the way to go. 
>>> > 
>>> > On Thursday, September 3, 2015 at 9:31:39 AM UTC-4, Matt Bauman wrote: 
>>> > > Oh man that's tricky.  The trouble is that you're effectively saying 
>>> > > `Pair{Symbol,Int}[1]`, which is the syntax for a typed array: 
>>> > > Pair{Symbol,Int}[:x=>1, :y=>2].  One way around this is to define: 
>>> > > 
>>> > > keytype{A,B}(::Type{Pair{A,B}}) = A 
>>> > > valuetype{A,B}(::Type{Pair{A,B}}) = B 
>>> > > pairtypes{A,B}(::Type{Pair{A,B}}) = (A,B) 
>>> > > 
>>> > > If you need this to work on 0.3, too, you can easily make these 
>>> functions 
>>> > > work for the old-style Tuples, too. 
>>> > > 
>>> > > On Thursday, September 3, 2015 at 9:06:30 AM UTC-4, Michael Francis 
>>> wrote: 
>>> > >> Incidentally 
>>> > >> 
>>> > >> eltype( Pair{String,Float64} ) 
>>> > >> 
>>> > >> gives Any, that seems slightly strange as well . 
>>> > >> 
>>> > >> On Thursday, September 3, 2015 at 9:02:33 AM UTC-4, Michael Francis 
>>> wrote: 
>>> > >>> julia> eltype( Dict( :x => 1, :y => 2 ) )[1] 
>>> > >>> ERROR: MethodError: `convert` has no method matching 
>>> convert(::Type{Pair 
>>> > >>> {Symbol,Int64}}, ::Int64) 
>>> > >>> This may have arisen from a call to the constructor 
>>> Pair{Symbol,Int64 
>>> > >>> }(...), 
>>> > >>> since type constructors fall back to convert methods. 
>>> > >>> 
>>> > >>> Closest candidates are: 
>>> > >>>   Pair{A,B}(::Any, ::Any) 
>>> > >>>   call{T}(::Type{T}, ::Any) 
>>> > >>>   convert{T}(::Type{T}, ::T) 
>>> > >>>   
>>> > >>>  in getindex at array.jl:167 
>>> > >>> 
>>> > >>> Is this intentional ? This breaks a package I am dependent on - I 
>>> > >>> believe the assumption was that Pair would respect the tuple API, 
>>> this 
>>> > >>> appears to not be the case ? 
>>> > >>> 
>>> > >>> collect( eltype( Dict( :x => 1, :y => 2 ) ) ) 
>>> > >>> ERROR: MethodError: `start` has no method matching 
>>> start(::Type{Pair{ 
>>> > >>> Symbol,Int64}}) 
>>> > >>> 
>>> > >>>  in collect at array.jl:255 
>>> > >>>  in collect at array.jl:262 
>>>
>>>

Reply via email to