# Kwdef and empty constructor

**URL:** <https://discourse.julialang.org/t/kwdef-and-empty-constructor/113553>\
**Category:** General Usage\
**Created:** [April 27, 2024, 3:04am UTC](https://discourse.julialang.org/t/kwdef-and-empty-constructor/113553 "2024-04-27T03:04:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 27, 2024, 3:04am UTC](https://discourse.julialang.org/t/kwdef-and-empty-constructor/113553/1 "2024-04-27T03:04:08Z")

</div>

My code has a section analogous to:

```julia
Base.@kwdef struct A
  a::Int
end
A() = A(a=1)

```

This appeared to work well (Julia 1.9.2), but when I moved my code to a local package and started using `] dev` and `Revise`, I received alarming warning messages about this code (“incremental compilation fatally broken” and others). Then I realized that the above code should not work. The kwdef constructor is a zero-argument constructor with keywords, and therefore the outer zero-argument constructor should overwrite the kwdef constructor because Julia does not dispatch on keywords. And yet the above code seems to work well — both constructors are callable — except for the warning messages about incremental compilation. So I am wondering if the above code is correct. If it is correct, why is it causing warning messages from Revise?

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 27, 2024, 4:02am UTC](https://discourse.julialang.org/t/kwdef-and-empty-constructor/113553/2 "2024-04-27T04:02:33Z")

</div>

I don’t have any insight to add about correctness, just wanted to make sure you’re aware that you can add default values directly in the `@kwdef` struct definition?

```julia
Base.@kwdef struct A
    a::Int = 1
end

```

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 28, 2024, 1:40am UTC](https://discourse.julialang.org/t/kwdef-and-empty-constructor/113553/3 "2024-04-28T01:40:18Z")

</div>

First, thanks to the previous poster for the reminder about default arguments. As for my original question, it appears I stumbled on an old open issue in Julia:

> <https://github.com/JuliaLang/julia/issues/9498>
>
> 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.

Despite the claim in the docs that multiple dispatch does not look at keyword arguments, it actually does in some circumstances. Maybe someone who understands this better than me could submit a PR to clarify the docs.
