@Markus_Agwin asked if I wouldn’t mind posting a response I wrote in the #biff channel on Slack (he brought this thread to my attention over there)–here it is for what it’s worth:
Interesting. I just read through it. My immediate thought is that I’m not really seeing what the benefit of namespace inheritance would be. Didibus mentioned that it’s used in Phoenix to make defining models/views/controllers more convenient. Although Biff doesn’t really follow MVC as far as I’m aware, the equivalents (schema, ring handlers, ui code) seem pretty easy to define already? If I was more familiar with Phoenix/Elixir I might have a clearer understanding of why it’s helpful there and why or why not it might be helpful in biff.
I think namespace inheritance is possibly a separate issue from whether or not the framework actually provides inversion of control (as was correctly pointed out, biff still follows the standard Clojure practice of keeping the “framework” code in your app rather than in an external library). Again at this stage it’s not obvious to me that there would be any benefits to having Biff’s feature maps work more like plugins. the very first release of biff did use a plugin system actually–you annotated namespace with
^:biff
metadata and then biff discovered them at runtime. but later I removed it because it didn’t really provide any value over the current explicit approach.
I went and found the commit where I removed the plugin system by the way. You can search for ^:biff example.core
and :example/core
(both in the same file) to get the gist of it–on startup, Biff would search all the clj files on the classpath for any with ^:biff
-annotated namespaces, then do a requiring-resolve
on the components
vars from those namespaces.
Now we just have users pass in the vector of components themselves, and similarly users also pass in the vector of feature maps. It seems to work well enough . And it still allows you to have “feature namespaces” with only your domain-specific code, and no framework code intermingled.
All in all my feeling so far is that the explicit approach can be made sufficiently easy so that it’s not a bottleneck on adoption*. My opinion on that may or may not change as Biff grows. I have been thinking about wrapping more of the stuff in that file (i.e. the template top-level namespace where all the framework code resides) in helper functions. It mainly depends on “what is the probability that people will want to change the framework code.” If we pull more of it into an external library, then it places less of a cognitive load on people at first. But if they do want to change the framework code, it would be less immediately obvious how to do so.
(*IMO social factors probably have a bigger affect on adoption than technical factors, which is why I’ve started doing meetups and things for Biff. But the technical factors probably have a larger affect on if people still like the framework after they’ve been using it a few years/after they’ve inherited a legacy project written with it )