# Is \`keyword\_argument = Val{true}\` good practice or an antipattern?

**URL:** <https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543>\
**Category:** General Usage\
**Tags:** type, precompilation, type-stability, ttfx\
**Created:** [January 31, 2022, 9:26pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543 "2022-01-31T21:26:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [January 31, 2022, 9:26pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/1 "2022-01-31T21:26:19Z")

</div>

I am seeing more and more library code that is written with keyword arguments of the form `kwarg = Val{true}` instead of `kwarg = true` or even `kwarg::Bool = true`. I know this is done in order to force specialization in precompilation which drastically improves time-to-first-X. However, I can not shake the feeling that it is plain ugly, a legibility sacrifice for a performance idiosyncrasy in Julia (that hopefully would be fixed in the future). After all, we all want a magically fast language that is as expressive as the slow magically dynamic language (I acknowledge that creating the magic is a monumental effort).

I would be grateful to hear from more advanced users of the language how they feel about this style.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [January 31, 2022, 9:34pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/2 "2022-01-31T21:34:40Z")

</div>

I probably don’t classify as an advanced user, but IMHO that should only be used as a very late stage optimization if and only if the specific function call was detected to be a bottleneck.

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [January 31, 2022, 9:49pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/3 "2022-01-31T21:49:56Z")

</div>

But even then, wouldn’t that lead to two separate styles of keyword calls? Half the libraries would use `kwarg=true` and the rest `kwarg=Val{true}`. The inconsistency is the part that bothers me the most.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [January 31, 2022, 9:52pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/4 "2022-01-31T21:52:01Z")

</div>

sounds like a bad idea to me, I think the community consensus is we shouldn’t litter code base with hacks in pursue of the performances or latency, people have faith in fixing them in releases

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [January 31, 2022, 10:06pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/5 "2022-01-31T22:06:33Z")

</div>

Likely that is a case to case discussion, but I think we all resort to hacks when those fix some important usability issue. Here and in any other language. The thing is that hacks should only be used as last resort, and likely only in internal functions, so we should not see them all around anyway.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 1, 2022, 1:26am UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/6 "2022-02-01T01:26:00Z")

</div>

I am also not the most advanced user, and my take is the following: it is okay to use `Val{true}` if you feel that your function should specialize based on that flag, I have done it in the past, in circumstances where I felt I had basically two different algorithms sharing a body of code, and that many `if` statements inside hot loops would be optimized away. However, doing it solely for precompilation does seems a little hacky, because it seems like a consequence that is too distanced from the semantics of the specific piece of code.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 1, 2022, 1:54am UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/7 "2022-02-01T01:54:26Z")

</div>

I agree this is bad style and should be avoided wherever possible. If it’s really necessary, I’d prefer the variant `kwarg = Val(true)` which produces the instance `Val{true}()` rather than the type `Val{true}` and was introduced in around Julia 1.0. At least that way, the dispatch is not based on matching `Type`s which is generally much cleaner.

In modern Julia, many (most?) of the use cases for `Val(true)` and `Val(false)` are unnecessary because the optimizer has become quite good at mixing constant propagation, type inference and inlining.

In the past, the optimizer couldn’t do this, so something as simple as

```julia
f(x, flag) = flag ? Int(x) : Float64(x)

```

couldn’t be optimized into a concrete type even when `flag` was a constant in the caller of `f`, even though `f` was inlined! For example all the way back in **Julia 0.6** :

```julia
julia> f(x, flag) = flag ? Int(x) : Float64(x)
f (generic function with 1 method)

julia> g(x) = f(x, true)
g (generic function with 1 method)

julia> @code_warntype g(1)
Variables:
  #self# <optimized out>
  x::Int64
  #temp#::Union{Float64, Int64}

Body:
  begin 
      $(Expr(:inbounds, false))
      # meta: location REPL[64] f 1
      unless true goto 6
      #temp#::Union{Float64, Int64} = x::Int64
      goto 8
      6: 
      #temp#::Union{Float64, Int64} = (Base.sitofp)(Float64, x::Int64)::Float64
      8: 
      # meta: pop location
      $(Expr(:inbounds, :pop))
      return #temp#::Union{Float64, Int64}
  end::Union{Float64, Int64}

```

There’s cases where `Val` is still necessary to force specialization based on a flag in a deeply nested computation. However in these cases a package’s public API would generally be better if it took a normal `Bool` and converted it into a `Val` for use internally, if necessary.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 1, 2022, 3:54am UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/8 "2022-02-01T03:54:21Z")

</div>

> [@c42f](#):
>
> If it’s really necessary, I’d prefer the variant `kwarg = Val(true)` which produces the instance `Val{true}()` rather than the type `Val{true}` and was introduced in around Julia 1.0.

Yeah, I agree with this. In Julia 1.x, I don’t know if there’s a reason to prefer `Val{true}` (unless if you still carry some pre 1.x codebase). On the other hand, you can loose the advantage of `Val` if you accidentally put `Val{true}` in some containers like a tuple:

```julia
julia> typeof(tuple(Val{true}))
Tuple{DataType}

julia> typeof(tuple(Val(true)))
Tuple{Val{true}}

```

The Julia compiler is often clever enough to optimize out the problem that comes with passing around the type `Val{true}`. But since the purpose of `Val` is to explicitly communicate what has to be statically known, depending on the optimizer to avoid the problem with `Val{true}` seems to be a bad idea. So, when using `Val`, I think it’s better to pass around the instance `Val(true)`.

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 1, 2022, 5:06pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/9 "2022-02-01T17:06:54Z")

</div>

I think this is **not** the reason people are using `Val{true}` today. It is not for optimizing the runtime by ensuring the compiler does something smart. Rather, I am seeing it used because it ensures pre-compilation works and import time is drastically lowered. And it seems to be used in new important libraries like [Symbolics.jl](https://symbolics.juliasymbolics.org/dev/manual/build_function/#Symbolics.build_function). Or maybe I am completely misunderstanding its purpose here?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 1, 2022, 5:29pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/10 "2022-02-01T17:29:36Z")

</div>

Would not be better to ask the package maintainers why they are doing this instead of speculating on it?

---

<div class="post-metadata">

**Author:** ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)\
**Post date:** [February 1, 2022, 5:31pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/11 "2022-02-01T17:31:12Z")

</div>

Doing this for **keyword** arguments is a bit pointless since the types of kwargs don’t participate in method dispatch: [Methods · The Julia Language](https://docs.julialang.org/en/v1/manual/methods/#Note-on-Optional-and-keyword-Arguments)

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 1, 2022, 5:38pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/12 "2022-02-01T17:38:32Z")

</div>

They do not participate in method dispatch, but they participate in what and how is being precompiled.

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 1, 2022, 5:39pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/13 "2022-02-01T17:39:14Z")

</div>

My question is not specifically about one package.

---

<div class="post-metadata">

**Author:** ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)\
**Post date:** [February 1, 2022, 5:47pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/14 "2022-02-01T17:47:47Z")

</div>

That’s kinda the point. Outside of method dispatch, the instance `Val(true)` , the type `Val{true}` and the constant `true` are just different values (and constant ones at that). So, especially in light of the continuing improvements in constant propagation, it really doesn’t make any difference for _keyword_ arguments, because it’s the same thing as propagating any other value. Types are all just a value of `Type` .

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 1, 2022, 5:53pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/15 "2022-02-01T17:53:47Z")

</div>

I am not referring to the quality of the compiled code - that would indeed be the same either way. However, from what I have read on this forum, this has an effect on whether Julia decides to **pre** -compile your code, and how long it takes to **import** your package. See the TTFX thread from last week [Taking TTFX seriously: Can we make common packages faster to load and use - #15 by Krastanov](https://discourse.julialang.org/t/taking-ttfx-seriously-can-we-make-common-packages-faster-to-load-and-use/74949/15)

---

<div class="post-metadata">

**Author:** ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)\
**Post date:** [February 1, 2022, 5:58pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/16 "2022-02-01T17:58:54Z")

</div>

As hinted at above, if you really are obsessing about making sure as much as possible gets precompiled, then it would be better to not doing anything fancy in the kwargs and just have an internal method. In other words, let the user specify a normal value and you wrap it as a `Val` singleton instance:

```julia
f(x::SomeType; kw=true) = f(x, Val(kw))

function f(x::SomeType, ::Val{true}) 
    # something to definitely precompile
end

function f(x::SomeType, ::Val{false})
    # something to definitely precompile
end

```

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 1, 2022, 6:08pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/17 "2022-02-01T18:08:35Z")

</div>

You should probably do

```julia
function f(x::SomeType, ::Val{T}) where T
    ... # code that branches on T
end

```

Otherwise you probably end with a ton of code repetition or you never needed a boolean keyword.

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [February 10, 2022, 5:42pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/18 "2022-02-10T17:42:01Z")

</div>

This (anti-)pattern makes a function, which I wrote, type-stable. What should I use as a better way?

I have a function that extract specific components from two plain vectors (state and parameters of an ODESystem-ODEProblem). The order of the components is only known after constructing the ODEProblem from the system, and I need a way to index it efficiently and conveniently by Symbols.

One version returns the plain vector and another version returns a LabelledArray to actually see the components. With a plain bool argument the result istype-unstable.

One alternative would be providing two differently named functions each returning its own result type.

Another alternative would require the use to explicitly call label\_paropt himself, but he would need to pass the position-label-information (in ProblemParSetter) twice.

```julia
function get_paropt(ps::ProblemParSetter, u0::Vector, p::Vector; label::Val{LABEL}=Val(false)) where LABEL
    v = [(first(t) == :par) ? p[last(t)] : u0[last(t)] for t in ps.optinfo]
    LABEL ? label_paropt(ps,v) : v
end

function label_paropt(ps, popt::Vector); LArray{paroptsyms(ps)}(popt); end

```

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [February 10, 2022, 7:01pm UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/19 "2022-02-10T19:01:37Z")

</div>

You will probably get very different answers depending on who you are asking. I am starting to lean to “restructure the code so that there are no functions of that kind”, but that could lead to severe code-duplication.

The next option is “write a `::Val{bool}` ‘private’ function and then just a `::Bool` ‘public’ function”, as type instability in the outer-most user-facing code probably does not matter for performance. But that fails when you are worrying about functions that users might be using in tight loops.

Which leads to “give up and use the ugly `::Val{bool}`” if the above are not an option. The compiler/language is just not yet good enough for a less hacky solution.

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [February 12, 2022, 7:31am UTC](https://discourse.julialang.org/t/is-keyword-argument-val-true-good-practice-or-an-antipattern/75543/20 "2022-02-12T07:31:41Z")

</div>

The `label::Val{LABEL}=Val(false)` hints to code smells and encourages rethinking the design.

From rethinking my specific example tells, I conclude that extracting an unlabeled or a labeled subset from the parameters are really two different usages. They warrant two different functions.

```julia
function get_paropt(ps::ProblemParSetter, u0::Vector, p::Vector) 
    v = [(first(t) == :par) ? p[last(t)] : u0[last(t)] for t in ps.optinfo]
end

function get_paropt_labeled(ps::ProblemParSetter, u0::Vector, p::Vector) 
    v = get_paropt(ps, u0, p)
    label_paropt(ps,v)
end

```
