I was thinking about this,
we have as I count it, 3 different kinds of Metapackage/Higher level package.
Though the term Metapackage is used only for the last 2.
I think especially for Class C maybe?
Class A: *Base packages / Namepace packages / Interface packages
E.g. StatsBase.jl, SklearnBase.jl, LearnBase.jl, ColorTypes.jl, RecipesBase.jl, MathProgBase.jl
These packages primarily exist to provide a set of types, and a set of function names in a common namespace.
A whole pile of packages (often with in an org use them), to achieve compatibility, and consistency.
By using the common namespace, one avoids name-collisions.
Further the functions come with a set of conventions that are expected to be met when you implement the functions.
StatsBase.jl and SklearnBase.jl actually contain an overlapping set of names, but they have different conventions (SklearnBase.jl is RowMajor and other things). One can actually implement both of them (one of the good things about namespaces).
The types they provide are often abstract, and the functions are often without methods.
A secondary purpose of these packages is to provide useful helpers for packages that build on them;
normally using the types and functions defined in the package.
Taken too far and this can can cause problems, for example StatsBase.jl is quiet heavy to install because it depends on a number of packages including the large DataStructures.jl.
In general this kind of package should have very few, or no dependencies. Maybe Compat.jl and/or another Base package.
Adding too much functionality also moves away from describing an interface and into just being a normal package, that other packages often extend.
Class B: Multi-backend / Front-end Package
E.g. JuMP, Plots.jl
These packages expose some useful functionality, and a standard API.
It does some real work and has real-non-empty functions.
But they let the bulk of the work be done via some backend package, which they make it possible to swap-out.
JuMP.jl facilities this via all its backends implementing the Class A interface package: MathProgBase.jl,
Plots.jl does not, it uses Requires.jl, and some other shenanigans
WordTokenizers.jl is sort of down this line, but all of its back-ends bar one, are contained in the package itself.
It is a notable trait of these packages that they have many optional dependencies
Class C: Standard Environments / Metapackages
E.g. DifferentialEquations.jl, MLDataUtils.jl, proposed Stats.jl
This kinda package is built around Reexport.jl,
has a large(ish) number of dependencies, which it reexports.
The idea is that the user just imports this packages and they have a full batteries included environment for doing a task.
Many users will not even realize the package is actually made up of parts – or at least they won’t have to care.
Class D: Glue packages
I am not sure these really exist. I can’t bring any to mind.
I’ve seen glue packages argued for in the past, which were to serve a similar purpose to what seems to be what Requires.jl is used for now.
For optional dependency of A upon B, have a glue package that depends on both and adds the functionality.
Better names for these?