Newly defined functions/structs exposed in package extensions are not exposed in the main package (also not once the extension is loaded). See this related question and workaround: How to use functions defined in package extensions but not the main package?
The workaround is nice, but doing this excessively creates a lot of boiler plate code in the main package. Additionally, for the function/struct to be exposed, I think it would need to be exported by the main package (or else some additional step would be required on the user end).
My questions is therefore: should we define new functions/structs in an extension at all?
It seems like a pretty common use case to add entirely new functionality through an extension, but maybe in most cases this just calls for an entirely separate package? What am I missing?
I remember a few slack discussions (can check whether we had a thread here as well), where the conclusion was:
An extensions extends given functionality, i.e. already defined functions (in either the main package or the one from the extension). It should not define new structs/functions.
When I wrote our extensions, having this in mind worked really well.
E.g. you would define a new plot receipt or implement a new dispatch for another function once a certain package is present.
Sure we have one or two functions that default to an error since then a certain solver is not present – that could be considered plate code but is just 6 lines.
Can you maybe have a more precise example? I would think entirely new functionality (new functions names or structs) should be in a package not an extension.
Ok, thanks, that makes sense. Probably good to make a clear distinction between the two use cases.
I have a concrete example in this PR, where I turned
MPI into extensions.
I think in the case of
MPI I can live with the boiler plate. In the case of
PythonCall (a lot of boiler plate) and probably also
RCall (some boiler plate), it might make more sense to move to a separate package.