Constructors for parameterized arrays

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)

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
1 Like

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?

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
Segfault on a simple method definition · Issue #20945 · JuliaLang/julia · GitHub
Ungraceful exit when redefining Base.promote_type · Issue #22132 · JuliaLang/julia · GitHub
fatal and strange: errors when overwriting Base.<, Base.==, etc. for Int64,Float64,etc. using @eval in v0.6.0 · Issue #23605 · JuliaLang/julia · GitHub
Stack Overflow (or segfault) with: (a=>b) = (1=>2) · Issue #21944 · JuliaLang/julia · GitHub
julia REPL aborting after harmless syntax error · Issue #24078 · JuliaLang/julia · GitHub
Segfault on method error · Issue #24122 · JuliaLang/julia · GitHub
Base.getproperty with Dict type gets fatal error · Issue #25208 · JuliaLang/julia · GitHub
(::Type{T})(x::Int) where {T<:Integer} = println("crash") · Issue #25740 · JuliaLang/julia · GitHub

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.

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

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

which is nicer.

2 Likes

Yes, nicer