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?
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.
I downloaded this notebook and extracted all code from from it: QuantEcon – Notes
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.
you can make the script work by setting dampen::Float64 = 1.0 on this line
if you don’t make that change, the script returns this error:
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!
Thanks for posting the script, but this is hardly a MWE
I think your problem can be boiled down to
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.
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.
The problem is not this, but that an internal implementation detail leaks into the error message.
Currently (on v"1.2.0-DEV.608")
f(x; y = z)
is translated to a call signature
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).
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> 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
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> 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.
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.