Call Generic Function From Specialization

Having a tough time calling a more “generic” form a function from one that is specialized (i.e call a function for a “base” type from a version of the function for a subtype).

Consider this:

abstract foo

type bar <: foo
end

function doStuff(a::foo)
  println("Generic!")
end

function doStuff(a::bar)
  println("Specialized!")
  doStuff(convert(foo, a))
end

b = bar()
doStuff(b)

That doStuff(convert(foo, a)) represents my obviously failing attempt to do this… as this code goes into infinite recursion calling doStuff(a::bar).

I can see a way to fix it by making doStuff() parametric and then explicitly specifying the parametric type to call… but I was hoping to avoid that (or, I guess, I was thinking that there should be a way to do this without resorting to that). Surely I’ve just missed something important here…

Any advice would be appreciated!

Derek

Instead of

doStuff(convert(foo, a))

you want

invoke(doStuff,(foo,),a)

See under Essentials in the manual.

i would probably make an internal function

function _dostuff(a::Foo)
  println("Generic!")
end

dostuff(a::foo) = _dostuff(a)

function dostuff(a::Bar)
  println("Specialized!")
  _dostuff(a)
end

however, i feel that based on the actual case, there should be a nicer solution. i assume there is some kind of branching going on in dostuff(::Bar), which might be done compile time through dispatch.

That works perfectly Ralph!

The documentation is pretty hilarious… it matches my use case perfectly. I have no idea how I wasn’t able to find invoke() on my own… I appreciate the heads up!

For completeness… here is the documentation for invoke():

invoke(f, (types...), args...)
Invoke a method for the given generic function matching the specified types (as a tuple), on the specified arguments. The arguments must be compatible with the specified types. This allows invoking a method other than the most specific matching method, which is useful when the behavior of a more general definition is explicitly needed (often as part of the implementation of a more specific method of the same function).