Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this list comprehension return an Array{Any,1} instead of an Array{Symbol,1}?

When I try to create an Array with a list comprehension, it results in an Array{Any, 1} even if I encode all the elements to "symbol":

julia> u_col_names=[symbol("user_id"), symbol("age"), symbol("sex"), symbol("occupation"), symbol("zip_code")]
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code 

julia> col_names=["user_id", "age", "sex", "occupation", "zip_code"]
5-element Array{ASCIIString,1}:
 "user_id"   
 "age"       
 "sex"       
 "occupation"
 "zip_code"  

julia> u_col_names=[symbol(col_names[i]) for i in 1:size(col_names)[1]]
5-element Array{Any,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code 

Why does that last list comprehension return an Array{Any, 1} instead of an Array{Symbol, 1}? Note that the following does return an Array{Symbol, 1}:

julia> u_col_names=[symbol("col_names$i") for i in 1:size(col_names)[1]]
5-element Array{Symbol,1}:
 :col_names1
 :col_names2
 :col_names3
 :col_names4
 :col_names5

Interestingly, so does the following:

julia> col_names[1]
"user_id"

julia> symbol(col_names[1])
:user_id

julia> [symbol(col_names[1]), symbol(col_names[2])]
2-element Array{Symbol,1}:
 :user_id
 :age    

What am I missing?

like image 458
ajkl Avatar asked Dec 23 '14 22:12

ajkl


1 Answers

According to this discussion in the issue tracker of the JuliaLang/julia repo on GitHub, the problem seems to stem from a deficiency of Julia's type-inference system. Jeff Bezanson (one of the Julia writers and maintainers) left a relevant comment in another discussion:

This behavior is actually expected at the moment. Since [col_names] is global, it might change anywhere so we can't assume we know its type. This is overly pessimistic, but it's hard to come up with a rule that would let us do better.

Surprisingly, perhaps (as observed by John Myles White), the type is correctly inferred if those operations are carried out inside a function:

julia> function fun()
         col_names=["user_id", "age", "sex", "occupation", "zip_code"]
         return u_col_names=[symbol(item) for item in col_names]
       end
fun (generic function with 1 method)

julia> fun()
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code

As an alternative to your list comprehension, you can use map(symbol, <Array{T,1}>), which does return an Array{Symbol,1}, even at the global scope:

julia> col_names=["user_id", "age", "sex", "occupation", "zip_code"]
5-element Array{ASCIIString,1}:
 "user_id"   
 "age"       
 "sex"       
 "occupation"
 "zip_code"  

julia> map(symbol, col_names)
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code 
like image 140
jub0bs Avatar answered Sep 30 '22 13:09

jub0bs