Duck typing when `quack` is not in `Base`

Say that I develop a package Foo that does interesting things with any type T with a well defined function quack(T). Typically, I may not want to impose T to let the user add relevant metadata or use a type from another package.

module Foo

function foo(x)
   q = quack(x)
   # ... do something with q ...
end

end

It works in a very satisfactory way when quack is in Base (like arithmetic operations). The user extends quack for its own type and everything works. But when quack is not in Base, julia complains that quack is not defined. I can define it with something useless, but it is not very elegant.

module Foo

quack( :: Union{} ) = nothing

function foo(x)
   q = quack(x)
   # ... do something with q ...
end

end

Moreover, it is not plug and play: if another package Bar defines a type S with a function quack, Foo will not be able to use it directly, it will require plumbing.

Is there a customary solution in this situation?

1 Like

Use function quack end to define the function quack.

It will need to depend on Foo and extend Foo.quack.

2 Likes

Thanks, that’s better!

I guess it has some good…

You might find GitHub - JuliaData/DataAPI.jl: A data-focused namespace for packages to share functions interesting: it’s a way to solve this in the data ecosystem. One package (DataAPI.jl) defines the names and maybe default definitions, and various packages depend on this one to extend them. The idea being you might want a very lightweight package to provide the common names, rather than having many heavy packages depend on each other just in order to extent bits of functionality.

1 Like