0
votes

In Julia am I allowed to create & use static fields? Let me explain my problem with a simplified example. Let's say we have a type:

type Foo
  bar::Dict()
  baz::Int
  qux::Float64
  function Foo(fname,baz_value,qux_value)
     dict = JLD.load(fname)["dict"] # It is a simple dictionary loading from a special file
     new(dict,baz_value,quz_value)
  end
end

Now, As you can see, I load a dictionary from a jld file and store it into the Foo type with the other two variables baz and qux_value. Now, let's say I will create 3 Foo object type.

vars = [ Foo("mydictfile.jld",38,37.0) for i=1:3]

Here, as you can see, all of the Foo objects load the same dictionary. This is a quite big file (~10GB)and I don't want to load it many times. So, I simply ask that, is there any way in julia so that, I load it just once and all of there 3 types can reach it? (That's way I simply use Static keyword inside the question)

For such a simple question, my approach might look like silly, but as a next step, I make this Foo type iterable and I need to use this dictionary inside the next(d::Foo, state) function.

EDIT

Actually, I've found a way right now. But I want to ask that whether this is a correct or not.

Rather than giving the file name to the FOO constructor, If I load the dictionary into a variable before creating the objects and give the same variable into all of the constructors, I guess all the constructors just create a pointer to the same dictionary rather than creating again and again. Am I right ?

So, modified version will be like that:

 dict = JLD.load("mydictfile.jld")["dict"]
 vars = [ Foo(dict,38,37.0) for i=1:3]

By the way,I still want to hear if I do the same thing completely inside the Foo type (I mean constructor of it)

1

1 Answers

1
votes

You are making the type "too special" by adding the inner constructor. Julia provides default constructors if you do not provide an inner constructor; these just fill in the fields in an object of the new type.

So you can do something like:

immutable Foo{K,V}
    bar::Dict{K,V}
    baz::Int
    qux::Float64
end

dict = JLD.load("mydictfile.jld")["dict"]
vars = [Foo(dict, i, i+1) for i in 1:3]

Note that it was a syntax error to include the parentheses after Dict in the type definition.

The {K,V} makes the Foo type parametric, so that you can make different kinds of Foo type, with different Dict types inside, if necessary. Even if you only use it for a single type of Dict, this will give more efficient code, since the type parameters K and V will be inferred when you create the Foo object. See the Julia manual: http://docs.julialang.org/en/release-0.5/manual/performance-tips/#avoid-fields-with-abstract-containers

So now you can try the code without even having the JLD file available (as we do not, for example):

julia> dict = Dict("a" => 1, "b" => 2)

julia> vars = [Foo(dict, i, Float64(i+1)) for i in 1:3]
3-element Array{Foo{String,Int64},1}:
 Foo{String,Int64}(Dict("b"=>2,"a"=>1),1,2.0)
 Foo{String,Int64}(Dict("b"=>2,"a"=>1),2,3.0)
 Foo{String,Int64}(Dict("b"=>2,"a"=>1),3,4.0)

You can see that it is indeed the same dictionary (i.e. only a reference is actually stored in the type object) by modifying one of them and seeing that the others also change, i.e. that they point to the same dictionary object:

julia> vars[1].bar["c"] = 10
10

julia> vars
3-element Array{Foo{String,Int64},1}:
 Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),1,2.0)
 Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),2,3.0)
 Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),3,4.0)