Check for undefined keyword

just stumbled upon julia’s keyword mechanism

julia> func(a; b::B) where B = a
func (generic function with 1 method)

julia> func(1)
ERROR: UndefKeywordError: keyword argument b not assigned
Stacktrace:
 [1] func(::Int64) at .\none:1
 [2] top-level scope at none:0

To me it seems like it would make more sense to let b undefined until either b or B is accessed.
There already is isundefined method which could be used to check this.

interestingly when defining both

func(a; b::B) where B = a
func(a) = a + 1

then both versions work

julia> func(1)
2
julia> func(1; b = 2)
1

however when used in a package, it prints a WARNING: Method definition ... overwritten at ... despite nothing seems overwritten

Keyword arguments don’t take part in dispatch, that’s why “Method overriden” is being printed.

As for why it “works” anyway, my best guess is that the presence of keyword arguments still gives enough information to distinguish the two versions in this case. I can’t check right now, but I bet if you define another method with a different keyword, dispatching on the method with one keyword won’t work anymore.

2 Likes

Correct; this has been a quasi-bug for a while (Keyword arguments affect methods dispatch · Issue #9498 · JuliaLang/julia · GitHub). Might change in 2.0.

As for the original question, we decided it was more useful to require the caller to pass a certain keyword argument. Otherwise we would need a lot of boilerplate if !@isdefined(b); error("you must pass b"); etc. Given that though, it looks like the error message should be reworded, something like “keyword argument b must be specified by callers”. The current behavior is also a little easier to implement, since you can’t pass around undefined variables.

7 Likes