5 ms·
See also the Configuration Complexity Clock: https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html https://mikehadlow.blogspot.com/2012/05
by gavinhoward 2y ago
See also the Configuration Complexity Clock: https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html https://mikehadlow.blogspot.com/2012/05/configuration-comple... .
This is why I have a separate config language and code language.
My config language is essentially JSON with newline separators and a first-class binary type (base64). I added little else.
When I get the temptation to add code to it, I just pull out my other, general-purpose language instead.
- aapoalas 2y agoI'm basically in charge of maintaining and developing a product that (on purpose) started at 9 o'clock. We've resisted the call to implement loops and such in our DSL but I can hear the wolves howling and I doubt I have much longer...
- pxc 2y agoI think the world needs programmable config langs because slinging YAML and JSON quickly becomes miserable (as is extending them through templating alone) and general-purpose programming languages usually have shitty ergonomics for writing configuration. The only question in my mind is whether our common config langs should be Turing-complete (e.g., Nix, Nickel, Jsonnet, Pkl) or not (e.g., HCL, CUE, Starlark, Dhall), which I think can only be determined through experience over the long term.
- gavinhoward 2y agoHate to burst your bubble, but because of `break` and early return, Starlark is basically Turing-complete. https://gavinhoward.com/2024/03/what-computers-cannot-do-the-consequences-of-turing-completeness/ https://gavinhoward.com/2024/03/what-computers-cannot-do-the...
- pxc 2y agoThe Starlark spec discusses this, and I consulted it before I wrote my comment. > It is a dynamic error for a function to call itself or another function value with the same declaration. > This rule, combined with the invariant that all loops are iterations over finite sequences, implies that Starlark programs are not Turing-complete. However, an implementation may allow clients to disable this check, allowing unbounded recursion. https://github.com/bazelbuild/starlark/blob/master/spec.md https://github.com/bazelbuild/starlark/blob/master/spec.md I do kind of agree with you about this, though: > At that point, just give your users a `while` loop for usability's sake. I'm generally in favor of powerful, purpose-built configuration languages, including Turing-complete ones. And the goal of assuring users that their programs will terminate at all is definitely aligned with a fuzzier goal, less formalizable, that their programs will terminate in a 'reasonable' period of time, whatever that means.
- __MatrixMan__ 2y agoIf possible, I'd say it's best to just stay at 12:00. Let them be "hard coded" in ~/.config/myapp/config.py or such so that it's very clear which edits should only be done by a wizard and which ones are suitable for a user. This way all your users are suitably placed on a slippery slope where one edit in the same language but to another file will transition them from user to contributor. Jail them in a separate language and they'll stay users forever. Besides, config languages never have the level of polish (re: tab completion and static analysis) that the main language does. Why deny your users the niceties that you set up for yourself?
- pxc 2y ago> Besides, config languages never have the level of polish (re: tab completion and static analysis) that the main language does. They don't have to! > Why deny your users the niceties that you set up for yourself? Don't do this, of course. :) For instance, Nickel gained[1] an LSP implementation years before it hit version 1.0. When editing Nickel configs,byou get all the stuff you'd expect for a programming language: syntax highlighting, type hints, autocompletion, etc. But beyond static analysis, Nickel can also validate your configurations dynamically, according to arbitrary predicates-- and that too, integrates with your editor through the language server. Nickel ships with a command-line evaluator, REPL, pretty printer for data structures, code formatter, documentation generator, and CLI tab completions for Bash, zsh, Fish, PowerShell, and Elvish. Upstream distributes the tooling (which is, Go-style, a single executable with subcommands) as a Nix flake, a Docker image, and static executables for Linux aarch64 and x86_64 (< 30 MB, for now at least). Nickel doesn't yet have a package manager[3], but other than that it honestly has a better tooling story than many general-purpose programming languages currently in widespread use. CUE, an older (but not old) configuration language (very cool in its own right), likewise has great tooling. It ships with a command-line evaluator, a pretty printer, a formatter, package management based on Go modules (i.e., it has both a `mod` and a `get` subcommand), a few refactoring tools, and tab completions for bash, zsh, and fish.[4] It currently lacks a language server[5] but there is recent and ongoing work to enable that. There's no reason that a configuration language can't have first-rate tooling! There is a new crop of really innovative, powerful configuration languages out there. I hope they start catching on. > This way all your users are suitably placed on a slippery slope where one edit in the same language but to another file will transition them from user to contributor. > Jail them in a separate language and they'll stay users forever. This, I admit, deeply appeals to me. It's one of the things I really like about the Nix language, wart-y though it may be: the tools you use to configure your NixOS computer are the same ones you can go on to use to extend NixOS. I think that's an enormous strength. But I also like for simple configuration to look really simple, and not trouble you much with the details of the language (or, God forbid, configuring the runtime). Perhaps programmable configuration languages, then, are good fits for tools like build systems and packaging systems (where the 'upstream' code users might next want to play with is also essentially fancy, expressive configuration in a special domain), but embedded DSLs might be better for applications (and work for packaging and build systems, too). Re: creating a continuous road for users to hack on the software they use, GNU is really trying to do something special there: with Guix you have application configuration, package management, and system configuration handled in a DSL in Guile Scheme. But then Guix itself is also written in Guile! And at the same time, Guile is the official extension language of the GNU project, so GNU applications all (hopefully?) have Guile bindings, so you can use the same language to plug into (hopefully?) all the other GNU applications on your system. It's a cool idea. -- 1: https://github.com/tweag/nickel/pull/405 https://github.com/tweag/nickel/pull/405 2: https://www.tweag.io/blog/2024-05-16-nickel-programmable-lsp/ https://www.tweag.io/blog/2024-05-16-nickel-programmable-lsp... 3: https://github.com/tweag/nickel/issues/1585 https://github.com/tweag/nickel/issues/1585 4: https://cuelang.org/docs/reference/command/ https://cuelang.org/docs/reference/command/ 5: https://github.com/cue-lang/cue/issues/142 https://github.com/cue-lang/cue/issues/142
- everforward 2y agoI've hit this point a few times, and I always advocate for cutting the losses and switching to embedding an existing interpreter. Lua and Lisp both have embeddings for most popular languages, Starlark is Python-y and embeddable, many languages can embed a Javascript engine. Imo, users asking for stuff like loops is a signal that they want a real language and not a bolted-on DSL. I've seen far too many cases of "extending a DSL until it's a full-flegdged but awkward and horrible language". Ansible's YAML and Terraform's are my prime examples. Both have grown into basically full languages featuring imports, for loops, etc, and both suck to use because of how awkward reaching for them is. I don't want to have to remember Ansible's bastardized, YAML-encoded for loop syntax, just let me use a Python for loop.
- jolt42 2y agoPersonally I've seen 9pm be a holy grail, an exceedingly advantageous position to be in. But, it's exceedingly challenging to figure out what that DSL should and should not have as well.