@@ -3019,7 +3019,7 @@ tips
30193019; ; the code has to hold both swaps in mind simultaneously.
30203020; ;
30213021; ; **`render-panel` does too much.**
3022- ; ; This function is the workhorse of the system : it computes statistics,
3022+ ; ; This function does most of the heavy lifting : it computes statistics,
30233023; ; merges domains, builds scales, constructs the coord function, renders
30243024; ; marks, draws axes and grid lines, and assembles everything into an SVG
30253025; ; group. `resolve-view` and `defaults` pull out some of that complexity,
@@ -3035,6 +3035,35 @@ tips
30353035; ; Adding Malli schemas for view maps and plot options would catch these
30363036; ; mistakes at the point where the user makes them.
30373037; ;
3038+ ; ; **Inference logic: code vs. data.**
3039+ ; ; `resolve-view` encodes all its inference rules as ordinary `cond`
3040+ ; ; branches and `or` expressions. This is easy to read and debug: you
3041+ ; ; can step through it, print intermediate values, and see exactly why
3042+ ; ; a view got `:mark :point` instead of `:bar`. But all rules are
3043+ ; ; wired into one function, so users who want different defaults --
3044+ ; ; say, boxplots instead of strip plots for categorical-vs-numerical
3045+ ; ; pairings -- must either override per view or modify the source.
3046+ ; ;
3047+ ; ; An alternative is to represent inference as data: a graph of
3048+ ; ; dependencies between properties, where each node has a rule that
3049+ ; ; can be replaced. [Hanami](https://github.com/jsa-aerial/hanami)
3050+ ; ; takes this approach with its substitution-key templates, which
3051+ ; ; form a DAG of defaults that users can override at any node.
3052+ ; ; Tableplot's current API builds on the same idea; its
3053+ ; ; [Dataflow Model Walkthrough](https://scicloj.github.io/tableplot/tableplot_book.dataflow_walkthrough.html)
3054+ ; ; explains the mechanism in detail.
3055+ ; ; The advantage is flexibility: swapping one default doesn't require
3056+ ; ; reading the whole inference function. The cost is indirection:
3057+ ; ; understanding *why* a property has a particular value means tracing
3058+ ; ; through a dependency graph rather than reading top-to-bottom code.
3059+ ; ;
3060+ ; ; This notebook chose plain code. The inference logic is short enough
3061+ ; ; (~40 lines) that reading it directly is manageable. But as the
3062+ ; ; number of inferred properties grows -- and it would in a real
3063+ ; ; library -- a data-driven approach might pay for its indirection
3064+ ; ; with better extensibility. Finding the right balance between
3065+ ; ; "easy to trace" and "easy to extend" is an open tension.
3066+ ; ;
30383067; ; ### 📖 Design space
30393068; ;
30403069; ; This notebook is one of several experiments in the same design space.
0 commit comments