Remix.run Logo
tombert 20 hours ago

I have grown pretty negative opinions of “using a programming language as a config language” after semi-recently having to spend a lot of time screwing around with someone’s Gradle Groovy abomination. Not even to mention how quickly Nix can get annoying.

I have to ask…why do people want a Turing complete language to configure stuff? I use Sway personally, which is very configurable but for any even remotely complicated logic I shell out to a set of Rust programs.

hombre_fatal 20 hours ago | parent | next [-]

If you look at hyprland config, you can see why they went with it.

Much like vim/neovim config, people want to do things like register a callback that fires to determine the window title and things that are much more advanced than that, like layout management.

When I was using sway, I was using its IPC or worse (https://github.com/johnae/persway) to do advanced things, and Lua scripting in the first class config would have been a much better UX.

phire 15 hours ago | parent | next [-]

It looks like the previous hyprland config language was already getting close to being Turing complete;

Already has variable substitution and math, it seems to falls short of Turing completeness only because I don't see any form of recursion. But recursion is something it could accidentally gain if someone decided to add templating to the language.

Besides, looks the config files can call out to external executables, which absolutely are Turing complete. And moving to lua might actually simplify configs by allowing more things to be done inside the config system, rather than calling out.

tombert 18 hours ago | parent | prev | next [-]

I did run Awesome for awhile and I liked it, but I never used the Lua config for the most trivial things so it never got in the way of anything.

I never found that Sway too annoying to just use the shell commands to grab/modify the current state of Sway (https://github.com/tombert/rs-swanbar) and just use a "real" programming language to actually do any kind of programming logic. To each their own!

32 minutes ago | parent [-]
[deleted]
yjftsjthsd-h 18 hours ago | parent | prev | next [-]

That feels like a plugin or external program, not configuration

17 hours ago | parent [-]
[deleted]
honeycrispy 19 hours ago | parent | prev [-]

I have to agree. There are things that I want to do with my sway scratchpad that are just not possible because the config vocab is so limited. I might port my config to hyprland and give it a shot.

mickeyp 20 hours ago | parent | prev | next [-]

So you don't like using programming languages as config languages, so you:

1. Use a declarative-style format for config, which is fine, I guess; 2. ... and when that inevitably fails, you... use a programming language?

Some people -- not all, but some -- may prefer to skip the first step and go straight for the second option. Particularly if it's a complex thing indeed like a build system and not, y'know, configuring your blog.

AlotOfReading 20 hours ago | parent | next [-]

The theoretical difference in power between a non-Turing complete declarative language and a turing complete one is irrelevant in practice. Datalog is a decidable, declarative subset of Turing-complete Prolog. It's also EXPTIME complete. I don't think we exclude any real use cases by prohibiting super-exponential algorithms.

The problem is shitty config languages. I wouldn't group xaml in the same category as dhall for example.

psd1 5 hours ago | parent | next [-]

OT, but seeing "alot" always sends me here: https://hyperboleandahalf.blogspot.com/2010/04/alot-is-bette...

Language is what people use, and "alot" is close to critical mass, so you'll outlive this species of pedantry. I just like the cartoon.

mickeyp 8 hours ago | parent | prev [-]

That's lovely. I look forward to seeing your autoconf and GNU Make replacement in MAUDE SYSTEM.

sureglymop 13 hours ago | parent | prev | next [-]

It's interesting because this is exactly what I used to do for my hyprland config (which the op is about). I had some keybinds that would shell out and use a script with the hyprctl cli.

Now it's all a single simple lua function and 3x as fast... I think this change is great.

ianburrell 16 hours ago | parent | prev | next [-]

Those aren't the only two options. There are non-Turing complete config languages like Cue, Dhall, and Jsonnet that are designed to complete and be consistent. They work well when did to generate static config from some dynamic input generated by regular program.

dlt713705 16 hours ago | parent | prev | next [-]

> 2. ... and when that inevitably fails, you... use a programming language?

Maybe it fails because you are trying to solve a problem with a configuration when it should be solved by a function implemented in the program you are trying to use.

eviks 6 hours ago | parent [-]

And what do you suggest users do if that function isn't in the program and is unlikely to appear there?

yjftsjthsd-h 18 hours ago | parent | prev [-]

> and when that inevitably fails

This assumption is doing a lot of work. Surely the question was precisely why it would fail?

corysama 19 hours ago | parent | prev | next [-]

Lua was specifically designed to be a configuration language https://www.lua.org/history.html

Lots of people start out with a non-programmable config format. But, as their situation becomes more complicated, they end up shoehorning in programmable-ish features until they realize they are running straight into https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule and decide to do it properly.

tombert 18 hours ago | parent [-]

I mean, fair enough I guess. I've accidentally more-or-less reinvented interpreters on two separate occasions (both times using JSON as a quasi-AST), so I understand it.

I guess I just feel like if you feel like you need programming constructs in your configuration, its approaching it from the wrong angle, and it should instead be handled via plugins.

I feel like configuration itself should be a "dumb" format like JSON, and when you want to do anything that can't be accomplished by plain JSON, you should allow for easy development of plugins.

ffaccount2 15 hours ago | parent [-]

>and when you want to do anything that can't be accomplished by plain JSON

Like comments? ;)

tombert 13 hours ago | parent [-]

YAML then, or something like it. I guess I just like dumb formats for this stuff.

pie_flavor 20 hours ago | parent | prev | next [-]

It is good to keep a configuration simple enough that it doesn't need to be a programming language.

The absolute moment you find yourself thinking of putting conditional logic, or string substitution, or anything like that, in your pure config format, switch to a real programming language, before you end up managing several times the complexity of one with only some of the benefits. No need to end up contemplating some sort of for-loop macro with another key referencing the loop variable, when you can just have a for loop.

I find TOML, in addition to being very readable, to be great at automatically restricting config complexity by making nested lists of tables miserable. If your config sucks at being TOML, it should be JS or Python. (Not a fan of Lua.)

skydhash 17 hours ago | parent | next [-]

> The absolute moment you find yourself thinking of putting conditional logic, or string substitution, or anything like that, in your pure config format, switch to a real programming language, before you end up managing several times the complexity of one with only some of the benefits

That’s where you add a plugin system or an ipc mechanism, not a whole programming language.

crowdyriver 19 hours ago | parent | prev [-]

python is terrible for embedding, starlark is the way to go. Very easy to embed.

nimih 19 hours ago | parent | prev | next [-]

Speaking personally, there are essentially two distinct reasons I like having programmable config languages:

- For personal application config (window manager, shell, text editor, etc), I find I often want to have site-specific configuration, but I also want identical configuration files at every workstation. My laptop probably needs slightly different keybindings than my desktop, my $PATH and text editor needs to be configured a bit differently for work than for personal use, etc. When the configuration is done with a real programming language, this is always straightforward, when it's done via a json/yml/toml file, it's usually a huge pain in the ass.

- You want templating for your configuration, to improve readability, reduce typos and configuration drift, &c, but if you give programmers an inch with any sort of templating system, they will eventually take a mile and figure out how to smuggle Turing-completeness (or, at least, for-loops and variable binding and probably closures) into their configs. If you have a real programming language, this is fine, because the programming language was designed to make loops and conditionals and function calls readable, and probably has decent tooling to boot, but if they're doing it with, say, Mustache-templated YAML, you will have an unreadable mess that is extremely unpleasant to work with.

adw 20 hours ago | parent | prev | next [-]

The usual answer is "config macros", because if you don't give people something Turing complete they'll just m4 their way into Turing completeness and that isn't really an improvement. (Starlark in Bazel, etc.)

zeratax an hour ago | parent | prev | next [-]

i find nix a weird mention here. there is a popular segment of people who wish nix would have used a generic programming language instead of a dsl, but i cant imagine nix working with something like toml ever. the complexity to build every program ever in every programming language is just way too high for that.

MantisShrimp90 20 hours ago | parent | prev | next [-]

Half of me agrees with you. As someone who used to tinker with neovim all day I've had to learn just because you can program the problem doesn't mean you should and stick to a relatively minimal config.

Still, its a valid design choice with different design decisions compared to sway. But that's the point you get to choose.

Hyprland is much more "build your workspace with legos" so having a full lang like lua makes sense to properly integrate the various pieces.

zeratax 41 minutes ago | parent [-]

imo the downsides to this are so minimal to a user? you can configure neovim without defining any functions or w/e and it's not like awkward or anything

HiPhish 16 hours ago | parent | prev | next [-]

> I have to ask…why do people want a Turing complete language to configure stuff?

What's the alternative? Petition the maintainer to add every little feature any random user might want? Or just do it yourself in a few lines of code?

Case in point, when I was still using BSPWM I did no like how if there was only one window on the desktop it would still get an outline. So I wrote 14 lines of Awk (BSPWM lets you use any language) to get what I want. This was only possible because BSPWM gives me all the primitive building blocks and lets me go wild with them. Sure, if all you want to do is set a few colors and numbers that's overkill, but any power user will sooner or later find himself thinking "oh, if only I could do X when Y unless Z".

tombert 16 hours ago | parent [-]

I think having good plugin support is a better way to do it. Keep the most obvious configuration options behind a "dumb" config language like JSON or something, but create a framework to add functionality via a plugin API.

temphaaa 7 hours ago | parent [-]

there is a point where maintaining zillions^H^Hmany plugins and keep them updated between version gets nightmarish (see gnome extensions for example)

mort96 19 hours ago | parent | prev | next [-]

All these window managers have a Turing complete configuration language, because you need to do things in response to events (keyboard hotkeys etc). It's just that for most of them, the "Turing completeness" happens through passing around strings with shell snippets. Might as well be a Lua callback function.

crote 18 hours ago | parent | prev | next [-]

Because there's a never-ending stream of plausible use cases where it just missing one little option. Just look at the web: people have done all sorts of horrible stuff in Javascript to make up for missing HTML / CSS properties.

At a certain point it becomes incredibly tempting to just give up on playing whack-a-mole and let the most demanding users do it themselves using a proper programming language.

vbernat 19 hours ago | parent | prev | next [-]

I have switched from FVWM to awesome because of Lua. Many years later, I have switched to i3 because it's not using a programming language for configuration. It's fine to have a configuration language if you have time to maintain, but your configuration can become quite complex and difficult to evolve. And it is also far more subject to breakage when upgrading.

I think I've found balance by using a Python daemon as a "companion" for my i3 configuration. It listens and react to event. It enhances the configuration, so when it's broken, it's not a big deal. And the interface exposed by i3 is smaller, so less risk of breakage. https://vincent.bernat.ch/en/blog/2021-i3-window-manager#i3-...

NoboruWataya 19 hours ago | parent | prev | next [-]

I don't dislike it but I do think it's interesting that a number of minimalist WMs seem to have converged on the idea of code as config. I have used AwesomeWM for years and love its Lua configuration for providing infinite flexibility. When I was recently looking for something like AwesomeWM but in Wayland I toyed with the idea of moving to something with a simpler config format (and Hyprland was one of the options I considered). I can see the benefit of the simplicity but I guess for the kinds of users that use these WMs, maximum configurability probably trumps everything else. (Currently I am using SomeWM which is just an attempt to get something as close as possible to AwesomeWM in Wayland.)

Personally I have grown a bit frustrated with Lua as a language, but at the same time can see why it would be a good choice for this use case.

somat 18 hours ago | parent | prev | next [-]

It smells like a variant of inner platform effect. Where in order to save you from programming the the config is super flexible, What is missed is that you are still programming only now you have to do it in some weird context.

At least in this case it is an actual programming language instead of XML or YAML like so many of them.

An alternative slightly more charitable interpretation is this is the engine/gamelogic pattern. But the difference between the two is more subtle than it naively appears depending largely on proper layer segmentation.

matesz 20 hours ago | parent | prev | next [-]

> I have to ask…why do people want a Turing complete language to configure stuff?

I don't understand this either. IMO, the current SOTA tool for configuration is CUE, because it is the only one that lets you write schemas for arbitrary refinements. I haven't used it myself, but my understanding is that everybody should be writing configurations in something like this instead of YAML, TOML, HCL, or a custom DSL with no tooling. And yes, definitely not in a Turing complete programing language.

LelouBil 14 hours ago | parent | next [-]

Cue is amazing, I'm using it to configure my kubernetes homelab.

I CANNOT imagine what horrors it would be to do it all with helm or templating.

ciupicri 20 hours ago | parent | prev [-]

> the current SOTA tool for configuration is CUE

the current state of the art tool for configuration is CUE (https://cuelang.org/). FTFY. Gotta love these acronyms.

newobj 19 hours ago | parent | prev | next [-]

if you get into a config system that's complicated enough, and has modularization or inheritance, you'll know that the semantics of "remove this" "add that", override this, default to this, this stuff is hard to express in most config languages, or worse, you start enforcing application level semantics. when you have turing complete language you just ... do those things. we reduced the configuration data of a tool suite once by 90%+ by moving from json to python. there was a tremendous amount of duplication and overlap, with tons of TINY exceptions and variations. it was so hard to see those differences, brittle to maintain, things would get stale, ... moving to python you basically had the "base" thing expressed in one file, and a bunch of tiny delta files encoding the exact deviations. All those deviations were of the forms I described above. Adding a thing to a list. Removing a thign from a list. Overriding a whole list. Do a thing if not already done. And so on. It's also then easy to build all kinds of diagnostics, validators, etc, right into the same framework, without having to munge the data into some other form first.

eviks 6 hours ago | parent | prev | next [-]

Because you are less limited by all the mistakes the designers encoded in the static files

chuckadams 16 hours ago | parent | prev | next [-]

I would agree that turing-complete config is more trouble than it's worth when the config is something you might need to reason over, such as a build definition in Gradle. But for something like a window manager config where everyone's config is a snowflake, it's kind of ideal. Horses for courses and all that.

vvillena 19 hours ago | parent | prev | next [-]

It depends a lot on the config language. Gradle has the uncanny ability to be a "worst of both worlds" option, where there are not many upsides to its using a full language for its configuration. Build configuration is also a space where people and even some tooling seem to forget about good engineering practices, giving birth to fragile builds that people are afraid to modify and improve.

jolt42 19 hours ago | parent | prev | next [-]

I think the progession is like 1) Oh, I can break stuff by changing a config value - it doesn't protect me. 2) Oh, I didn't think X would need to be configurable. 3) With code I can colocate the values with the code that uses them - easier to understand, and I can "configure" anything I want. 4) Why are we using configs?

0x20cowboy 20 hours ago | parent | prev | next [-]

Because it almost always devolves into that anyway. Every yaml system I have ever worked in winds up with some layer on top to “generate the yaml” or some other such madness.

ufo 20 hours ago | parent [-]

In fact, that's how Lua itself came to be. They started with a simple configuration language and added more and more features until at some point they decided to rip the bandaid and turn it into a proper programming language.

marginalia_nu 19 hours ago | parent | prev | next [-]

Yeah I think there are two basic routes that work. Either you have a declarative configuration, or you go the route of Emacs and make the entire thing programmable.

Turing complete configuration languages suck and makes everything slow, janky and difficult to reason about.

weinzierl 20 hours ago | parent | prev | next [-]

I think INI-style config is one of the few good things that came out of the Microsoft/Windows ecosystem. Shame that it is so underspecified. We have TOML, of course, but I think for stupid config even that is too much.

The intersection of INI and TOML would be perfect.

0x457 18 hours ago | parent | next [-]

TOML was created purely because INI has no format spec at all. So what you want is just TOML.

If you don't like certain things, just don't use them in your configs (i.e. tables)

hiccuphippo 19 hours ago | parent | prev | next [-]

What would you remove from TOML to make it perfect?

weinzierl 19 hours ago | parent | next [-]

Tables.

Not from TOML, just from my config language. TOML has other applications that require its complexity.

I'd still keep simple INI style sections in my config lang, but they wouldn't have deeper meaning apart from grouping.

PunchyHamster 18 hours ago | parent [-]

Tables in TOML have uniquely bad format

kibwen 19 hours ago | parent | prev [-]

All scalar types other than strings (especially nonsense like datetimes). I'm already ingesting the configuration file as a string and parsing it into a language with actual types, e.g. Rust, and the act of parsing it into my defined configuration type will itself identify any problems with the config; having half-assed types like "int" in the config file format itself is not only useless, it's counterproductive because it requires people to ask questions like "okay, but what actually is the maximum range of integer values allowed to be contained in this type?". Just enforce UTF-8 encoded string values and let me take care of data validation.

drdexebtjl 18 hours ago | parent [-]

The problem is that you end up with multiple dialects, just like INI.

For example, I’ve seen booleans being represented with “enable”/“disable”, “yes”/“no”, “t”/“f”, “1”/“0”. Sometimes a mix in the same program.

It’s nice that every TOML config requires “true”/“false” across any application.

kibwen 13 hours ago | parent [-]

You won't end up with a mix in the same program unless the code that you're using to parse the config is deliberately written to allow a mix, which no sane code owner would allow. And even if it did, that still wouldn't be enough to outweigh the aforementioned downside of the impedance mismatch between the """types""" in your config file format (how many bits wide is this integer? how much precision is this float? how is nullable data represented?) and the types in your actual language where it matters.

andrewshadura 19 hours ago | parent | prev [-]

Isn't that called TOML?

Dylan16807 13 hours ago | parent [-]

An "intersection of INI and TOML" would presumably only have scalar values. TOML allows really complex lines like these:

  data = [ ["delta", "phi"], [3.14] ]
  temp_tagets = { cpu = 79.5, case = 72.0 }
LatticeAnimal 20 hours ago | parent | prev | next [-]

I like the ability to introspect the system. I have a lua LSP, when I edit lua config files, I know all of the fields of the config I am editing, and I know how they behave (without randomly trying things)

20 hours ago | parent | prev | next [-]
[deleted]
uncletaco 18 hours ago | parent | prev | next [-]

I never really felt like scheme got annoying when configuring guix. I’m half certain most of my configurations for Guix services were just yaml configs with s-expressions

mghackerlady 20 hours ago | parent | prev | next [-]

I think it's only really useful for things you'd want to be able to control programmatically, like text editors or in this case window managers

stephc_int13 20 hours ago | parent | prev | next [-]

I fully agree with that.

Past experience has shown what while Turing complete config is powerful, it is also a double edged sword and I would be wary of using it.

simlevesque 20 hours ago | parent [-]

The thing is that if your config language isn't Turing complete, the community will create N softwares to generate dynamic configs.

skydhash 20 hours ago | parent | prev | next [-]

> I have grown pretty negative opinions of “using a programming language as a config language”

Same here. I like the openbsd approach of small DSL (pf, doas) or just simple ini-like key-value config (sysctl, rc.conf). If you want more, just patch the software and be done with it.

A programming language is OK if the intent is to build a platform (Emacs, Vim) but for something that is purely an application software, it's very much not necessary.

Barrin92 19 hours ago | parent | prev | next [-]

>I have to ask…why do people want a Turing complete language to configure stuff?

because it lets me configure programmatically. Practical recent example, I use Wezterm which uses Lua as a config language but I tried out Ghostty and because I use all operating systems regularly I have a lot of 'if this then that' in my Wezterm config, different default shell, different key bindings etc. With Ghostty my only option is to maintain different config files per machine.

And what's worth pointing out is that Ghostty does have an operator for this('?' I think) which means there's already a bit of programming in it, except what always happens is that software with declarative config files invent their own scripting an templating languages as more and more people demand it, so just give me lua or lisp from the beginning and we're good.

nickjj 16 hours ago | parent [-]

> With Ghostty my only option is to maintain different config files per machine.

This turns out to be a benefit IMO.

Ghostty supports include files. You can have all of your shared config in 1 main config and then have small files that are included which are machine specific. My dotfiles uses it and it supports Linux and macOS. Example: https://github.com/nickjj/dotfriedrice/blob/master/.config/g...

You can have something like this in your Ghostty config: config-file = ?config.local

And then on each machine that's different, you can have your machine specific config in ~/.config/ghostty/config.local or whatever you decide to name the file.

It works out nicely because config options are merged, so the local file can overwrite what's in the main config. This lets you deviate from the original git committed config without needing to modify it. Super handy for public dotfiles.

crest 19 hours ago | parent | prev | next [-]

A window manager / compositor is one of the few things where I can see this making a lot of sense. The alternative of using an IPC socket for everything would be more complex and require users to reinvent the wheel all the time. Also it makes low latency synchronous reactions to events really hard to implement well.

kibwen 19 hours ago | parent | prev | next [-]

Seconded. Your configuration should be a simple declarative language with no Turing-complete escape hatches. Turing-complete configuration languages are the devil. That goes for build systems too: if you absolutely need Turing-completeness in your build system (my condolences for the hellscape you inhabit), use a separate task runner that does its arbitrary nonsense before dispatching to an underlying build system with declarative configuration.

mhitza 19 hours ago | parent | prev [-]

I want a programming language as soon as the program benefits from conditional clauses or subsystems. So if the will and know-how is there, would be great to have it from the start.

I was pretty happy the day I could move some Jenkins jobs to a Groovy script. I've worked with HCL significantly, but once I learned the idiosyncrasies of Pulumi, scripting infrastructure via a programming language was a better experience (good IDE autocomplete simplified things), though it requires more discipline.

Even without working with the Nix scripting language I'll dismiss it. When I looked at it was some kind of bastardisation of Bash with Haskell ideas. A hobby project idea at best, yet forced upon all Nix users. Guile Scheme is a nice small language, and Guix uses that, and I think that is a better approach.

isityettime 18 hours ago | parent [-]

Nix isn't a scripting language in the sense you seem to have in mind. The snippets you saw that looked like Bash most likely were literally Bash, embedded as multiline strings in Nix.

Nix doesn't have much in common with Haskell.

Nix is a really small language, and you can learn pretty much all of it in a few minutes: https://nixcloud.io/tour/?id=introduction/nix

lobofta 7 hours ago | parent [-]

Nix is awesome and has not been part of any pendulum (or clock). It's complex enough that it allows you to build programs with it, but on such a simple core that for all intents and purposes it is a config language.

zeratax 38 minutes ago | parent [-]

yeah i honestly like it a lot too, but i wish it was typed and that the tooling around it was better. though it's getting there...