Call Generic Function From Specialization

question

#1

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


#2

Instead of

doStuff(convert(foo, a))

you want

invoke(doStuff,(foo,),a)

See under Essentials in the manual.


#3

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.


#4

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).