# Keyword function error inverts position of arguments?

**URL:** <https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571>\
**Category:** General Usage\
**Created:** [March 31, 2019, 8:42pm UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571 "2019-03-31T20:42:40Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [March 31, 2019, 8:42pm UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/1 "2019-03-31T20:42:40Z")

</div>

I just spend a _lot_ of time figuring out why this function here

```julia
function solve(ncgm::NeoclassicalGrowth, vp::ValueCoeffs{T};
        tol::Float64 = 1e-06, maxiter::Int = 5000, dampen::Float64 = 1,
        nskipprint::Int = 1, verbose::Bool = true) where {T <: SolutionMethod}

```

would not for all of my efforts compile. I was trying to make sense of this error message

```julia
ERROR: MethodError: no method matching #solve#14(::Float64, ::Int64, ::Int64, ::Int64, ::Bool, ::typeof(solve), ::NeoclassicalGrowth, ::ValueCoeffs{IterateOnPolicy})

```

What completely tripped me up is that the arguments don’t come in the order the funciton is defined. I would have expected `ncgm` to come first. Why is that so or what I’m getting wrong here?

---

<div class="post-metadata">

**Author:** ![aharoun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aharoun/32/6887_2.png) [@aharoun](https://discourse.julialang.org/u/aharoun)\
**Post date:** [March 31, 2019, 9:12pm UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/2 "2019-03-31T21:12:49Z")

</div>

How exactly are you calling `solve` function so that it gives this particular error?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 1, 2019, 6:45am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/3 "2019-04-01T06:45:27Z")

</div>

Please provide an MWE.

> [@Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757):
>
> Welcome to the Julia Discourse! We are enthusiastic about helping Julia programmers, both beginner and experienced. This public service announcement (PSA) outlines best practices when asking for help. Following these points makes it easier for us to help you and more likely you’ll get a prompt, useful answer. Keywords are highlighted to make it easier to refer to specific points. Choose a descriptive title that captures the key part of your question, eg “plots with multiple axes” instead of …

---

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [April 1, 2019, 7:31am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/4 "2019-04-01T07:31:47Z")

</div>

my problem is solved. there was a stupid typo `dampen::Float64 = 1` which generated that weird error. The error message is a problem though. Here is how you can generate it.

1. I downloaded this notebook and extracted all code from from it: [QuantEcon – Notes](https://notes.quantecon.org/submission/5b5f711d9cd7f00015be634f)
2. I upgraded the code (0.6) to julia 1.1 by following suggestions of v0.7. in the process i must have introduced above mistake.
3. here is my resulting [file as a gist](https://gist.github.com/floswald/25d8184e5582d8d7d6f9dc0dd8cd6f5a)
4. you can make the script work by setting `dampen::Float64 = 1.0` on [this line](https://gist.github.com/floswald/25d8184e5582d8d7d6f9dc0dd8cd6f5a#file-mwe-jl-L249)
5. if you don’t make that change, the script returns this error:

```julia
julia> include("GrowthModelSolutionMethods_jl.jl")
ERROR: LoadError: MethodError: no method matching #solve#8(::Float64, ::Int64, ::Int64, ::Int64, ::Bool, ::typeof(solve), ::NeoclassicalGrowth, ::ValueCoeffs{IterateOnPolicy,Degree{2}})
Closest candidates are:
  #solve#8(::Float64, ::Int64, ::Float64, ::Int64, ::Bool, ::Any, ::NeoclassicalGrowth, ::ValueCoeffs{T<:SolutionMethod,D} where D<:Degree) where T<:SolutionMethod at /Users/74097/Dropbox/teaching/ScPo/ScPo-CompEcon/code/notebooks/GrowthModelSolutionMethods_jl.jl:254

```

where, again, it’s really totally confusing that the order of arguments is not identical to the function defintion. in that error message, the keyword arguments are referenced first!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 1, 2019, 7:53am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/5 "2019-04-01T07:53:35Z")

</div>

Thanks for posting the script, but this is hardly a MWE 😉

I think your problem can be boiled down to

```julia
julia> f(; x::Float64 = 1) = :works
f (generic function with 1 method)

julia> f()
ERROR: MethodError: no method matching #f#3(::Int64, ::typeof(f))
Closest candidates are:
  #f#3(::Float64, ::typeof(f)) at REPL[1]:1
Stacktrace:
 [1] f() at ./REPL[1]:1
 [2] top-level scope at REPL[1]:1

julia> f(; x = 1.0)
:works

```

ie you are overspecifying the keyword argument types for no good reason. Generally, this is not good programming style.

I am not sure how the error message could be improved (except for `#solve#8`, which can be cryptic). It describes what is happening concisely and accurately.

---

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [April 1, 2019, 8:02am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/6 "2019-04-01T08:02:07Z")

</div>

> [@Tamas\_Papp](#):
>
> f(; x::Float64 = 1) = :works

well, that’s not quite it. that’s more like it:

```julia
julia> f(y::Float64; x::Float64 = 1) = :works
f (generic function with 2 methods)

julia> f(1.0)
ERROR: MethodError: no method matching #f#30(::Int64, ::typeof(f), ::Float64)
Closest candidates are:
  #f#30(::Float64, ::Any, ::Float64) at REPL[7]:1

```

 ![24](https://global.discourse-cdn.com/julialang/original/3X/b/0/b0077a07dc5a7aecb93d365effdd3784e78ae9f0.png)

the error message could be improved dramatically by

1. not saying that we want to match `#f#30(::Int64, ::typeof(f), ::Float64)`
2. not coloring in red the first argument, `Float64`, which happens to be correct.

don’t you think?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 1, 2019, 8:28am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/7 "2019-04-01T08:28:04Z")

</div>

It is colored in red in the _candidate_, so that part is correct.

As I said above, not using the internal form with the `#` in the error message would be an improvement. Cf

> <https://github.com/JuliaLang/julia/issues/16490>
>
> I just helped @evanfields boil down a more complex situation to the following:
> 
> …\`\`\`
> function trigger(a, b; c::Float64 = a \* b)
> return true
> end
> \`\`\`
> 
> On Julia 0.4, with \`trigger(5, 10, c = 3)\` you get
> 
> \`\`\`
> ERROR: LoadError: TypeError: trigger: in typeassert, expected Float64, got Int64
> \`\`\`
> 
> Which I consider fairly understandable (unfortunate that you don't get told which field it was though).
> 
> With \`trigger(5, 10)\`, again on 0.4, however, you get
> 
> \`\`\`
> ERROR: LoadError: MethodError: \`\_\_trigger#0\_\_\` has no method matching \_\_trigger#0\_\_(::Int64, ::Int64, ::Int64)
> Closest candidates are:
> \_\_trigger#0\_\_(::Float64, ::Any, ::Any)
> \`\`\`
> 
> Which, while fairly understandable in retrospect, is totally baffling unless you know how \`kwargs\` are lowered. Its unfortunate that its a different error message though, for a similar sin. It is also hard to figure out whats going on in more complex cases - here it was a 2+1 arg function, but the original setting was much more interesting.
> 
> On Julia 0.5 you get
> 
> \`\`\`
> ERROR: LoadError: TypeError: #trigger: in typeassert, expected Float64, got Int64
> in (::#kw##trigger)(::Array{Any,1}, ::#trigger, ::Int64, ::Int64) at ./null:0
> \`\`\`
> 
> for the first, which is worse than 0.4 (the null:0 is delightful) , and for the second case you get
> 
> \`\`\`
> ERROR: LoadError: MethodError: no method matching #trigger#1(::Int64, ::#trigger, ::Int64, ::Int64)
> Closest candidates are:
> #trigger#1(::Float64, ::Any, ::Any, ::Any)
> in trigger(::Int64, ::Int64) at /Users/idunning/....
> \`\`\`
> 
> which is even more exciting maybe.
> 
> Is there a path forward for making these messages nicer, or is too much information lost when lowering?

---

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [April 1, 2019, 11:19am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/8 "2019-04-01T11:19:11Z")

</div>

I’m not following. Here is how I think this should be:

```julia
g(x::Float64,y::Float64) = x
julia> g(1.0,2)
ERROR: MethodError: no method matching g(::Float64, ::Int64)
Closest candidates are:
  g(::Float64, ::Float64) at REPL[11]:100:

```

 ![42](https://global.discourse-cdn.com/julialang/original/3X/8/c/8ca8e40dcc7cb5447755ea140b510ff13cdcdeb7.png)

The red bit is of course the part that is **wrong** and needs to be changed - it says there is a `g` where the second argument (_shown in red for your benefit_) is a `Float64`, so supply the correct argument. Now compare that to the picture above. the _first_ argument is red, when it should be the second.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 1, 2019, 11:27am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/9 "2019-04-01T11:27:33Z")

</div>

> [@floswald](#):
>
> The red bit is of course the part that is **wrong** and needs to be changed

The problem is not this, but that an internal implementation detail leaks into the error message.

Currently (on `v"1.2.0-DEV.608"`)

```julia
f(x; y = z)

```

is translated to a call signature

```julia
g((y = z, ), f, x)

```

where you see `g` as a generated symbol name somehow related to `f` (currently something like `#kw#f`).

This is an _internal detail_, and might change at any point. The problem is not that things are not in the right order, or mismatched, but that this is _printed at all_, and not translated back to the original call form (for the error message).

This is known (see the above issue).

---

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [April 1, 2019, 11:39am UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/10 "2019-04-01T11:39:51Z")

</div>

that’s good to know. i don’t care so much about that printing really. I think this inconsistency is really confusing. just for the record, i am talking about this inconsistency

```julia
julia> f(x::Float64;y::Int = 1.0) = x
f (generic function with 1 method)

julia> g(x::Float64,y::Int) = x
g (generic function with 1 method)

julia> f(0.0)
ERROR: MethodError: no method matching #f#5(::Float64, ::typeof(f), ::Float64)
Closest candidates are:
  #f#5(::Int64, ::Any, ::Float64) at REPL[1]:1
Stacktrace:
 [1] f(::Float64) at ./REPL[1]:1
 [2] top-level scope at none:0

julia> g(1.0,0.0)
ERROR: MethodError: no method matching g(::Float64, ::Float64)
Closest candidates are:
  g(::Float64, ::Int64) at REPL[2]:1
Stacktrace:
 [1] top-level scope at none:0

```

 ![03](https://global.discourse-cdn.com/julialang/original/3X/2/3/23b32ea73ce2af802d46f9ebec962782b8b41c23.png)

I think the first error message should not say that there is a candidate `f` with an Int as first argument available. Notice that _calling the function with wrong kwarg_ behaves as I think it should:

```julia
julia> f(0.0,y = 1.0)
ERROR: TypeError: in keyword argument y, expected Int64, got Float64

```

anyway, i guess it won’t happen that often that someone messes up the default arg in their function definition like i did here.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 1, 2019, 12:10pm UTC](https://discourse.julialang.org/t/keyword-function-error-inverts-position-of-arguments/22571/11 "2019-04-01T12:10:27Z")

</div>

> [@floswald](#):
>
> the first error message should not say that there is a candidate `f` with an Int as first argument available

But, if you read carefully, it doesn’t. It refers to `#f#5`, not `f`. The main issue is that you should not see `#f#5` (because, again, it is just an implementation detail), but given that you do, the message is actually correct and consistent.
