Dispatch Problems

I thought I knew how dispatch worked, at least to some degree. It is not working as expected. I am using 1.6.3.

First a MWE with 3 methods.

function foo(; count::Bool = false)
	foo(:ANY, count)
end

function foo(id::Symbol; count::Bool = false)
	number = 5
	if count
		return number
	end
	list = foo(id, number, count)
	return list
end

function foo(id::Symbol, number::Integer; count::Bool = false)
	
	if number < 1
		error("Number  must be >= 1")
	end

	# maximun number
	numbermax = 5

	if count
		return numbermax
	elseif number <= numbermax
		list = Vector{String}(undef, number)
		for i = 1:number
			list[i] = "$i $id"
		end
		return list	
	else
		error("Requesting $number '$id' items $numbermax available")
	end
end

Executing foo() I expect the first method to call the second method which in turn should call the third method. According to the stack trace this does not occur.

julia> foo()
ERROR: Number  must be >= 1
Stacktrace:
 [1] error(s::String)
   @ Base .\error.jl:33
 [2] foo(id::Symbol, number::Bool; count::Bool)
   @ Main G:\\test.jl:17
 [3] foo
   @ G:\\test.jl:17 [inlined]
 [4] foo(; count::Bool)
   @ Main G:\\test.jl:2
 [5] foo()
   @ Main G:\\test.jl:2
 [6] top-level scope
   @ REPL[61]:1

and when I call foo(count = true) I expect the number 5 but get a one element vector.

julia> foo(count = true)
1-element Vector{String}:
 "1 ANY"

my suspicion is that if I remove the keyword ‘count’, dispatch would work as I expect.

foo(:TWO, 5) give the expected output
foo(:TWO, 5, count = true) does as well

However foo(:TWO) gives the error

julia> foo(:TWO)
ERROR: MethodError: no method matching foo(::Symbol, ::Int64, ::Bool)
Closest candidates are:
  foo(::Symbol, ::Integer; count) at G:\test.jl:15
  foo(::Symbol; count) at G:\test.jl:5
Stacktrace:
 [1] #foo#17
   @ G:\\test.jl:10 [inlined]
 [2] foo(id::Symbol)
   @ Main G:\\test.jl:6
 [3] top-level scope
   @ REPL[67]:1

That one I cannot figure out, because there is a method of that type. You help is appreciated.

this call is calling a method with two non-keyword arguments, which is the third one, not the second. You probably want here foo(:ANY, count=count).

the same here, you want foo(id, number, count=count).

2 Likes

Thank you, the second set of eyes is invaluable!

2 Likes