Cyan
June 13, 2025, 9:25am
1
I wrote these two functions
function test(;e::Float64)
return e^2
end
function test(;e::Int)
return e*2
end
I obtain the right answer when test(1.)
or test(1)
, but the test(e=1.)
returns an error of:
TypeError: in keyword argument e, expected Int64, got a value of type Float64
What is wrong with the test(e=1.)
?
Keyword arguments do not participate in dispatch. So, when you define the second method, the first one is overwritten (as it has the same signature, disregarding keyword arguments)
7 Likes
These aren’t two functions: you’re overwriting the only method of the single function test
because keyword arguments don’t participate to dispatch.
1 Like
If you want to dispatch on keyword, you can use some kind of barrier function :
test(;e) = _test(e)
function _test(e::Float64)
return e^2
end
function _test(e::Int)
return e*2
end
julia> test(e=1)
2
julia> test(e=1.)
1.0
8 Likes
There’s also the very nice KeywordDispatch.jl package.
2 Likes
Is this really true? The following 10-year old issue still applies to Julia 1.11:
opened 07:55AM - 30 Dec 14 UTC
bug
docs
needs decision
types and dispatch
keyword arguments
correctness bug ⚠
So this is an issue that I find after figuring out how the keyword arguments are… currently implemented in Julia. It will probably not be an issue anymore if #2773 is implemented.
The document on methods says
> Methods are dispatched based only on positional arguments, with keyword arguments processed after the matching method is identified.
However, method dispatch actually behaves differently when doing a function call with or without keyword arguments. i.e.
``` julia
julia> function f(::Integer)
2
end
f (generic function with 1 method)
julia> function f(::Number; kw...)
1
end
f (generic function with 2 methods)
julia> f(1)
2
julia> f(1; a = 2)
1
```
What happens here is that `f.env.kwsorter` only has one method defined and therefore when calling with keyword argument, `f(::Integer)` does not participate in method dispatch.
IMHO, there are several possible ways to fix it,
1. Fix the document to include this behavior. This should be the easiest fix but will probably make the whole keyword argument/optional argument/multiple dispatch more confusing especially for someone who does not know how it all works behind the scene. (It's already quite confusing/surprising that anonymous function does not support keyword argument for someone (like me) that expects python-like keyword argument implementation.)
2. Having an entry (that just throw an error) in `env.kwsorter` even for methods that does not take keyword arguments. This can also avoid the following confusing abuse of overriding method
``` julia
julia> function f(::Number; kw...)
1
end
f (generic function with 1 method)
julia> function f(::Number)
2
end
f (generic function with 1 method)
julia> f(1)
2
julia> f(1; a = 2)
1
```
This is probably the easiest way to fix the code and is consistent with the best long term behavior.
3. Fix #2773 and let the method themselves handle keyword argument dispatch. Since #2773 is on `1.0` milestone, hopefully this will be eventually be implemented.
2 Likes