# Keyword argument types - what's going on?

**URL:** <https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778>\
**Category:** New to Julia\
**Created:** [February 4, 2022, 8:40am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778 "2022-02-04T08:40:49Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [February 4, 2022, 8:40am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/1 "2022-02-04T08:40:49Z")

</div>

Hey everyone,

I’m new-ish to Julia and have been loving it so far, but I just stumbled on some behavior I’m confused about when it comes to types and keyword arguments.

As per the [docs](https://docs.julialang.org/en/v1/manual/functions/), I can define a function accepting e.g. `Int` vs `Float64` to create two methods which behave differently

```julia
f(x::Int64) = x
f(x::Float64) = 2x
# f (generic function with 2 methods)

f(1) # == 1
f(1.0) # == 2.0

```

However, if I want to do the same for a keyword argument:

```julia
g(x; y::Int64) = x + y
g(x; y::Float64) = x * y
# g (generic function with 1 method)

```

it **doesn’t** create two methods that behave differently based on the type of `y`. What’s more, this throws an error:

```julia
g(2; y=1) # ERROR: TypeError: in keyword argument y, expected Float64, got a value of type Int64
g(2; y=1.0) # == 2.0

```

The same happens if I assign default values to the keyword argument:

```julia
function h(x;y::Int=1)
    ###
end

function h(x; y::Float64=1.0)
    ###
end
# h (generic function with 1 method)

```

Now, I have 2 questions:

1. why does this happen? I’m guessing it’s because both `Int` and `Float64` are subtypes of the same abstract type, but it works fine when they’re not keyword arguments.
2. How can I work around this, if I want two methods that behave differently based on the type of `y`?

Specifically, in my case I’m writing a function that creates some pseudo random events and users can either pass a `p::Float64` probability value or an `n::Int` number of events to be produced. The logic of the function is very different based on the type of the parameter, and I want them to be keyword arguments. I could put an `if` statement inside the function, but I thought multiple dispatch should be able to handle this for me!

Any help would be greatly appreciated, thank you!

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [February 4, 2022, 8:51am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/2 "2022-02-04T08:51:25Z")

</div>

It is not possible to dispatch on keyword arguments with base Julia. You might be interested in this package: [https://github.com/simonbyrne/KeywordDispatch.jl](https://github.com/simonbyrne/KeywordDispatch.jl)

---

<div class="post-metadata">

**Author:** ![trahflow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trahflow/32/30585_2.png) [@trahflow](https://discourse.julialang.org/u/trahflow)\
**Post date:** [February 4, 2022, 8:51am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/3 "2022-02-04T08:51:33Z")

</div>

Hi @FedeClaudi ,

> [@FedeClaudi](#):
>
> I’m guessing it’s because both `Int` and `Float64` are subtypes of the same abstract type

no. The type dispatch tries to always resolve to the most concrete type. If that’s not possible like here (neither is `Int64` more concrete than `Float64`, nor is the reverse true) then it would error (if those were positional arguments).

Julia explicitely does not dispatch on keyword arguments as mentiond here in the doc:  
[https://docs.julialang.org/en/v1/manual/methods/#Note-on-Optional-and-keyword-Arguments](https://docs.julialang.org/en/v1/manual/methods/#Note-on-Optional-and-keyword-Arguments)

```julia
Keyword arguments behave quite differently from ordinary positional arguments. In particular, they do not participate in method dispatch.

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 4, 2022, 8:58am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/4 "2022-02-04T08:58:18Z")

</div>

> [@FedeClaudi](#):
>
> users can either pass a `p::Float64` probability value or an `n::Int` number of events to be produced.

Then I think those two inputs should have different keyword names. If the keyword isn’t descriptive, you might as well make it a regular positional argument.

---

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [February 4, 2022, 8:58am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/5 "2022-02-04T08:58:54Z")

</div>

Ooooh I missed that @trahflow, thank you!  
It looks like [https://github.com/simonbyrne/KeywordDispatch.jl](https://github.com/simonbyrne/KeywordDispatch.jl) should do the trick, thank you @Christopher_Fisher !

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 4, 2022, 9:04am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/6 "2022-02-04T09:04:52Z")

</div>

> [@FedeClaudi](#):
>
> It looks like [GitHub - simonbyrne/KeywordDispatch.jl: Dispatch on keyword arguments](https://github.com/simonbyrne/KeywordDispatch.jl) should do the trick

I suspect that’s going about it the wrong way.

---

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [February 4, 2022, 9:08am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/7 "2022-02-04T09:08:01Z")

</div>

> [@DNF](#):
>
> Then I think those two inputs should have different keyword names

They already do?

> Blockquote I suspect that’s going about it the wrong way.

Why do you think that? Is it not Julian? Performance costs?  
The only other solution I can think of is having both `n, p` as keyword arguments to a single methods that then behaves differently based on which one is used, but I felt that it wouldn’t be the most Julian way to do this, any suggestion on how do it better?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 4, 2022, 9:09am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/8 "2022-02-04T09:09:07Z")

</div>

> [@FedeClaudi](#):
>
> They already do?

Do they, I thought you just used the name `y` for both?

> [@FedeClaudi](#):
>
> The only other solution I can think of is having both `n, p` as keyword arguments

Yes, that is what I was suggesting, though I would suggest something slightly more descriptive.

---

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [February 4, 2022, 9:11am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/9 "2022-02-04T09:11:12Z")

</div>

In the minimal example above I’ve used the same `y` name, in my code I have `n, p`.

> I would suggest something slightly more descriptive.

👍

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 4, 2022, 9:12am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/10 "2022-02-04T09:12:58Z")

</div>

Ah, ok. But I thought you wanted the same keyword name to have different behaviour depending on argument type. I guess I don’t understand how the problem arose in the first place then. Why did you need dispatch at all then?

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 4, 2022, 9:14am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/11 "2022-02-04T09:14:12Z")

</div>

> [@FedeClaudi](#):
>
> The only other solution I can think of is having both `n, p` as keyword arguments to a single methods that then behaves differently based on which one is used, but I felt that it wouldn’t be the most Julian way to do this, any suggestion on how do it better?

Yes I think t it’s better to have one method defined as e.g. `f(x; n=nothing, p=nothing)` and in the body of `f` check which argument is given by the user. In this body you can then dispatch the implementation to two different helper functions.

---

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [February 4, 2022, 9:16am UTC](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/12 "2022-02-04T09:16:45Z")

</div>

Sorry I guess how I phrased the question might have been a bit confusing.

I need:

```julia
f(...; n::Int)
f(...; p::Float64)

```

to be different methods. However, since keyword types doesn’t affect dispatch, the scond definition with `Float` overwrites the first one and calling `f(...; n=1)` gives an argument error because `n` is not in the function signature anymore.

In the example I’ve started with I’ve tried to go to the root at the problem which is that the type of the keyword argument was being ignored when defining multiple methods, and now I know that this is the case (although it’s not clear to me the reason for this in Julia).

Thanks @sijo
