Tuple with conditional entries

Is it possible create a tuple with the existence of entries conditioned on some variables?

I.e. what I want is something like

mytuple = (42 if condition1, pi condition2 )
# == (42, pi) if condition1 and condition2 are true
# == (42,) if condition1 is true and condition2 is false
# ...

I know that I could do something like

mytuple = if condition1 && condition2
    (42, pi)
elseif condition1 && !condition2
   (42,)
elseif
   ...
end

but I have quite a few conditions and possible entries in the tuple s.t. enumerating all possible combinations would get quite lengthy.

Probably a tuple is the wrong data structure in this case. Tuples are mainly good for situations in which the size (and types) of the entries are known statically (at compile time, not runtime).

What underlying problem are you trying to solve?

The use case is inside a @generated function where I want to generate different code depending on the parameters of a parametric type. See the following MWE for what I am trying to achieve:

struct MyRecord{R1,R2,R3}
    data::DataFrame
end

@generated function MyRecord{R1,R2,R3}()
    return quote
        rows = $(:(:var1 => Int[] if R1, :var2 => Float64[] if R2, :var3 => Int[] if R3))
        data = DataFrame(rows...)
        return MyRecord{R1,R2,R3}(data)
    end
end

@generated function Base.push!(records::MyRecord{R1,R2,R3}, var1, var2, var3) where {R1,R2,R3}
    return quote
        row = $(:(var1 if R1, var2 if R2, var3 if R3))
        push!(records.data, row)
    end
end

In that case, performance doesn’t matter since it is happening at compile time, so I would just do it as an array and then convert back to a tuple, e.g.:

@generated function Base.push!(records::MyRecord{R1,R2,R3}, var1, var2, var3) where {R1,R2,R3}
    rowexpr = Tuple([:var1, :var2, :var3][[R1,R2,R3]])
    return quote
        row = $rowexpr
        push!(records.data, row)
    end
end

Arrays are easier for these kinds of manipulations.

2 Likes