KeywordCalls.jl

KeywordCalls makes it easy to define a method taking a NamedTuple considered as a an unordered collection of bound variables. The required redirection is done at compile time, so there's no runtime overhead.
Author cscherrer
Popularity
24 Stars
Updated Last
1 Year Ago
Started In
April 2021

KeywordCalls

Stable Dev Build Status Coverage

In Julia, the named tuples (a=1, b=2) and (b=2, a=1) are distinct. In some cases, it's convenient to define a method for each set of names, rather than each particular ordering.

KeywordCalls.jl lets us do this, and allows specification of a "preferred ordering" for each set of arguments.

On Julia 1.6, this can be done with no allocation! This is included in the unit tests. Unfortunately, the current implementation leads to allcoation in Julia 1.4 and 1.5. We hope this can be improved for better backward-compatibility, but for now we recommend using 1.6 if possible.

KeywordCalls is very light weight:

julia> @time_imports using KeywordCalls
[ Info: Precompiling KeywordCalls [4d827475-d3e4-43d6-abe3-9688362ede9f]
      0.3 ms  Compat
      0.3 ms  Tricks
      0.2 ms  KeywordCalls

@kwcall

If we define

f(nt::NamedTuple{(:b, :a)}) = println("Calling f(b = ", nt.b,",a = ", nt.a, ")")

@kwcall f(b,a)

Then

julia> f(a=1,b=2)
Calling f(b = 2,a = 1)

julia> f(b=2,a=1)
Calling f(b = 2,a = 1)

We can define a new method for any set of arguments we like, including default values. If (after the above) we also define

f(nt::NamedTuple{(:c, :a, :b)}) = println("The sum is ", sum(values(nt)))

@kwcall f(c=0,a,b)

then

julia> f(a=1,b=2)
The sum is 3

julia> f(a=1,b=2,c=3)
The sum is 6

@kwalias

It's often useful to allow multiple names to be mapped to the same interpretation. For that, we have @kwalias:

julia> using KeywordCalls

julia> @kwcall f(c=0,a,b)
f (generic function with 3 methods)

julia> @kwalias f [
       α     => a
       alpha => a
       β     => b
       beta  => b
       ]

julia> f=2=3)
The sum is 5

julia> f=2,beta=3)
The sum is 5

@kwstruct

KeywordCalls is especially powerful when used for structs. If you have

struct Foo{N,T} [<: SomeAbstractTypeIfYouLike]
    someFieldName :: NamedTuple{N,T}
end

then

julia> @kwstruct Foo(μ,σ=1)
Foo

julia> Foo=2=4)
Foo{(:μ, :σ), Tuple{Int64, Int64}}((μ = 4, σ = 2))

In MeasureTheory.jl, we use this approach to allow multiple parameterizations of a given distribution.

Related Packages

KeywordDispatch.jl is very similar. When we started KeywordCalls, it seemed we would need lots of extra dependencies to make the idea work. This motivated creating a new package instead of making a PR for KeywordDispatch. @simeonschaub helped us get away from this and simplify the implementation; it's now very light-weight, and very fast.

Required Packages