~severeoverfl0w/wedge#30: 
Separate config from system API

config/system are inherently tied together to some degree. How can integrant load it's system from environ? It can't.

However, perhaps there's an opportunity to define a way that it could. This would reduce implementation effort for new configs/systems and avoid the combinatorics which may confuse new users.

#28 will be worth completing before undertaking this.

Status
RESOLVED IMPLEMENTED
Submitter
~severeoverfl0w
Assigned to
No-one
Submitted
1 year, 1 day ago
Updated
8 months ago
Labels
beta

~severeoverfl0w 11 months ago

Instead of (config-system) I think we can define the pipeline as (-> config transform-config system). The place funny business happens is in "transform-config".

transform-config is variable dependent on the use-case. The transformation for starting a system is distinct from the transformation applied when finding your Figwheel build.

transform-config will be called with the config only, meaning no opts are available. This will allow maximal use of plain functions. Perhaps an transform-opts option may be read in somewhere and if present be provided as a second arg, tbd.

~severeoverfl0w 11 months ago

One minor problem with this is tight integration between config/system, e.g.

(defmethod aero/reader 'ig/ref [_ _ value]
  (ig/ref value))

(defmethod aero/reader 'ig/refset [_ _ value]
  (ig/refset value))

One option is for known combinations to be loadable in some way that would allow for this tight integration to remain.

~severeoverfl0w 11 months ago

This is a great example of integration woes. It stems from the framework nature of Wedge (this isn't a problem when you're putting the pieces together yourself).

With the combined integrant-aero namespace there was a clear responsibility for integrating the two parts. When you make these separate, even were you to build some auto-combination-functionality, where would you document it? This moves clearly into occult rather than an explicit, clear process.

Stepping back a little bit, the problem is that the config cannot be read in a bubble. To read the config, you must know the system. So there's an inherent coupling there. That's not always true though, environ doesn't have this problem until the transform phase (which is inherently coupled to the system, it's glue!). There's a parallel with read-eval. While they're decoupled, you sometimes need to configure read using data_readers.cljc in order to actually read something such that it can be evaluated.

Options:

  • Retain the combined config-system step
  • Add mechanism to wedge which can detect combined pairs and execute code
  • Add plugins to Wedge which would be explicitly loaded: {:system integrant :config aero :plugin [integrant-aero]}
  • Don't support aero, only support configs which can be read without additional context
  • Systems provide a function for loading them for a given config system.
  • Configs dynamically load any extensions based on what's on the classpath (rather than what's actually in use)
  • Systems dynamically load any config extensions based on what's on the classpath :)

Going back to the problem statements that drove this:

  • There are use-cases for pulling from the config that aren't systems, but we'd still like to derive everything from config
    • reading a figwheel build rather than starting it as part of your system (required for clip).
  • There's high friction to adding new system or config libraries as the work is M×N rather than M+N.

Constraints:

  • Clear documentation - when this is activated, what's it activated by
  • Forked system or config support
  • Allow adding new integrations to existing configs or systems that Wedge has never heard of (e.g. adding fern support to Wedge's integrant or integrant support to Wedge's aero)

~severeoverfl0w 8 months ago

I'm decided on:

Configs dynamically load any extensions based on what's on the classpath

This allows documentation to be added to the config about which extensions are built into them. The config will also be responsible for defining how other extensions could be loaded, in aero this is defined as a key that's read before reading. In fern this is a plugins key that's part of the config. I'm undecided how environ support would work, it may just be a library you'd use directly from a var-based config.

~severeoverfl0w REPORTED IMPLEMENTED 8 months ago

Register here or Log in to comment, or comment via email.