Constructors for parameterized arrays


#1

Trying to code the generation of an array as a constructor, for example,

Vector{Float64}(f::Function, n::Int) = [f(2*pi*(k-1)/n) for k in 1:n]

gives a WARNING: static parameter Float64 does not occur ... and, of course, for example

Vector{Float64}(sin, 16)

doesn’t work.

Yes, there are zillions of other ways to do this in Julia, but I’m just wondering, how comes that Base.Vector{Float64}(n::Int) is working (it is obviously not implemented in pure Julia?)?

BTW, after the first try in my REPL

Vector{Float64}(3) does not work any more. So trying to overload the Array constructor in this (faulty) manner seems to do more serious damage than being just not callable.

(This is Julia 0.62, Fedora 27)


#2
julia> (::Type{Vector{Float64}})(f::Function, n::Int) = [f(2*pi*(k-1)/n) for k in 1:n]

julia> Vector{Float64}(sin, 4)
4-element Array{Float64,1}:
  0.0        
  1.0        
  1.22465e-16
 -1.0

#3

Ah, thanks. Probably also Base.Vector{Float64}(n::Int) is then implemented similarly.

My “BTW” remains. Rephrased, should the damage by trying to overload constructors the wrong way be avoided, e.g. by throwing an error instead of just a warning?


#4

It works for me:

julia> (::Type{Vector{Float64}})(f::Function, n::Int) = [f(2*pi*(k-1)/n) for k in 1:n]

julia> Vector{Float64}(sin, 4)
4-element Array{Float64,1}:
  0.0        
  1.0        
  1.22465e-16
 -1.0        

julia> Vector{Float64}(4)
4-element Array{Float64,1}:
 6.90402e-310
 6.90401e-310
 6.90401e-310
 0.0

The general advice is to not overload types that you don’t own. (See e.g. https://docs.julialang.org/en/latest/manual/style-guide/#Avoid-type-piracy-1). If you do, you may run into things like
https://github.com/JuliaLang/julia/issues/20945
https://github.com/JuliaLang/julia/issues/22132
https://github.com/JuliaLang/julia/issues/23605
https://github.com/JuliaLang/julia/issues/21944
https://github.com/JuliaLang/julia/issues/24078
https://github.com/JuliaLang/julia/issues/24122
https://github.com/JuliaLang/julia/issues/25208
https://github.com/JuliaLang/julia/issues/25740


#5

Works now for me, too.

Sorry for the false alarm. I still have the non-working Vector{Float64}(3) in the terminal buffer, but can’t reproduce it any more. Something else way before must have damaged my REPL session.

Thanks for the advice. The planned use is having as first parameter a type that I own, i.e. calling the constructor like:

floatdata=Vector{Float64}(h::Handle_to_nonfloat_data, ... )

Perhaps not too bad then, but certainly a matter of taste.


#6

I think that after the 0.7 deprecations are removed, this will be written as:

Vector{Float64}(f::Function, n::Int) = ...

which is nicer.


#7

Yes, nicer