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