Array by reference

Assigning a new type out of function prevents the compiler to assign the returned-type properly.
In the example I show it just ends up returning ::Any. In my broader example it messes up within the function itself and the AST goes from 60 lines to 300!
Can you explain me why?

Furthermore, I would like to export those type definitions in another file. But if I have to define the type within the function I will end up writing same lines again and again, every time I want to use those types. This cannot be.

Thanks for the answer,
Alessio

Here is the code:


Params = Dict{String,Union{Vector{Int},Int64,String,Bool,Float64}}
function get_params()

   ##################################3
   # Plotting parameters
   ###################################
   plot_pars =Params( #type any because it has an array too
   "do_plot" => true,        # main plotting switch
   "savefigs" => true,       # whether to save resulting plots
   "do_neuronplot" => true,  # plot graphs of V and g_sra and stuff
   "plotneurons" => [1,5,8], # which neurons to plot
   "Vspike" => 0.0,          # (mV) plot spikes as having this potential
   "do_rasterplot" => true,
   "recordTime" => 5000,   #(ms) how long to record plot data for
   )
end

function get_params_correct()
   Params = Dict{String,Union{Vector{Int},Int64,String,Bool,Float64}}
   ##################################3
   # Plotting parameters
   ###################################
   plot_pars =Params( #type any because it has an array too
   "do_plot" => true,        # main plotting switch
   "savefigs" => true,       # whether to save resulting plots
   "do_neuronplot" => true,  # plot graphs of V and g_sra and stuff
   "plotneurons" => [1,5,8], # which neurons to plot
   "Vspike" => 0.0,          # (mV) plot spikes as having this potential
   "do_rasterplot" => true,
   "recordTime" => 5000,   #(ms) how long to record plot data for
   )
   a = "do_plot"
end
@code_warntype get_params()
@code_warntype get_params_correct()

This seems like a case where a struct or a named tuple would be a much better choice. You can use https://github.com/mauro3/Parameters.jl to more easily define structs holding parameters like this.

Or you can simply leave the first version of your code as-is. The fact that the compiler can’t identify the type of every field in the dict will harm performance, but the difference may be negligible if the rest of your code dominates the run time.

1 Like

Maybe also worth knowing: The ::Any complaints come from depending on a non-constant global. If you change to const Params = Dict{String,Union{Vector{Int},Int64,String,Bool,Float64}} they will go away. This is the usual way of defining an alias for a too-long-to-type type.

(I think that if the type is parametric, like Params{T} = Dict{String,T}, then const is automatic, but don’t fully trust my memory here!)

1 Like