Hello, I have a question regarding type-stability and good practices.
Let’s say I have a function/constructor that takes a params::Dict
which has some optional fields and returns a Session
struct instance with the following fields:
struct Session
previous::Union{Nothing, State}
language::Symbol
complete::Bool
And then I realise I don’t want to be manually checking fields on my types later and I would rather encode this in the type system:
abstract type AbstractSession end
struct NewSession <: AbstractSession
language::Symbol
complete::Bool
end
# complete = true
struct CompleteSession <: AbstractSession
previous::State
language::Symbol
end
# complete = false
struct ActiveSession <: AbstractSession
previous::State
language::Symbol
end
Then I can have a constructor sort of like this, analysing the params:
function Session(params::Dict)::AbstractSession
if haskey(params, :previous)
if params[:complete] == true
CompleteSession(params)
else
ActiveSession(params)
end
else
NewSession(params
end
end
which it’s obviously type-unstable due to the if-else branching.
Note: For simplicity I have ommited the step of taking a Dict
to construct an object.
So, a few questions:
- Is this an anti-pattern? Using the type system to exactly model your data seems like a desirable thing to do. On the other hand, having more types will lead to more inference down the line, so I suppose there is always a compromise.
- Is there any way around this?
- Am I overthinking this and type unstability is something you only need to care if it’s a problem?
I could imagine a helper macro that generates constructos from NamedTuple
with exactly the right arguments for each type, but this seems like just moving where the unstability happens, the Dict
would still need to be transformed into a NamedTuple
.
As I said, maybe I am overthinking this and type-unstability is sometimes a necessary compromise. The improvement on code-readability / safety probably outweighs the performance cost in my use-case.
Still, would be nice to know what are good practices, work-arounds or if have any misconceptions about performance and type-stability.
Thank you in advance!