Hello, should I be afraid of ::Val{_A} where _A
in this situation?
f(x, y, ::Val{:x}) = x
f(x, y, ::Val{:y}) = y
f(x, y, s :: Symbol) = f(x, y, Val(s))
@code_warntype f(1,2,:x)
Variables
#self#::Core.Const(f)
x::Int64
y::Int64
s::Symbol
Body::Int64
1 ─ nothing
│ %2 = Main.Val(s)::Val{_A} where _A
│ %3 = Main.f(x, y, %2)::Int64
└── return %3
Does that mean all my code which uses Val
is type unstable?
1 Like
Not necessarily. Val(s)
itself returns different types for different values of s
and is by definition type unstable. Val{:x}
on the other hand is a specific type.
In your example the return type of f
is type stable but the internal type instability would need a (relatively slow) dynamic dispatch to resolve, unless the function is specialized by constant propagation. If you use Val(:x)
, i.e. with a literal argument, you should see that you get a correctly inferred return type, for example.
Addendum: This is a better illustration of specialization by constant propagation for your example:
julia> g(x, y) = f(x, y, :x)
g (generic function with 1 method)
julia> @code_warntype g(1, 2)
Variables
#self#::Core.Const(g)
x::Int64
y::Int64
Body::Int64
1 ─ %1 = Main.f(x, y, :x)::Int64
└── return %1
3 Likes