Example of problem:
For me, [struct foo] is analogous to foo_class in an external-- that is, when you instantiate an object that is an external, it doesn't have to generate and compile new source code with 1001foo_class in it. Rather it just allocates memory for all the stuff that class needs, and deallocates when you remove that object. That corresponds to creating/deleting a scalar on a canvas.
So instead of [struct $0-foo], which is ugly and a hack, you should be able to do this:
1. Put [import bar] in your abstraction or whatever
2. In directory "bar" have bar_setup.pd, which contains [struct foo]
3. Pd searches its loaded libs to see if library "bar" has been loading; if it hasn't, it loads the patch bar_setup.pd without giving it a tk window (so that exactly one instance of [struct foo] exists now
4. You're abstraction loads and is able to instantiate scalar foo regardless of $0
5. For loading additional abstractions that use scalar "foo" go to step #1 and it should work.
Of course this runs into the same problems with namespace clashes as externals do, but probably has the same solutions, too. This would also work for libs of abstractions that want to share a common [v] or a [table]