module Core
abstract type AbstractInterfaceType end
foo(a::AbstractType) = println("do interface stuff")
struct MyBaseType <: AbstractInterfaceType end
bar(a::MyBaseType) = println("do base stuff")
end
Now i want to add a new type that a user might use, but it comes with a heavy dependency.
import SomeHeavyPackage
struct MyExtType <: AbstractInterfaceType end
bar(a::MyExtType) = println("do ext stuff")
baz(a::MyExtType) = println("do more ext stuff")
How to do this correctly?
I can add a lib folder and register it separately, this would introduce a new namespace.
I think doing it via a package extension is not possible, since the MyExtType and baz are not extensions but actually new.
Requires technically allows names conditioned on multiple loaded packages, but extensions deliberately moved away from that messiness. Extensions aren’t much accessible and can’t be listed in import statements, and it’s ambiguous and disallowed to do using Core, SomeHeavyPackage: MyExtType. Your intuition is right, exposed names deserve an importable namespace, save extensions for extensions.
I think he might be asking if the type’s name MyExtType would be accessible from outside the extension, and it’s not in the way mkitti structured it. You can get at the type in various ways (get_extension is the most general) but not import the name. The type could be defined in either of the packages instead of the extension, just unimplemented besides the constructors.
Depending on the setup, it could also make sense to add something like
# Core
export get_interface_implementation
get_interface_implementation(pkg) = get_interface_implementation(Val(pkg))
get_interface_implementation(::Val{M}) = error("No interface extension implemented for $M")
# SomeHeavyPackage extension to Core
import SomeHeavyPackage
struct MyExtType <: AbstractInterfaceType end
get_interface_implementation(::Val{SomeHeavyPackage}) = MyExtType
That is, you could define get_interface_implementation in Core and add methods in each extension in order to provide access to the types. So if the user does using Core, SomeHeavyPackage then they can do T = get_interface_implementation(SomeHeavyPackage) to get the type.
Oh yes my bad, I didn’t even look in detail. Since extensions are hard to access, the usual recommendation would be to define everything that external users need inside of the main package, both types and functions, hence my hasty answer.