Comment by rdtsc
17 hours ago
It's just part of what I call the config pendulum.
Simple config -> (Need to do more complicated things) -> Add override levels -> (Need even more flexibility) -> Add a Turing complete language -> (Things get ridiculous, lots of spaghetti code outside of version control. Time for a reset) -> goto "Simple config"
It's fine. I am not saying it's wrong or right. I've gone through the cycle a few times in some projects. On the other hand, think of it as your project is lucky to be used long enough to have these problems. To feel better about it think of it as a spiral. The next "Simple config" is a slightly better version of the first.
I've seen this expressed similarly as the 'configuration complexity clock': https://mikehadlow.blogspot.com/2012/05/configuration-comple...
I like your spiral metaphor though, since you learn some things along the way.
I've tended to find a lot of value in systems that have both, especially when there is automatic translation from the simple config to the Turing complete language. Lean 4's lakefiles are a good example of this, with a TOML format that is a subset of the Lean DSL format.
That seems like a huge waste of time for anything slightly complicated to convert code to simple configs and lose a lot of functionality in the process. Do you have an indication of how prevalent the cycle is in reality?
That's clever insight. If it was lisp from the beginning, maybe would be more straightforward. It's as simple as code can get, according to Uncle Bob, while still being expressive. It's no wonder Emacs still reigns supreme. Well, I am happy with Niri's kdl approach for the time being.
It can be Lisp if you want it to be. Just use Fennel. That's what my Hyprland config is written in.
I saw an interview with one of the main contributors for Neovim and they use fennel for everything. All roads lead to Lisp
I like to have a simple config AND a real scripting language. That way, the UX for changing "simple" things remains straightforward (you can even add a config editor panel), while for less simple things you can use a real programming language (reducing pressure from the "simple" config to turn into a DSL).
I haven't really seen program go back from "a programming language" to a simple config format.
Python setup.py -> pyproject.toml? Make -> ninja. eBPF kernel modules from C to a custom language. Helm Go templates -> Kustomize.
I am sure there are other projects picking up json from a previous xml + xpath + other ...xml junk.
> Make -> ninja
I would disagree on that one. Ninja config might not be turing complete, but they're generated by turing-complete tools (usually cmake). Nobody writes ninja by hand, thus I would argue it's irrelevant!
1 reply →
Python went from setup.py to pyproject.toml, but pyproject.toml declares a build-system, which is another package which all the complex logic from setup.py.
Granted, it's a "simpler" config syntax, but the total system complexity has not decreased.
> Python setup.py -> pyproject.toml?
That's because setup.py was objectively a mistake. In order to know how to run the package you need to know its dependencies, which requires evaluating setup.py, but you cannot evaluate setup.py until you know the dependencies, which requires you to evaluate setup.py, and so on. The pyproject.toml is plain text where you specify the build backend and its options, and the build system can be as complex of a program as need by.
If anything, pyproject.toml is an example of taking the idea of programmable configuration to its next conclusion. The build system is part of the configuration and it's more than a simple script, it's an entire application. You just plug in its name into the universal entry point pyproject.toml.
I'll die on the hill that Helm charts are more of a problem because text/templating is a weird looking templating language then anything else.
3 replies →
WirePlumber switched its config from Lua to a JSON variant not so long ago.
there's a rare form of that where it goes from( simple -> programming language -> language with DSL support -> simple dsl ) ; emacs has followed this model a bit.
Emacs seems to do a pretty good job handling this with the "Customize" interface. Presents a bunch of variables the user is intended to customise in something resembling a familiar interface, then it inserts the values into the Elisp init file. Someone could use and customise Emacs for years and never really touch Elisp directly. But then, oh, those text fields actually take lists, which in Emacs Lisp is the same as taking code. Maybe you use that for a while until you get comfortable and wanna try modifying something not surfaced in "customize", where you can discover init.el, etc. Etc. It's not perfect, but to me it's really close, it's the model of progression I wish all UIs for customisation used, personally.