
In Defense of YAML - rbanffy
https://blog.atomist.com/in-defense-of-yaml
======
bpicolo
> This is not structured data. This is programming masquerading as
> configuration

I find myself expressing this same opinion to people on a frequent basis. See
ansible for another big example. Ansible has a try/catch equivalent in yaml
[0]!

Unfortunately, YAML is more or less a lowest common denominator for these
sorts of interactions - being usable from _any_ language is a really big boon.
Would love to see the world adopt a trivial lisp or similar for this sort of
thing, but that feels a ways off.

Helm 3 introducing lua, for example, is a big step forward. Pretty much
exactly what I've been envisioning for making k8s deployments less crummy, so
I hope they end up with a good product. [1] Helm 2 is using Go-templated YAML,
and it's terribly unergonomic and not particularly maintainable. Until you run
templating, it's not even valid yaml, so text editors are terribly useless in
aiding you with linting.

[0]:
[https://docs.ansible.com/ansible/latest/user_guide/playbooks...](https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html#error-
handling)

[1]: [https://sweetcode.io/a-first-look-at-the-
helm-3-plan/](https://sweetcode.io/a-first-look-at-the-helm-3-plan/)

~~~
joshlemer
What about [https://dhall-lang.org/](https://dhall-lang.org/) ?

~~~
kevin_thibedeau
You can make Tcl as non-Turing complete as you wish. Stripped of most or all
builtin commands, it becomes a flexible configuration language. You can add
back power in small controlled doses as it becomes necessary. You can also
make it more palatable to the cool kids by adding infix assignment and
expression evaluation with a few simple helper procs.

~~~
yellowapple
This was a big part of what motivated me to create OTPCL [1]; using full-blown
Erlang or Elixir for configuration files feels dangerous and heavy-handed, and
I want to be able to readily define DSLs for configuration files instead to
offer better control/safety/ergonomics. Plus, I happen to like Tcl ;)

Imagine being able to go from a foo.app like this:

    
    
        {application,otpcl,
                     [{description,"Open Telecom Platform Command Language"},
                      {vsn,"0.1.0"},
                      {modules,[otpcl,otpcl_env,otpcl_eval,otpcl_init,otpcl_parse,
                                otpcl_shell,otpcl_stdlib,otpcl_stdmeta]},
                      {registered,[]},
                      {applications,[kernel,stdlib]},
                      {licenses,["ISC"]},
                      {links,[{"Bitbucket","https://bitbucket.org/YellowApple/otpcl"},
                              {"GitHub","https://github.com/YellowApple/otpcl"}]}]}.
    

to something more like a foo.app.otpcl:

    
    
        application otpcl {
            description "Open Telecom Platform Command Language"
            vsn 0.1.0
            modules otpcl otpcl_env otpcl_eval otpcl_init otpcl_parse \
                    otpcl_shell otpcl_stdlib otpcl_stdmeta
            registered
            applications kernel stdlib
            licenses ISC
            links {
                Bitbucket "https://bitbucket.org/YellowApple/otpcl"
                GitHub "https://github.com/YellowApple/otpcl"
            }
        }
    

I dunno about you, but I like the latter a lot better :) It ain't a 1:1
representation, but it'd be straightforward to define each of those parameters
as commands that emit the corresponding Erlang forms that make up an actual
app spec.

While OTPCL's by no means ready for primetime yet, I'm hoping it'll eventually
be good enough to fill that niche in the Erlang/OTP ecosystem the same way Tcl
was meant to fill that niche for software in general.

[1]: [https://otpcl.github.io](https://otpcl.github.io) /
[https://github.com/otpcl/otpcl](https://github.com/otpcl/otpcl)

------
actionowl
You want to see a real abuse of YAML? Take a look at SaltStack's Jinja
rendered YAML. I just grabbed a random forumla as an example:
[https://github.com/saltstack-formulas/openssh-
formula/blob/m...](https://github.com/saltstack-formulas/openssh-
formula/blob/master/openssh/gather_host_keys.sls)

~~~
k__
I don't understand why people use a markup language when they need a
programming language.

I mean, sure, you can convert one into the other syntax-wise, both form trees,
but what do you gain?

~~~
cube2222
Because the tools only support markup languages, so we have to use stuff like
Jinja or go templates to create those.

~~~
k__
Sure thing, but Jinja looks like a garbage fire.

Why couldn't they use a regular programming language to create the markup? I
mean this is done with HTML and JS all the time.

~~~
linuxftw
jinja is great, IMO, and well suited for it's intended purpose.

jinja is in wide use in the python community.

~~~
weberc2
Maybe jinja is well-suited to whatever its intended purpose is, but it's not
well-suited for programmatically building markup. Using a dynamically typed
scripting language to generate the markup at least has the benefit of allowing
you to define appropriate semantics via functions ("give me a blob of YAML
that represents a Kubernetes service with these parameters").

Sure, you can probably build your own concept of functions on top of Jinja,
either by embedding them or building your own paradigm on top of Jinja's
template inheritance, but it's a hack either way.

~~~
linuxftw
Well, I think it was originally designed with server-side html templating in
mind. It works great for that purpose.

In the case of thread OP, that template is pretty messy, yes. In ansible, I
would just create a custom module or action plugin in python to spit out
whatever it is I need. I don't know how flexible salt is in this regard, but
ansible is quite flexible.

For simple cases, jinja works great if you're just doing a find/replace type
operation in yaml.

------
onion2k
Something I've never liked about YAML, and I've not found a way around, is
that you can't know if you have the entire file because there isn't an end
marker. If someone cut'n'pastes a block of YAML you don't know if they missed
a bit off the end by mistake (unless you know the schema). That makes it
harder to debug problems with YAML config.

~~~
jw1224
From the YAML spec[1]:

> Three dots ( “...”) indicate the end of a document without starting a new
> one, for use in communication channels

[1]
[https://yaml.org/spec/1.2/spec.html#id2760395](https://yaml.org/spec/1.2/spec.html#id2760395)

~~~
onion2k
Three dots indicates the end of a block, not a document. Look at Example 2.8
in your link.

If the user sends;

    
    
        ---
        time: 20:03:20
        player: Sammy Sosa
        action: strike (miss)
        ...
    

.. you can't know if they actually meant to send ..

    
    
        ---
        time: 20:03:20
        player: Sammy Sosa
        action: strike (miss)
        ...
        ---
        time: 20:03:47
        player: Sammy Sosa
        action: grand slam
        ...
    

Also, in my experience, which is mostly limited to Ansible config because I
prefer JSON, I've _never_ seen three dots in the wild. I don't think devops
people like them.

~~~
calibas
They mark the end of a YML "document", but not the end of a YML "stream",
which can contain multiple documents. It's the terminology that's causing
confusion.

~~~
ams6110
That's interesting, I have always seen the three dots as the _first_ line in a
YAML file, my exposure to YAML being almost exclusively Ansible
configurations.

------
jasonhansel
I really want a good "universal" configuration language (like [https://dhall-
lang.org/](https://dhall-lang.org/)) that can be used to generate arbitrary
text files (e.g. nginx configurations, JSON, YAML, etc.)

~~~
marcyb5st
So, my opinion is based only on perhaps 1h playing with it. I have mixed
feelings about this. It's definitely neat, but I don't like that it adds quite
a bit of cognitive overhead (again, this might be because I'm not fully used
to it). I believe configurations shouldn't force you to think "how will this
be rendered?". For my personal projects I started using protobuffer text
formats as configurations. Having the proto definition is the only docs you
need and you get meaningful errors when you misconfigured/forgot something.

Sure, the text format is quirky, but so far it works quite well for me and
protobuffers (v3) can be easily rendered as JSON.

~~~
krisrm
I agree with this sentiment. I work primarily in web dev, and the stacks are
already so sprawling with different technologies... config file generation
debugging just sounds like unnecessary hassle.

Had not heard of protobuffers before though, and it does look pretty neat.

~~~
marcyb5st
Glad to hear :) I must admit that protobuffers v2 might be best for
configurations files, given that they have the "required" keyword on fields
and the generated code has methods like "hasFieldX() -> bool" which proto v3
dropped in favor of simplicity.

------
undecisive
This whole argument pivots on the idea that you don't need code in your data.

Sure, you _should_ wrap up all the shell commands you plan to use into code
fragments that you can reference. It's neater that way. Suddenly, you have 50
beautifully unit tested objects in your code, each encapsulating a different
way you planned on using 'grep'.

And then you open-source your tool, and hundreds of people descend on it and
yearn to use it in ways unimaginable to you. You then have to decide whether
you're going to a) create a plugin system that allows nicely tested modules in
whatever language the user is most familiar with, b) you wrap all the
functions yourself (good luck!), c) Say "Sorry, my beautiful tool - with is
99% exactly what you need - is totally not for this. Fork it and be gone" \-
or d) let people embed scripting statements or shell commands in some way.

If you have the time for (a) and (b), and this is the issue on which you wish
to sacrifice yourself, more power to you. If (c) makes more sense to you, then
thank you for your input, sorry your project didn't quite take off like you
planned.

But please, don't get upset if people choose (d) and get on with their lives.
Yes, it _might_ cause pain further down the road, but it's their road to
travel.

~~~
tracker1
Thank you... couldn't agree more. It's probably the best option I've
encountered for configurations... Hell, look at apache, Ms config files, xml
config files, they are all nightmarish compared to YAML. Short of an actual
shell script language, it's about as good as we'll ever see.

------
maelito
A substantial part of the french social and tax system is being coded as free
software. One of the teams writes the source code in YAML.

It's not a programming language, but rather a specification for calculable
parts of the law. A JS programm then generates Typeform-like simulators, a
node library, and an online interactive documentation (it is now compulsory
for french administrations to explain their algorithms).

I'm not sure YAML is the good long-term design choice, but as we can't afford
to write our own language, it's bootstrapped the project successfully.

Here is the main file :
[https://github.com/betagouv/syso/blob/master/source/règles/b...](https://github.com/betagouv/syso/blob/master/source/règles/base.yaml)
Don't be afraid by the number of lines, it's just a collection of variables.

~~~
simtel20
Is something typed and better structured (e.g. protobufs) an option?

~~~
tracker1
You can edit YAML with any text editor... how do you edit protobuf files?

~~~
simtel20
There is a text format, but you can serialize YAML into protobufs. The benefit
with protobufs is that by defining them you are specifying types and sub-
messages etc. so when you assemble disparate pieces you get type checking at
various levels.

------
jtreminio
The YAML spec requiring turning "yes" "1" to true, and "no" "0" to false is
one of the most aggravating things about YAML.

~~~
oftenwrong
Also "on" and "off", and variations.

"y|Y|yes|Yes|YES|n|N|no|No|NO |true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF"

[https://yaml.org/type/bool.html](https://yaml.org/type/bool.html)

~~~
stevelosh
"NO" being false is particularly fun:

    
    
        - languages:
          - en # english
          - is # icelandic
          - no # norwegian
          - ja # japanese
          - fr # french
    
        [{"languages": ["en", "is", false, "ja", "fr"]}]

~~~
yellowapple
I feel like 99% of YAML's problems (this being the case in point) would be
solved by just treating everything as a string and letting the application
interpret it whichever way it sees fit.

~~~
slavik81
That's basically the idea behind StrictYaml. Unless you provide a schema, all
fields are parsed as string, list or OrderedDict.

------
peterwwillis
While we're writing the wrongs of badly specified interfaces, can we please
kill this stupid obsession with "writing code" to get work done? Code is
_buggy_. It's difficult to write well, you have to write 10,000 tests for it,
you have to have a testing framework, complex procedures to move it through
pipelines and roll it back and version control it and debug it and maintain it
and deploy it. It's annoying.

I don't want to hand-craft a file like a 14th century woodworker carving out
letters on blocks. I want a program to just make the config or do the
appropriate action for me, based on questions it asks me. I shouldn't have to
write code to do that, or treat a file as code, or use a "language" to get
work done, whenever it is possible (i.e. most of the time).

The only times I ever want a "language" is when I need to do something complex
and iterative, like crafting a search query, or constructing a simple one-line
pipeline of pre-defined functions. Aside from that, crafting configuration and
performing operations should have a _real user interface_.

~~~
smhenderson
So while obviously a bit data UI wise are CPAN's config script and/or the
"make menuconfig" script for compiling a Linux kernel good examples of what
you're talking about?

While I haven't run menuconfig since the 90's I find myself setting up CPAN on
just about every server I manage. Although a bit dated like I said above it's
still very easy to use and provides clear instructions on why you should or
should not choose certain options based on the environment you are setting up.

Just wondering if these are good examples or not. If not, do you have any
other examples of good config programs you can point to?

~~~
peterwwillis
Really any of them are preferable to nothing at all. Yep, CPAN at least does
the bare minimum to get you up and running and saves its configs, you don't
have to do a mini research project just to get it working. I think Jenkins is
a good model for basic web UIs. I wish tools like Terraform and Consul had a
setup UI, but I guess that's how Hashi makes money.

~~~
smhenderson
Thanks, I’m not familiar with Jenkins but I’ll check it out.

I have to admit that I used to spend time reading and painstakingly setting
each and every option in CPAN, some of the time not even understanding why or
what I was setting, but these days I just say yes to “do you want me to try
and configure as much as possible automatically?”. It hasn’t failed me yet!
:-)

Any tool that can do the heavy lifting by poking the environment a bit like
that seemed to fit what you were talking about so that’s why I mentioned it.

------
arkadiytehgraet
I highly agree with inappropriateness of YAML for GitLab CI/CD configuration.
It does work for simple use cases and/or in small repositories - however,
doing something slightly more complicated than a simple build/test/deploy
pipeline takes an immense effort, with a range of hacks and workarounds.

Even the simplest things, like passing some data (e.g. a link) from one job to
another requires quite an overhead (either using artifacts, storing it
somewhere in KV or even something worse).

Moreover, .gitlab-ci.yml is one and only entry-point for the CI configuration,
so everything goes into it. Yes, it does have concept of includes, but even
that is quite limited and not sufficient for any reasonable workflow.

~~~
boleary-gl
GitLab PM for Verify (CI) here.

I agree that a lot of complex pipelines can be tough to express in YAML. One
of our key focuses this year is to make advanced use cases for GitLab CI/CD
more lovable. Specifically, you can see the overall direction here:
[https://about.gitlab.com/direction/verify/](https://about.gitlab.com/direction/verify/).
Some specific issues I'd love feedback from the community on that I'm thinking
about are:

* Directed acyclic graphs (DAG) for pipelines: [https://gitlab.com/gitlab-org/gitlab-ce/issues/47063](https://gitlab.com/gitlab-org/gitlab-ce/issues/47063)

* Make it possible to use any language to generate `.gitlab-ci.yml` and pipelines: [https://gitlab.com/gitlab-org/gitlab-ce/issues/45828](https://gitlab.com/gitlab-org/gitlab-ce/issues/45828)

* First class support for multiple pipelines: [https://gitlab.com/gitlab-org/gitlab-ce/issues/28592](https://gitlab.com/gitlab-org/gitlab-ce/issues/28592)

* Self-modifying pipelines: [https://gitlab.com/gitlab-org/gitlab-ce/issues/44199](https://gitlab.com/gitlab-org/gitlab-ce/issues/44199)

(edited for readability)

~~~
bmurphy1976
DAG's are good. Let me define a DAG in imperative code (any language I want)
using any techniques I want, then I hand the DAG off to you and you execute
it. Anything else is introducing complexity for complexities sake.

------
cpach
Related: If you haven’t seen TOML (”Tom's Obvious, Minimal Language”), have a
look. It seems pretty nice IMHO.

[https://github.com/toml-lang/toml](https://github.com/toml-lang/toml)

~~~
holy_city
Nested schemas are pretty disgusting in TOML. Granted, there's an argument
against having deeply nested schemas in the first place.

------
lmm
Article fails to live up to its title and offer any defense of YAML,
specifically.

Yes, a lot of YAML abuse consists of trying to pretend code is config, and
that problem exists for any config format. However YAML specifically is also a
uniquely bad config format, even when used for plain config; too many obscure
corner cases (e.g. the abbreviation for Norway turning into false, port
mappings turning into times when the ends in a number...)

------
philipov
> Note the script block containing a list of shell scripts. Does this look
> like data?

Code is Data! Lisp-it or Quit!

~~~
krapp
One of these days, I want to come up with a non Turing complete s-expression
based config format (basically something like a Lispy JSON) and post it here
just to watch Lispers rage at not being able to write DSLs in it.

~~~
jimbokun
But...they will be able to write DSLs in it. Just create functions with the
same name as the head atom of the top level lists, then run the config file as
a program. Or write macros matching the syntax of your format to generate
code.

I mean, maybe there is something about your format that makes these specific
approachs inconvenient. But once you give a Lisper a bunch of S-expressions,
you just opened the door for them to unleash the full power of Lisp upon it.

So I think your plan to frustrate Lispers by making an S-expression based
format popular, will just give them even more power.

~~~
taeric
I don't think many non lispers realize that you can pass the same structure to
different parts of your program for different manipulations or executions.
Truly, the code as data mantra is just too removed from most languages. It is
too easy to think eval is something that can just take in a string, at best.
Completely missing that you can literally change how your code is evaluated.

------
AstroJetson
I'm a big fan of using Lua for this. You can put all the configurations you
want in a fairly readable format and then if you need to, custom Lua code to
get process for the hard parts. The receiving end has the ability to decide if
it wants to run the custom code or not for security reasons.

I saw the comment that Helm is going to include Lua, but not getting the
advantage that Helm brings over base Lua.

------
gaogao
You can actually use Python as a configuration file pretty well, if you need
more complicated logic and macros. Otherwise, sticking to a toml or ini file
is my preference.

~~~
lmm
Are you gonna embed a Python interpreter into your C# programs though? Better
to use something like dhall that's at least open to being loaded from multiple
languages.

~~~
zimablue
I like your point, it goes against the lambda-ultimate post linked separately
in the thread. If you accept your point (cross-lang-loading) and accept the
LTU argument about the benefits of internal DSLs (you're not slowly
reinventing a useful turing-complete language) then you would maybe want to
use a very simple, easily interpreted language for your DSL and embed an
interpreter for that. (I (can't (think (of any though))))

~~~
lmm
> then you would maybe want to use a very simple, easily interpreted language
> for your DSL

Right, which is essentially what Dhall is. There aren't any established "real"
programming languages that are restricted enough (non-Turing complete, etc.)
to use for this kind of case.

> (I (can't (think (of any though))))

S-expressions are never going to succeed; there are too many subtly
incompatible variations going around already, and their fans are unwilling to
compromise and agree on a common standard.

------
js2
I’m glad I read the internal vs external DSL discussion two links away from
the article:

[http://lambda-the-ultimate.org/node/4560](http://lambda-the-
ultimate.org/node/4560)

------
zeveb
Alternatively, if you're programming _and_ you want a structured data format,
use S-expressions! They are basically tailor-made for exactly this problem.

    
    
        (gitlab:assets:compile
         #%dedicate-no-docs-pull-cache-job
         (image "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.5.3-git-2.18-chrome-71.0-node-8.x-yarn-1.12-graphicsmagick-1.3.29-docker-18.06.1")
         (dependencies
          setup-test-env)
         (services
          (docker stable-dind))
         (variables
          (NODE_ENV production)
          (RAILS_ENV production)
          (SETUP_DB false)
          (SKIP_STORAGE_VALIDATION true)
          (WEBPACK_REPORT true)
          ;; we override the max_old_space_size to prevent OOM errors
          (NODE_OPTIONS "--max_old_space_size=3584")
          (DOCKER_DRIVER overlay2)
          (DOCKER_HOST "tcp://docker:2375"))
         (script
          "node --version"
          "yarn install --frozen-lockfile --production --cache-folder .yarn-cache"
          "free -m"
          "bundle exec rake gitlab:assets:compile"
          "time scripts/build_assets_image"
          "scripts/clean-old-cached-assets")
         (artifacts
          (webpack-report
           (expire-in 31d)
           (paths
            "webpack-report"
            "public/assets/"))))
    

And that’s just a first cut; it could be made much nicer.

~~~
lmm
> And that’s just a first cut; it could be made much nicer.

This is exactly the problem with S-expressions. No-one is willing to define
what "good enough" looks like and create a fixed, reusable standard for how
you represent these things. Instead everyone hand-rolls their own, subtly
incompatible variant.

~~~
taeric
Whatever is the final evaluator gets to define what is required. Beyond that,
give your users the power to do it their way. Or they will find a way to get
it themselves.

~~~
lmm
> Whatever is the final evaluator gets to define what is required.

Which is completely useless, because it means everyone will do it differently.

> Beyond that, give your users the power to do it their way. Or they will find
> a way to get it themselves.

Users put value on having a standard set of scaffolding. That's why these
standardised config formats have succeeded.

~~~
taeric
Have you seen the plethora of templating engines used to generate the yaml
configs out there? I am surrounded by folks that think Jinja to create yaml is
a normal idea. Good, even.

Then there is the slow creep of Turing into config for the sake of dynamic
config. Starts as a simple condition flag. Then add if/then logic. It is an
amusing tread.

So, yes. You can get a lot of variety in how configs look. But at the end if
the day, they should all work. Usually in much more explainable terms. Just
look at most people's emacs config. There are good options to make those
readable today. It is still not that hard to see how most people's have worked
for a long time.

~~~
lmm
Are those options agreed on and used consistently though? Other people's emacs
configs are even more notoriously unreadable than Jinja-templated yaml, IME.

~~~
taeric
I've found emacs configs are actually not that bad, all told. There can be a
lot there, and some are certainly more organized than others, but just
figuring out what is happening is usually not hard.

Reading people's CloudFormation and related templates? Especially if they are
done using jinja or some other yaml generation trick? Near impossible.

To directly answer your question, though. No, it does not appear that anyone
agrees on how to generate config for things. Which is why every team I join
seems to have invented a new way for doing it, all in the name of
"maintainability." I often get dirty looks for suggesting that people not
build automation on top of the config before they have proven it is truly
needed with experience. (That is, if this is your first config to create, do
it by hand for the reviewability, if for no other reason.)

------
decasia
OK, I totally get the argument that YAML is for data and not programming. But
I'm not sure the line between them is always clear.

For example: I used to use YAML to define field mappings between external data
and internal models in a Rails application.

like:

    
    
      - src: fieldA
        dest: field_a
        filter: name_of_some_filter_function
    
    

Is this programming? Data? Really it's configuration for an import library,
but I find the line blurry.

~~~
fendy3002
Imo that's data, except if the filter is an executable script. For me, the
programming part in yaml is string, either single, array or multiline, that
will be compiled, executed or eval-ed.

In your case, it can be defended as documentation for data mapping, but
executable scripts are rarely so.

~~~
philipov
I once built an interpreter that parsed YAML files as s-expressions, just to
watch them scream. I called it YAMlisp, because it's better than a potato.

------
AaronFriel
At my work we've started rolling out Pulumi as an alternative to YAML hell.
The advantages are numerous. It's an integrated programming environment for
devops, and engineers can split config and data or unify them as relevant.
Sometimes a mix is good!

The TypeScript SDK is extremely thorough and type driven, enabling non-devops
engineers to catch more errors before it's run, and it extensively uses
asynchrony to build up a graph of resources needed, even if those are across
platforms. e.g.: We create a project in Google Cloud, then create a service
account, then we create a GKE cluster, then a namespace in the cluster when
that's available, then we create roles, ... all of this falls out of simply
using their SDK, the resolution of the DAG and awaiting of results is done
automatically with some nifty types (almost all inputs can take a promise-like
value instead of a POD data type.)

------
Communitivity
If you haven't seen EDN (Extensible Data Notation), it might be worth a look.
It was developed by Rich Hickey as a JSON alternative, for use in Clojure.
I've found it to be very useful, and not just in Clojure. For example there is
an edn crate in Rust.

* [https://github.com/edn-format/edn](https://github.com/edn-format/edn) * [https://learnxinyminutes.com/docs/edn/](https://learnxinyminutes.com/docs/edn/) * [https://www.compoundtheory.com/clojure-edn-walkthrough/](https://www.compoundtheory.com/clojure-edn-walkthrough/)

------
gomoboo
The configuration method for the Gunicorn server
([http://docs.gunicorn.org/en/stable/configure.html#configurat...](http://docs.gunicorn.org/en/stable/configure.html#configuration-
file)) would be a great example to follow. Configuration files are just Python
modules. You can specify the number of workers and set log file locations with
the following:

    
    
      from multiprocessing import cpu_count
    
      def max_workers():
         return cpu_count() * 2 + 1
    
      workers = max_workers()
      errorlog = "/var/www/lcfs/logs/error_logs.log"
      accesslog = "/var/www/lcfs/logs/access_logs.log"

~~~
taeric
You should see how people configure their emacs setups. :D

~~~
d0mine
use-package is a nice declarative way to configure packages in .emacs

~~~
taeric
And it is just a standard macro. Nothing built into emacs to support it.

My point being that just having some code to configure your thing is not
exactly novel. Just not commonly done. Outside of lisp communities.

------
kristiandupont
Slightly related, I just made a Webpack plugin that lets you use Markdown as
configuration data: [https://www.npmjs.com/package/mdconf-
loader](https://www.npmjs.com/package/mdconf-loader)

I've been playing with ways of entering test data for years. At Triggerz where
I have worked, we use Excel heavily. That works really well but I have to open
Excel or LibreCalc to edit the files, which feels really slow and annoying
compared to all other files that I can keep in my editor. There is a read-only
plugin for VSCode but not yet one that lets me edit.

Markdown tables are quite easy to write when the editor supports them (i.e.
auto-formatting), and work pretty well for me.

------
_bxg1
I can't help wonder how much better YAML would've been with minimal delimiters
instead of significant-whitespace. The big feature (X/YA)ML has over JSON is
distinction between properties and children; which I think is pretty cool for
many use-cases. Lack of comments is also a big limitation of JSON, and of
course there's the huge legacy ecosystem behind XML. But I've never seen
significant whitespace be a good thing; this alone makes YAML decidedly not
"human readable", speaking as someone who doesn't work with it very often.

------
mirages
I'm usally confronted at YAML when I setup gameservers of some indie games
(I'm looking at you Empyrion) and I find it extremely painful to handle.

When you have sevral configuration files where you have to change/tweak data I
always end up pulling my hairs why stuff isn't working because of an extra
space lying anywhere in the file.

Please don't use YAML for anything that has to be edited by a human

INI, XML, JSON are all formats that are more forgivable regarding that (oh and
always trim anything you parse. The more you do to help against accidental
input, the less admins you'll have ;)

~~~
virtualized
It's weird how languages like YAML, XML and JSON are very much designed for
communication between machines, but are still the default choice for human
input. Actual programming languages - designed for use by people - are rarely
considered for high level configuration.

I have actually seen something similar to this happen:

1\. We just need a few configuration options. Let's add an XML configuration
file.

2\. Keeping all the configuration files in sync for different environments is
a lot of work and really error-prone. Let's generate all the configuration
files. What about an XML meta-configuration file?

3\. Some things are different between environments. We need conditionals in
our XML meta-configuration language.

4\. There is a lot of repetitive configuration. It would be more maintainable
if we had loops, variables, integers, string interpolation, functions, ... in
our XML meta-configuration language.

Great, now we invented our own awful programming language that lacks any
tooling, documentation or libraries and isn't compatible with anything else.

~~~
krapp
>It's weird how languages like YAML, XML and JSON are very much designed for
communication between machines, but are still the default choice for human
input. Actual programming languages - designed for use by people - are rarely
considered for high level configuration.

What are you talking about? YAML, XML (particularly HTML) and JSON were always
intended to be written by and understood by human beings, no less so than any
"programming language." All of these were designed to be "used by people"
_and_ machines.

>Actual programming languages - designed for use by people - are rarely
considered for high level configuration.

And the rest of your comment illustrates why. What you have when you use a
programming language for "high level configuration" isn't configuration.
Configuration should describe constant state, not operate on or transform
mutable state. What you have, then, is just more application layer, on top of
your application.

Which you don't have with JSON. Or INI. And you do still kind of have with
YAML, and definitely can with XML, but that's why a lot of people don't like
YAML or XML when it gets too complex.

What it looks like your example shows is dumping unnecessary complexity into
configuration in order to maintain "simplicity" in the application. You would
have the exact same problem using a high level programming language, it would
just be potentially infinitely worse with the explosion of complexity and
feature creep that comes with it.

------
feanaro
Many comments here make the point that configuration languages often pretend
to be code and they do so badly. The conclusion is then that we should simply
use code instead.

I'd like to propose that there is no fundamental distinction between code and
configuration languages. The distinction is actually between total and non-
total (Turing-complete) languages. Configuration languages are just
programming languages of varying complexity. Some of them are total (i.e. non-
Turing-complete) and that's a good thing.

------
pducks32
Recently been working on a rails app and been forced to use nano for editing
one a remote server and it's now that I really see the niceness of YAML. I
always like YAML with ruby but I think a lot of the great features are subtle
and hard to appreciate. Inheritance! What a great idea for a configuration
language. Greatly missed in JSON.

~~~
tracker1
Anything you can express in YAML, you can express in JSON. I'm not saying I
would choose JSON over YAML for configuration... but it's definitely not
lacking in equal flexibility in use for structure.

------
aboutruby
I wish there was a .safe_yaml or something that would just use YAML.safe_load,
would get rids of most of the YAML issues for me.

------
yellowapple
On the flip-side, if you were to embrace using YAML for programming (i.e. by
creating a programming "language" by treating certain YAML constructs
specially), you'd likely end up with a homoiconic Lispy language (albeit a
very weird one), just using YAML instead of S-expressions (maybe call 'em
Y-expressions?).

------
fendy3002
While there are no other format with clear advantage over YAML, I wonder why
nobody use javascript with modules as programmable configuration.

Can be broken to file parts, support comment, variable, functions or scripts.
And with additional extension can import packages. Though the downside may be
JSON format that's noticably bigger than yaml.

~~~
ams6110
I think JSON is almost always better than YAML, except for very simple cases.

~~~
stubish
I feel it is always better for programs to accept YAML than JSON, because then
you can feed it either YAML or JSON (all valid JSON is also valid YAML).

------
obiefernandez
I can't be the only one that sees the historical irony in Rod Johnson being
the one to write up this opinion? (Then again, you could argue that he's
speaking from experience.)

Over fifteen years ago I was in programming as configuration hell with
Interface21, and later Spring-based enterprise Java stuff...

------
jimbokun
This article is one of the best arguments I've read in favor of Lisp in a long
time.

Code is data is code.

------
Waterluvian
My favourite configuration style is used by Django it's just a Python file.
And the result is I can do things like have base.py devel.py staging.py
prod.py

All with any form of inheritance or programmatically derived settings I see
fit.

ROS2 is going the same way too.

------
jpomykala
Why we even have something like yaml? We already got JSON, same key value
format, but more reliable. I remember my first docker experience was ruined
because of yaml and wrong formatting.

~~~
theonemind
YAML predates JSON as far as I know.

------
coldtea
YAML is so badly designed, it shouldn't be used for data either.

------
Freak_NL
At the bottom of that blog post:

> Djikstra

Dijkstra. Please!

------
karate-fu
JSON for everything. Done.

------
Ari_Ugwu
+1000 fake internet points to this article for keeping it short with clear
examples.

