Best way to declare a structure field that could be a function or a number

Hello,
I’m currently writing a PDE solver in julia, and I’m wrapping the inputs in a structure in order. Among these inputs is the initial condition V0 and can be either a constant or a function.

My question is, what is the best way to write a structure with such field? I currently have the following implemented:

struct input{T,P<:AbstractFloat,O<:Signed}
    V0 :: T
     L :: P
     N :: O
end

Is this the correct approach to this use case? In this situation, the field input.V0 is always well defined:

julia> f(x) = x^2;
julia> in_1 = input(0,5.5,55);
julia> in_2 = input(f,5.5,55);
julia> typeof(in_1.V0)
Int64
julia> typeof(in_2.V0)
typeof(f)

Am I correct? Sorry for the newbie question.

Best regards,
Tiago

1 Like

Yes, that’s how it’s usually handled.

But probably it’s best to go with function-only approach to avoid special cases, i.e.

struct Input{F<:Function,P<:AbstractFloat,O<:Signed}
    V0 :: F
     L :: P
     N :: O
end

Input(V0::Number, L, N) = Input(_->V0, float(L), Signed(N))
2 Likes

Ok, so declaring the structure for the function case and then create a method to it to deal with the constant case, right? What did you mean about avoiding special cases? Sorry, I didn’t understand!

By the way, what means Input(_->V0,...)? It’s a kind of mapping or something?

Thanks!

Right, so that you don’t need to write separate codes for V0::Number and V0::Function and just assume that V0 is always a function in the code that uses the structure.

_->V0 is an anonymous function of one argument which returns V0 for any input. You may write it as x->V0 or function(x) V0 end. The underscore just shows that the argument is in fact ignored. More verbosely, the same constructor is written as

function Input(V0::Number, L, N)
    function always_V0(x)
        return V0
    end
    return Input(always_V0, float(L), Signed(N))
end
4 Likes