16 votes

A reasonable configuration language

23 comments

  1. [13]
    first-must-burn
    Link
    While the idea of the quality of life improvements sounds good, I would not use something that is almost JSON. For one, if its not parseable by JSON tools, you have to use the CLI to convert it....

    While the idea of the quality of life improvements sounds good, I would not use something that is almost JSON.

    For one, if its not parseable by JSON tools, you have to use the CLI to convert it. If you have a conversion step anyway, you might as well use YAML which has most of the qol improvements proposed and much wider adoption.

    Second, almost JSON erodes my muscle memory for writing correct JSON, and love it or hate it, there's a enough of it out there that I ha e to be reasonably good at writing it.

    But as an exercise in learning how to so it, sure, it seems like a neat project.

    8 votes
    1. [5]
      unkz
      (edited )
      Link Parent
      I don't like YAML for config. People think it's good because it looks like you can read and write it easily, but there are so many horrifying little implicit conversion tricks. yaml: dependencies:...

      I don't like YAML for config. People think it's good because it looks like you can read and write it easily, but there are so many horrifying little implicit conversion tricks.

      yaml:

      dependencies:
          module1: 1.2.3
          module2: 1.2
          module3: 013
          module4: 04:30
          module5: 4:30
          module6: no
          module7: NO
          module8: yes
          module9: true
          module10: True
          module11: 'NO'
      sha1:
          module1: 1ABC432D
          module2: 99999999
      

      json:

      {
         "dependencies": {
            "module1": "1.2.3",
            "module2": 1.2,
            "module3": 11,
            "module4": "04:30",
            "module5": 270,
            "module6": false,
            "module7": false,
            "module8": true,
            "module9": true,
            "module10": true,
            "module11": "NO"
         },
         "sha1": {
            "module1": "1ABC432D",
            "module2": 99999999
         }
      }
      

      This is a funny site too:

      https://noyaml.com/

      15 votes
      1. [4]
        first-must-burn
        Link Parent
        Fair enough, I guess. But I still wouldn't want almost JSON.

        Fair enough, I guess. But I still wouldn't want almost JSON.

        3 votes
        1. [2]
          teaearlgraycold
          Link Parent
          Give me JSON or give me death.

          Give me JSON or give me death.

          3 votes
          1. first-must-burn
            Link Parent
            We can have your JSON when we pry it from your cold, tea-stained hands?

            We can have your JSON when we pry it from your cold, tea-stained hands?

            1 vote
        2. unkz
          Link Parent
          Oh hell no, just JSON is fine thanks.

          Oh hell no, just JSON is fine thanks.

          1 vote
    2. [3]
      skybrian
      Link Parent
      JavaScript/Typescript is almost JSON when you're defining objects and that does trip me up sometimes. (What do you mean I have to quote keys?) Quality-of-life improvements that make JSON a bit...

      JavaScript/Typescript is almost JSON when you're defining objects and that does trip me up sometimes. (What do you mean I have to quote keys?) Quality-of-life improvements that make JSON a bit closer to JavaScript (comments, trailing commas) seem good to me since that's not increasing overall inconsistency, it's moving the inconsistency around.

      I dislike YAML because it's complicated, I don't trust myself to remember the syntax, and sometimes it doesn't do what you expect. (The "no means false" problem.)

      7 votes
      1. [2]
        creesch
        Link Parent
        Funny you'd say that, considering that JSON is JavaScript derived and the name originally stood for "JavaScript Object Notation". Honestly, for pure data storage I don't see the issue although...

        JavaScript/Typescript is almost JSON when you're defining objects and that does trip me up sometimes. (What do you mean I have to quote keys?)

        Funny you'd say that, considering that JSON is JavaScript derived and the name originally stood for "JavaScript Object Notation".

        Honestly, for pure data storage I don't see the issue although having to quote keys can be a tad annoying. But at the same time you can also do that in JavaScript if you insist and want consistency.

        3 votes
        1. skybrian
          Link Parent
          Yeah, it's not that big a deal. The JSON config files that I most often edit are for VS Code. It's technically an extension ("JSON with comments"). But I don't think anyone minds that it's an...

          Yeah, it's not that big a deal.

          The JSON config files that I most often edit are for VS Code. It's technically an extension ("JSON with comments"). But I don't think anyone minds that it's an extension? After all, how often does someone want to feed a VS Code config file into a different JSON parser? And if they did want to do that, it wouldn't be hard to convert it.

          Other programs could do the same; converting a fancier config language down to JSON is a common feature. (Although, there are other times when you have to be conservative because you don't know what else is going to read the file.)

          A nice thing about this sort of conservative extension is that many people already know how to read it, since they know JSON and it's not that different. It's similar with markdown extensions.

          2 votes
    3. [4]
      Greg
      Link Parent
      I spend more time than I’d like in HCL, the language that pushed the author to develop this in the first place, so my first thought was “oh thank god, sensible loop syntax and comprehensions”. As...

      I spend more time than I’d like in HCL, the language that pushed the author to develop this in the first place, so my first thought was “oh thank god, sensible loop syntax and comprehensions”. As far as I’m aware YAML has neither?

      2 votes
      1. [3]
        first-must-burn
        Link Parent
        I've been doing a lot of work with Go, and one of the useful "countercultural" ideas that I've picked up is that for simple cases, it is okay for copy and paste to be the right answer. So arguably...

        I've been doing a lot of work with Go, and one of the useful "countercultural" ideas that I've picked up is that for simple cases, it is okay for copy and paste to be the right answer. So arguably for three buckets (the loop example in the article), the loop is not necessary.

        If you have 300 items in the loop, then sure, you don't necessarily want to do that by hand. But I think solving that by having code mixed into the config directly loaded by the end program eliminates the opportunity to troubleshoot the expanded result. What if there is a fencepost error in the loop?

        And I'd much rather have a script+template generate the unrolled loop as part of a deployment workflow and be able to inspect the (now static) output than to have code mixed into my config and have to "mentally execute it" to see what the result is.

        If I'm going to template my configs, both Go and Python have mature template languages already. If one wanted RCL as a template format instead, then i suppose, to each their own, but I don't think it's adding much besides yet another syntax to learn.

        I will say, I am not trying to establish YAML as my last stand of all time. I think @unkz makes a compelling case that it has it's own flaws. But in the interest of discussion, here is how I would (and have) handled the loop example using the anchors and aliases feature. Is it beautiful, no? Is it functional using an established standard? Yes.

        (please be kind if the syntax is not perfect, writing this on my phone) :

        &bucketlocation: eu-west1
        &lifetime: 86400 //24 * 3600
        
        buckets:
        - name = bucket-00
          location: *bucketlocation
          delete-after-seconds: *lifetime
        - name = bucket-01
          location: *bucketlocation
          delete-after-seconds: *lifetime
        - name = bucket-02
          location: *bucketlocation
          delete-after-seconds: *lifetime
        
        4 votes
        1. [2]
          Greg
          Link Parent
          It sounds like we’re coming from a similar place! I’ve got no worries about copying two or three things, and at that level I like your example of just using shared variables to avoid human error...

          It sounds like we’re coming from a similar place! I’ve got no worries about copying two or three things, and at that level I like your example of just using shared variables to avoid human error if the values need updating later. I also genuinely don’t use YAML very much (not a fan, personally: I like explicit structure in my syntax, but that’s subjective), so I’m not especially up to date on what it can/can’t do - I’m comparing more directly to HCL because it sounds like the author’s need was similar to my own.

          When it does come to terraform, it tends to get out of reasonable copy/paste territory relatively quickly. I just needed to do 112 instances evenly distributed across 16 regions the other day, for example, and while HCL’s weird double-nested for each comprehension structure is perfectly capable of doing that, it’s clunky. There are also some decisions they’ve made around implicit importing and variable scoping that can get frustrating once you’re dealing with a few thousand lines of the stuff.

          So yeah, perhaps the real answer is I should just be writing code in a fully featured language to output my terraform config, rather than doing it the “official” way with HCL - I may genuinely take another look at libraries to do that (Pulumi was a non-starter for integration reasons, but perhaps there’s something similar that slots more neatly into an existing workflow), but right now I’m already mentally executing the loops in my config, they’re just a lot less readable than the ones the author proposes!

          2 votes
          1. first-must-burn
            Link Parent
            I don't work with Terraform very much, but the little I have used it makes me appreciate the pain there. I think Helm is a good example of a tool that provides a valuable abstraction layer to get...

            I don't work with Terraform very much, but the little I have used it makes me appreciate the pain there.

            I think Helm is a good example of a tool that provides a valuable abstraction layer to get composability and reusability on Kubernetes configs. So if I were looking at (or writing) tools to layer on TF, those would be the design elements I'd be looking to bring over. Does TF still store the deployment state locally? Once helm started putting the deployment state into the cluster (so that helm upgrades, etc would work from seamlessly from different local environments) it became a lot more useful.

            2 votes
  2. [5]
    drannex
    (edited )
    Link
    I detest json based configurations, they are just messy, hard to parse, and definitely more machine readable than human and this seems like another take on it, still can't believe JSON doesn't...

    I detest json based configurations, they are just messy, hard to parse, and definitely more machine readable than human and this seems like another take on it, still can't believe JSON doesn't have native commenting. (Edit: Which is funny I say that, since I do like XML...)

    I'm not per se a fan of TOML (and particularly not a fan of of YAML), but it's definitely easier to read, and has the grounds for something great.

    I am a fan of NestedText, but sadly adoption is very small and I've barely used it. It seems to hit that sweet spot of being great for configuration, highly readable, modular, and can handle configurations and data fairly well. Most of these can only do one or the other. NestedText also only accepts one data type: String, with the expectation that you can define the type in another field which makes far more sense since its impossible to have a configuration standard handle all types of data types.

    7 votes
    1. [2]
      skybrian
      Link Parent
      That's odd, I think of JSON as very easy to parse since every language has a parser :) Also, I'm used to it. I never liked dealing with XML parsers, but perhaps they're better now. There's...

      That's odd, I think of JSON as very easy to parse since every language has a parser :)

      Also, I'm used to it.

      I never liked dealing with XML parsers, but perhaps they're better now. There's something nice about using an XML-like syntax as an embedded UI language though, as used in React, Preact, and similar libraries.

      I've invented my own data format before. Never again.

      4 votes
      1. fxgn
        Link Parent
        I think "hard to parse" in the original comment reverse to json being hard to parse by humans, not by computers

        That's odd, I think of JSON as very easy to parse since every language has a parser :)

        I think "hard to parse" in the original comment reverse to json being hard to parse by humans, not by computers

        4 votes
    2. [2]
      unkz
      Link Parent
      persay -> per se

      persay -> per se

      4 votes
      1. drannex
        Link Parent
        You see that was what I thought, and what I originally wrote until my spellcheck red lined it. So I searched it, from what I can tell the original is of course per se, from Latin, but has been...

        You see that was what I thought, and what I originally wrote until my spellcheck red lined it. So I searched it, from what I can tell the original is of course per se, from Latin, but has been about as commonly misused as persay since the 1500s. They both mean the same thing, but appears to be both regional, and just generalized depending on where one would have learned.

        I'm just going to stick with per se, even if it looks a little wonky when written out.

        1 vote
  3. Power0utage
    Link
    I appreciate the legibility and simplicity of YAML for small, personal project-type configuration files. But I, like many others I'm sure, learned very quickly how messy YAML becomes when the...

    I appreciate the legibility and simplicity of YAML for small, personal project-type configuration files. But I, like many others I'm sure, learned very quickly how messy YAML becomes when the project starts to grow OR you start to depend on configuration for lots and lots of things.

    Something that Symfony (PHP) has that comes with the copious YAML config files is an "Options Resolver" class, which forces validation on their internal configs (or anything else you build it for). So, you could use YAML files and enforce types, value ranges, etc. But unfortunately, you have to build a bunch of boilerplate code in addition to the config, so it becomes very tiring.

    Along those same lines, I just saw the Hacker News post about Pkl which seems like it accomplishes both legibility and some sort of validation.

    6 votes
  4. skybrian
    Link
    From the article: [...] [...]

    From the article:

    So now what, is it a Serious Software Project now? No, it’s still a hobby project without stability promise. I don’t recommend using it for anything serious. But it’s also useful to the point where I expect I’ll keep it in my toolbelt for the forseeable future — if only as a jq replacement. And if it’s useful to me, maybe it’s useful to others, so that’s why I’m writing about it today.

    So what is this language? I call it RCL, named after myself in Bender meme style, but it turns out that rcl is a pretty good file extension and name for a command-line tool. If you prefer, it might stand for Reasonable Configuration Language, or, in classic GNU style, for RCL configuration language.

    The language is a superset of json. [...]

    [...]

    An RCL document is always an expression, and you can evaluate it to a json document with the rcl command-line tool [...]

    [...]

    Abstraction in a single document is nice, but the real power comes from imports. These allow you to break down configuration into small reusable pieces. [...]

    2 votes
  5. [3]
    unkz
    Link
    I feel like xkcd has something applicable to say here. https://xkcd.com/927/ But seriously, we have enough good configuration languages. There's no good reason for this.

    I feel like xkcd has something applicable to say here.

    https://xkcd.com/927/

    But seriously, we have enough good configuration languages. There's no good reason for this.

    1 vote
    1. [2]
      artvandelay
      Link Parent
      The author addresses this in their article. I wouldn't really say there's no reason for it to exist, it seems like a cool hobby project that can be useful in certain circumstances, which is...

      The author addresses this in their article. I wouldn't really say there's no reason for it to exist, it seems like a cool hobby project that can be useful in certain circumstances, which is exactly what the author thinks as well. There are more mature alternatives with bigger communities and more financial backing but its got its own charm and usefulness.

      2 votes
      1. unkz
        Link Parent
        I would go much further and say there are good reasons for this not to exist. It’s superfluous cognitive load to even think about this when it isn’t solving a real problem, and especially to have...

        I would go much further and say there are good reasons for this not to exist. It’s superfluous cognitive load to even think about this when it isn’t solving a real problem, and especially to have to think about the differences between this config language and any of the other more mature languages that we already use.

        When I use a new project and it is configured via toml or json, I’m already an expert in that config language, and so are millions upon millions of other developers. I just need to know the specifics of that project and I’m off to the races.

        This whole thing reminds me of the worst aspect of Perl, which is TIMTOWTDI. Yeah, there could be more than one way to do it, but unless there’s an enormously compelling reason to, we probably shouldn’t.

        1 vote