Fork me on GitHub

Now users can define their own (defmulti reader)


Another thing I think would be valuable, but is incompatible with Aero currently, is having graph links.

{:food {:fruit [:apple :pear]
                :sweets [:chocolate :cake]}
  :frank {:favorite-food #link [:food :fruit 1]}}
Where after we read the config, we would get
{:food {:fruit [:apple :pear]
                :sweets [:chocolate :cake]}
  :frank {:favorite-food :pear}}


This either requires a post-processing walk of the config map, or exposing something more flexible than the edn reader. I’d be willing to contribute that to Aero, although I would be worried it would ballon complexity and bare simplicity seem’s to be an aim of this project.


I guess you could built that on top of aero with your custom reader support


Took a stab at it. The main thing I wanted was to have a #path/`#link` type tag, but I also need it to compose with the existing tags. I could not find a happy medium between this (give a multimethod the entire config) and using a lens based approach. This has a pretty simple extension API, if your reader is called with tag, you’re reading EDN, if your reader is not called with tag, you’re postwalking over the map with opts holding a copy.


In hindsight, it’s most likely clearer to pull that duality with reader into two multimethods, or ditch the prewalk step out of aero completely and just leave that up to the application.


This has strong echoes in Om Next query expressions. Ultimately, config is a graph, but it's convenient for us to extract out a tree - whether for building a web view or configuring a tree of componrnts. A query expression is a syntax for turning a graph into a tree, and the library support exists in both clj and cljs.


The reason config is so hard is usually because different parties have different perpectives (trees) on the same data (graph) but insist their perspective should be the canonical one.


So instead we duplicate, because that's often easier than compromise


Graph databases are better data sources for config than relational tables (because config tends to be individual and not class oriented). But because of the bootstrapping problem local data wins


@gardnervickers I really like this idea, interested to see your implementation. Also, the defmulti is a great idea. I think aero should have safe sensible builtins with extension points where you need them. I'm somewhat conflicted about making it easy to use environment variables for config. Sometimes you need them but it's a bad idea to go overboard, or use them for passwords


Very insightful @malcolmsparks! The #path extension was to fill my desire for Om Next style query paths, the biggest problem we face today is duplicate config. A #path and a #file operator would solve this (the later being able to read-config in other files). Aero seems to care about two things, reading a tagged EDN file with a set of custom tag interpreters, and apply something to the result (schema check). Using multimethods it’s simple to make the first part extensible, as you’re limited to how the reader works (cant go back up tree). But making the second part extensible is a bit unclear because then you get into the trouble of specifying transform order (i.e. this transform depends on this one).


I have some ideas for this I am working through. I believe the simplest way to extend that with them most amount of flexibility is to require extensions have (through protocol or convention)

{:reader (fn …)
 :before (fn…)
 :after (fn …)}
Where :reader stays like in my original commit, and the results of :reader gets threaded in order through all the :before’s and then back through all the :after’s. I’ll play with it a bit and report what I find.