[SOLVED] How to create an empty tuple of specific type in Julia?

Issue

This Content is from Stack Overflow. Question asked by dot64dot

How do I initialize a variable x such that typeof(x) equals Tuple{something, something}?

Specifically, I would like something to be a struct.

e.g. assume

struct myStruct
    info::Int
end

How would I create a an empty tuple x such that x is an empty tuple of type Tuple{myStruct, myStruct}?



Solution

The short answer is that you cannot create an empty tuple of type Tuple{Int,Int}. By definition, a Tuple{Int, Int} has a length of 2 and is thus not empty.

Compare this to an empty Array{Int} which can have a length of 0 and is thus empty:

julia> empty_array = Int[]
Int64[]

julia> isempty(empty_array)
true

julia> length(empty_array)
0

The long answer is it depends what you mean by "empty". Perhaps you mean something that you did not have to initialize. We can partly investigate this using a Ref. In this case the values will be whatever is resident in memory. Overall, I’m not sure what advantage this would have over just initializing the tuple as (0,0).

julia> r = Ref{Tuple{Int,Int}}()
Base.RefValue{Tuple{Int64, Int64}}((2, 139735268818544))

julia> r = Ref{Tuple{Int,Int}}()
Base.RefValue{Tuple{Int64, Int64}}((139735268745904, 139735268746800))

julia> isempty(r[])
false

It is not clear to me overall why you want an empty tuple other than as a default initial value for a default myStruct constructor.

For a default constructor, I recommend using (0,0) as the initial value:

julia> mutable struct myStruct
           info::Tuple{Int, Int}
       end

julia> myStruct() = myStruct((0,0))
myStruct

julia> myStruct()
myStruct((0, 0))

My last guess at why you might want an "empty" tuple is to avoid allocations. Creating a myStruct instance results in a 32 byte allocation. To avoid allocations, the best course of action would be to make the struct immutable. Doing so comes with a multitude of advantages such as simplified memory layout involving less pointer indirection. It also allows the compiler to make simplifying assumptions resulting in faster code.

julia> @time myStruct();
  0.000001 seconds (1 allocation: 32 bytes)

julia> struct NonAllocatingStruct
           info::Tuple{Int, Int}
       end

julia> NonAllocatingStruct() = NonAllocatingStruct((0,0))
NonAllocatingStruct

julia> @time NonAllocatingStruct()
  0.000002 seconds
NonAllocatingStruct((0, 0))


This Question was asked in StackOverflow by dot64dot and Answered by Mark Kittisopikul It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?