
Dhall: A Non-Repetitive Alternative to YAML - ff_
https://dhall-lang.org/
======
zeliard
Couple of contenders:

\- Jsonnet ([https://jsonnet.org/](https://jsonnet.org/)) - simpler syntax and
less concepts to learn, just an extension of JSON. But no type checking. An
open source offspring of Google's internal config language (GCL/BCL)

\- Cue ([https://github.com/cuelang/cue](https://github.com/cuelang/cue)) - a
more ambitious attempt to fix GCL/BCL by replacing inheritance as the
fundamental compositional primitive with constraint unification.

Great thread comparing them against each other by the authors of both:
[https://github.com/cuelang/cue/issues/33](https://github.com/cuelang/cue/issues/33)

Cue seems kind of similar to Dhall on first sight, but I haven't used either
enough for an informed opinion yet.

~~~
dharmab
We tried to introduce Jsonnet at our org. It failed miserably because ops kept
mistaking the name for JSON which they hated. (International multilingual
team).

It was a real shame because ops then implemented some features of Jsonnet via
scripts to to parse and merge YAML. What was 0 LOC in Jsonnet is now about 300
LOC plus custom CI checkers, all because of a marketing problem.

~~~
Fnoord
If I go to the mentioned Jsonnet homepage it says "A simple extension of
JSON". The graphic explains its relation to JSON. The example looks awfully
similar to JSON.

What I don't understand is the following: config files are read by text
editors, and in the end, by human beings. Because of the latter they should
have certain traits. We must agree on the importance of these traits before we
can settle on a standard.

For me, important features are that they must be readable, and easily
editable. They must be readable with a certain text editor (vi) for backwards
compatibility. So that means it shouldn't require syntax highlighting or
schema. Well, these 2 simple requirements of mine rule out anything remotely
resembling JSON.

It just appears to me that JSON is for JavaScript developers, YAML for Python
developers, and Dhall for ML (the whole family I suppose, not just Haskell)
developers.

Well then if we're going that route then perhaps all we need is some kind of
glue between text config and binary config (which reminds me of Systemd...).
Ie. that it accepts multiple config file formats.

~~~
jholman
I'm a little confused by one part of what you wrote. You say that your config
files must be readable by vi, and that in turn adds a no-highlighting-required
constraint and a no-schema-required constraint, and that in turn adds a no-
JSON-nor-anything-like-it constraint.

I deal with JSON all the time in vim, effortlessly. I'd be willing to deal
with it in Notepad if necessary, and certainly in non-vim vi. Pipe it through
a prettifier (lately I use `jq . file.json`) if necessary.

I don't need syntax highlighting, and I don't need a formalized schema
(although I certainly appreciate an informal one, interpreted by the 1.0 Human
Meatbrain I carry around). Also, if by "vi" you meant "vim", this is EVEN MORE
confusing, because vim syntax-highlights JSON.

~~~
Fnoord
With vi I mean vi, not vim. If I meant vim, I'd have written vim. I use vim if
its available (with my own configuration which includes syntax highlighting),
but it isn't always available.

With my Human Meatbrain syntax highlighter I have far more issues with JSON
than with say YAML or any other markup language.

Consider, for example, how easy the syntax is of a Wireguard configuration
file. It is basically akin to a shell script or ini configuration file. And
these have a proven track record. Why is that way of configuration broken in
the first place? You could do things such as variables in shell scripts as
well.

I also believe that the whole Systemd drama is basically because of moving
away from such a proven track record. And it might very well be true that
shell scripts are slow. That is why I argue for backwards compatibility and
converting to/from formats. Which is something Dhall is able to (it can
convert to/from YAML and JSON).

------
jrudolph
Dhall is an awesome tool to have in your DevOps tool belt - we're heavy dhall
users at meshcloud [0] and couldn't be happier about it. We picked it after
evaluating a long list of contenders (yaml madness with anchors, jsonnet,
ksonnet, j2/jinja, a hacked ejs compiler [1] and some more I forgot). It's so
good we're looking into how we can give back/donate to the project.

Dhall elegantly solves a major challenge: configuration management at scale.
We build a multi-cloud management platform, which serves DevOps teams, IT
Governance, Controlling and IT Management in large enterprises. That means
we're an integration solution for a lot of things, so we need to be highly
configurable. Because we also manage private clouds (a la OpenStack, Cloud
Foundry, OpenShift etc.), we often run on-premises and operate our software as
a managed service. Using dhall allows us to _compile and type check_ all our
configuration for all our customers before rolling things out. We use dhall to
compile everything from terraform/ansible, kubernetes templates, spring
config, to concourse ci pipelines and customer-specific reference data to load
into our product. Since adopting dhall earlier this year, we measurably
reduced our deployment defect rate and re-gained the ability to safely
refactor configuration.

It takes a little time to get used to, but we appreciate that it's highly
opinionated around formatting and "how to do things" \- somewhat in the same
way as golang is. It has certainly helped that we had a member with haskell
experience on the team, as dhall is built in haskell and the syntax feels
familiar.

Plug: if you're looking for a job working with dhall, reach out :-)

\- 0: [https://meshcloud.io](https://meshcloud.io) \- 1:
[https://github.com/Meshcloud/ejs-compiler](https://github.com/Meshcloud/ejs-
compiler)

~~~
tedmiston
Heads up - Your naked subdomain redirect to www doesn't seem to be working. If
I go to www directly, I don't get the timeout.

~~~
jrudolph
thanks! turns out it wasn't working for https, should be fixed now.

~~~
tedmiston
working for me now as well

------
adev_
For a pragmatic, _really_ readable configuration file format, TOML never
disappointed me ( [https://github.com/toml-lang/toml#user-content-local-
date](https://github.com/toml-lang/toml#user-content-local-date) ).

\- This is human readable contrary to the JSON family and its {} abuses.

\- It is not space / ident base contrary to YAML that becomes very quickly a
mess to write and a mess to parse.

~~~
nikolay
TOML is _almost_ perfect. The only things I don't like are the need for commas
and the double brackets.

~~~
smitty1e
Perfection is a bugaboo. Give me 95%, minor inconveniences, and declare
vict'ry, say I.

------
markandrewj
My comment isn't specifically about Dhall, but about the note on Turing
completeness. I often read comments about how YAML/JSON is not turning
complete. These comments normally frame the lack of Turing completeness as
being a short coming of the format(s). I find this interesting because one the
reasons that the industry moved away from XML was to have cleaner separation
between data and logic. I generally tend to think that it is cleaner to
separate logic and data, instead of creating a tight coupling. I don't read
many people making comments from this perspective though. I am not trying to
say we can't do better then YAML/JSON, I am just trying to offer some food for
thought. I tend to view JSON/YAML as a data exchange format, and not a
programming language, so I am not bothered by the lack of Turing completeness.

~~~
nine_k
Not being Turing-complete is a feature.

A Turing-complete language allows to write programs that never terminate. This
is not what a config file should be capable of.

~~~
dharmab
Previously in my career I've abused Jinja templating to build "scripts" out of
Ansible and SaltStack YAML. It solved business problems effectively but I'm
sure when I left that role I passed on a big plate of spaghetti to my
successor with minimal automated tests.

If it depends on conditional logic or iteration, it probably belongs in a
proper programming language with a linter, type checkers, debugger and unit
test framework.

~~~
eropple
This is one of the reasons why, coming from a background of writing Chef and
writing exhaustive testing around my configuration management, I've never been
able to deal with Ansible without grinding my teeth. Or, for that matter,
Terraform; HCL is godawful and trying to write it in JSON is a sucker's bet,
too. With the move towards more containerized systems I don't write Chef much
anymore (thankfully), but Terraform has become ever more of a boil on my rear
end. Fortunately there's also Pulumi now and writing this stuff in TypeScript
is a lot faster and feels really good.

~~~
markandrewj
The thing is, although Ansible is not perfect, it is python. When you are
writing playbooks you should be defining the state of the world, if you are
writing custom logic it is probably best to write a custom module, which are
commonly unit tested. I haven't tried Pulumi yet, thanks for pointing it out.

~~~
_frkl
I'm not quite ready yet (esp. documentation is lacking), but I'm working on
something to get the best of both worlds:
[https://freckles.io](https://freckles.io)

Basically, you write your state-defining code in Ansible, using either
modules, tasklists, roles, or a combination thereof. 'freckles' lets you wrap
those up in re-usable, distinct, atomic units which you can combine for more
complex tasks. Then you can use those directly via the command-line, or you
can auto-generate (wrapper) Python (will do other languages later) classes
from them (e.g.
[https://freckles.io/doc/interfaces/python#code](https://freckles.io/doc/interfaces/python#code)
), for when there is more 'logic' to be implemented.

I reckon it's a bit like Pulumi, but it is less opinionated. Actually, it's
probably more like it lets you create your own little domain-specific Pulumi,
if that makes any sense. It also works really well as a wrapper for Packer and
Terraform.

As I said, documentation is not quite there yet, but most of the important
stuff works. Starting to look for people to try it out, if anybody on here is
interested.

~~~
eropple
First off: congratulations on shipping something! Shipping is hard.

But this misses the mark. With respect, and I'm trying to not not dunking on
your project, to me Ansible is the worst of every world and is emblematic of
configuration management retreating from the realm of "infrastructure as code"
to "infrastructure as magic notepad files because incurious sysadmins won't
_write_ code.". I don't really care that Ansible is being wrapped so long as,
inevitably, I'm going to have to go deal with that when it breaks. Eventually
Pulumi/Terraform will break too, and there is no _programming_ language I have
more eyerolls for than Golang, but at least it's a programming language, you
know? (And I really don't relish the thought of ping-ponging from the Python
wrapper to YAML hell to a Python module, tbh.)

The biggest thing that a project like Freckles fails to capture, and where
Pulumi shines, is that _it 's all code and you just treat it as code_. They're
compiler wonks, or at least the guy I know there is one, and they leverage
that--when dealing with stuff like Lambdas/GCP Cloud Functions, you just write
them inline and they're hoisted into deployable packages without comment or
incident. There's no zipping of files, there's no messing around--you wrote a
function to do a thing and it gets run. Done-and-done.

It's got a lot of other nice features, but that it is transparently code, and
that they're investing most of their effort (it seems) into hiding the
unfortunate fact that eventually some Terraform providers get run, makes
Pulumi a really hard one to top.

~~~
_frkl
Fair enough, I can see some of your points, but (obviously) I don't think they
are entirely relevant, and my experience and view of Ansible is a different
one.

Also, Ansible is only one backend for freckles, it's just the first one I
implemented because of all the roles and modules already available for it.
There will be a Terraform backend, and a Packer one, and a Kubernetes one too,
probably. And I'm actually much more excited about the shell backend I have in
mind, but that is much more work to create a repository of tasks for. You'll
be able to just select one of those backends, or combine all of them.

The goal is for 'end-users' never having to deal with underlying backends and
Ansible code and the like, if they don't want to. Those are just there to
provide the building blocks end users would use to compose their
provisioning/orchestration -- which they can do entirely in code. I hope to
have a stable 'stdlib' of such tasks at some point, comparable to what is
available in Pulumi, which people can just use without any other concern.

I don't know how Pulumi works under the hood, are you saying they basically
wrap Terraform modules? If that's the case, that's not that different to how
freckles works. With the exception that freckles can also be used for non-
cloud things.

------
oalessandr
I'm trying to use it for Kubernetes since it can both work like helm
(paramerizing functions) and kustomize (using the merge // operator). Moreover
it has (safe) imports which make defining constants quite easy.

There are already kubernetes bindings available [https://github.com/dhall-
lang/dhall-kubernetes](https://github.com/dhall-lang/dhall-kubernetes) .

The syntax in the examples looks a bit more verbose and less readable than
yaml but I think building sensible abstractions on top of it will alleviate
the pain (abstractions here are innocuous since you can 'normalize' the code
and they disappear)

I'm not too happy with the default formatting though. I think if the formatter
indented nested values similar to yaml that would look better to the human
eye.

~~~
amluto
> Moreover it has (safe) imports which make defining constants quite easy.

I read about dhall’s imports, and I don’t think I like it. If I add a text
configuration mechanism to software, I do not want it accessing the network by
default, full stop. To me, a “safe” configuration language means that parsing
terminates, does not have side effects, does not touch the network, and that
parsing the same file twice gives the same output unless I _explicitly_ change
an input. Pulling a prelude off of github does misses several of these
requirements.

(Having your config file fail to parse if your network is down is bad, bad
news if that config is needed to bring your network up. It’s also bad news if
a parsing failure due to a transient network issue leaves your system in a
state where it won’t quickly recover if the network comes back.)

~~~
jose_zap
You can still do that, though. In Dhall you may import things remotely as you
develop and then tell Dhall to pre-fetch the result, you can commit that and
it will not access anything.

You may also just download any imports yourself and source them locally.

Additionally Dhall supports import fallbacks, for example you may try first a
remote import, and if it fails it will look for another place, which I’ve
could be remote or local. This is a good strategy for developing locally and
then committing imports for production use.

You can also, of course, host the files in your local network.

------
dang
Thread from 2018:
[https://news.ycombinator.com/item?id=17523623](https://news.ycombinator.com/item?id=17523623)

2017:
[https://news.ycombinator.com/item?id=15185015](https://news.ycombinator.com/item?id=15185015)

2016:
[https://news.ycombinator.com/item?id=13109672](https://news.ycombinator.com/item?id=13109672)

------
hjk05
This isn’t an alternative to yaml. It’s a yaml generator. To me it’s not
competing with yaml it’s competing with python or Haskell, and i’d argue that
putting yet another language in your stack just for generating config files is
added unneeded complexity. And sure while both python and Haskell are Turing
complete, how often do we actually run into issues when generations flat
config files? I mean I’ve never had that issue, and I’ve never caught myself
thinking “if only there was a nice way to limit myself to a non Turing
complete subset of python/Haskell”...

~~~
eridius
That's kind of like saying C isn't an alternative to assembly, it's an
assembly generator.

~~~
HelloNurse
On a practical level, C is an alternative to assembly because the appropriate
black-box tools and combinations of tools allow the user to easily turn source
code in either Language or a combination of both into an executable.

Generating assembly from C is an implementation detail, and many C compilers
don't do that.

On the other hand, Dhall really is a YAML generator: the available tools allow
only one-way conversion (in particular, there is no interpreter/library to
ingest Dhall from the configured application itself).

~~~
eridius
Dhall is also a JSON generator. And you could write your own Dhall
implementation that lets you consume it directly from an application if you
want to, it's just nobody's considered that worth doing.

~~~
hjk05
Which is odd because tons of applications in the wild already have this
amazing capability of directly consuming python and Haskell without first
converting to yaml. But of cause you still have the ability to both produce
and consume yaml if that’s needed for some reason.

~~~
eridius
What applications directly consume Haskell code? The only examples I can think
of off the top of my head are apps written in Haskell that actually get
recompiled any time you change the "configuration" Haskell code.

As for Python, that's because the Python interpreter can be embedded in an
app.

That said, Dhall is exposed as a Haskell library, so if you're writing a
Haskell app you could consume Dhall directly and skip the YAML.
[https://hackage.haskell.org/package/dhall-1.24.0/docs/Dhall-...](https://hackage.haskell.org/package/dhall-1.24.0/docs/Dhall-
Tutorial.html) shows examples of this.

------
cryptonector
If you have functions that can call functions, you'd better not have recursion
if you want to not be Turing-complete.

Non-Turing-completeness is certainly very important in many cases (e.g., in
DTrace and eBPF), but I'm not sure that it's so important for _configuration_.
Assuming for a moment that I don't need non-Turing-completeness for
configuration, my choice of DSL would be jq[0]! Using jq for configuration
means that I can use JSON, TOML-style, and other ways of expressing complex
data, including combinations of them, all with "interpolation" (not quite) and
complex computation being available.

    
    
      [0] https://stedolan.github.io/jq/

~~~
Quekid5
One valuable point of Dhall is that it is _programmable_ (yet not TC) in such
a way to that you can e.g. describe a _whole system_ entirely in Dhall and
then (in Dhall!) derive whatever further configurations (plural!) you need
from that. This is much more feasible than in e.g. YAML because Dhall is
strongly typed.

So you could describe e.g. a cluster of machines entirely in Dhall and derive
Ansible YAML scripts (with all their boilerplate), derive DNS config files,
etc. etc. all from a single strongly typed description.

~~~
cryptonector
I mean, jq is a powerful programming language. Did you look at the link I
posted?

~~~
Quekid5
Sure, I'm familiar with it. It's nothing compared to what Dhall can do.

... unless of course it's grown to a similar point. As of about a year ago,
for some complex transformations I had to stitch together multiple invocations
of jq using pipes, etc. etc. That may have been my inexperience with using it,
though.

Regardless, the point about typing stands. Dhall uses structural
typing/subtyping which turns out to be hugely useful for config
transformation.

~~~
cryptonector
I never have to "stitch together multiple invocations of jq using pipes".
There was a time when I did have to, but that was years ago, and it now has
the features needed to avoid that. Not sure what the point about typing was --
you can do the same derivation of data from a master entity with or without
strong typing (though my preference is always for strong typing, which jq
lacks).

~~~
Quekid5
> you can do the same derivation of data from a master entity with or without
> strong typing (though my preference is always for strong typing, which jq
> lacks).

Yes, of course you can. The point is that the strong typing helps prevent
inadvertent and hard-to-spot mistakes. In jq even simple typos of a field name
can lead to "empty result set" silent failures instead of "what do you mean!"
loud failures. That's a big thing.

~~~
cryptonector
Strong typing generally doesn't speak to "how many values this expression
should produce", only their types. Not saying it couldn't, but that even in
Haskell you don't quite get that.

~~~
Quekid5
I was talking about a mismatched field name. What case are you talking about?

EDIT: Actually, responding to

> Strong typing generally doesn't speak to "how many values this expression
> should produce"

Have you heard of affine/linear types?

------
nikolay
Dhall keeps popping up on HN. Here what I don't like about it:

\- Why use '=' instead of ':' for attributes? If you used ':', then '=' could
be variable assignment and eliminate the need for 'let'.

\- Why is there a need for commas?

\- Why quote via ticks?! Gee!

\- What's with the '{-' and '-}' for comments?! It's like its author decided
to differ _at any price_!

In general, good ideas, but it's too weird and unnecessarily deviates from
common syntax.

~~~
duijf
Dhall heavily borrows both ideas and syntax from the ML family of languages.
E.g. Haskell, OCaml, Elm, Purescript

Colons are used for type signatures.

Commas are presumably required because you can have multi line and nested
records. (don't quote me on this, not a parser expert)

The comment syntax is from Haskell.

Not saying this syntax is familiar to _everyone_ , but it is familiar to some.
The lineage of the syntax might help you understand where the language is
coming from

~~~
dymk
Weird that it's billed as an alternative to YAML, but effectively has zero
roots or influence from YAML. Looks more like an alternative to... whatever
configuration language is popular in ML language projects?

~~~
Vosporos
So? They live in the same solution domain for the same problem. Moreover,
Dhall can generate (typechecked) YAML and JSON.

~~~
dymk
It's not even in the same solution space. I can't replace my YAML with Dhall
and consume it directly. I have to now depend on the converter to go from
Dhall -> YAML/JSON. All I did was add another layer of complexity into my
config.

Maybe you'll benefit from the added abstraction; I see the value in having
"typed" configs that are semi-scriptable but not turing complete. But it's in
no way a "replacement".

~~~
Jeff_Brown
> All I did was add another layer of complexity

If that was in fact all you had done, it would not be worth it. But it might
remove a ton of boilerplate from your YAML.

~~~
LoSboccacc
or, one can eliminate boilerplate in code so that configuration stays simple
and the logic in the application

I mean what's the role of configuration? is so that installer can tune or
match environments. if configuration becomes as hard as your program to
understand then installation won't ever scale

------
andybak
Immediate response?

I hate commas at the start of lines and I would prefer not to have curly
braces in a human editable/readable format.

Neither reason is terribly rational but my first impressions weren't great.

~~~
piotrkubisa
It looks that Dhall has been inspired of the Elm language [0] and it's
formatter.

[0]: [https://guide.elm-lang.org/](https://guide.elm-lang.org/)

~~~
bvaldivielso
It's a common practice in the Haskell community. Knowing where the creator of
dhall comes from I would say that that's the source of inspiration

~~~
Gabriel439
Author here: the syntax is inspired by all three of Haskell/PureScript/Elm

------
tobr
So far, only comments complaining about syntax. You can do better, HN!

~~~
nikolay
Yeah, because that's what most configuration languages differ in.

~~~
kccqzy
And yet, in focusing on the syntax, you missed the biggest difference between
Dhall and other configuration languages: safe, termination-guaranteed non-
Turing-complete computation.

~~~
nikolay
How is it better than Jsonnet or Starlark?

~~~
mbrock
static type system

~~~
nikolay
True. But isn't this also accomplished when pairing JSON with JSON Schema?

~~~
jose_zap
The schema applies to the generated values, but what’s the equivalent of a
schema for a programming language? Types.

Jsonnet does not have a way to validate its functions without running them
first.

~~~
nikolay
I clearly get that, but many IDEs use the schema to help you produce valid
JSON.

------
NuSkooler
Still much prefer HJSON ([http://hjson.org/](http://hjson.org/)) for stuff
that people might need to touch.

If it's truly for end-users (read: non-admin/dev types), you probably
shouldn't have them touching configuration files _at all_.

~~~
tobr
How is this at all related to Dhall? It looks like a completely different
thing with a completely different purpose.

~~~
NuSkooler
They are both text based configuration file formats made to be easier for
humans to interact with, so I'm not sure what you're confused about?

~~~
tobr
That’s about the least interesting thing about Dhall. (It’s weird that they
tout it prominently on the homepage.) There are so many flavors of syntax
sugar for JSON, Dhall is a completely different beast.

~~~
mcphage
You might want to ask the HN admins to rename the title for this post, then.

~~~
tobr
It looks fine to me. Reducing repetition is precisely the type of thing
Dhall’s features should be useful for.

------
KirinDave
Dhall is fantastic and I try to encourage everyone in tech I meet try it.

~~~
GordonS
OK, _why_?

~~~
KirinDave
Because it is a good mix of features, syntax, execution speed and correctness.

Of course. Didn't you read the article?

~~~
GordonS
I did, and it's bad form to suggest otherwise.

I was asking about your personal opinion, since you said it was great but
didn't give any info as to _why_.

~~~
KirinDave
> I did, and it's bad form to suggest otherwise.

If you say so. But... I said I think the features are good and you ask "why?"

I could relist the features, but that's a waste of time. As I said, I think
the combination is a good combination. In a world where people try to encode
loops in YAML or JSON, even small improvements are better and Dhall is a large
improvement.

> I was asking about your personal opinion, since you said it was great but
> didn't give any info as to why.

I don't really get what you're asking. I said I think the combination of
features is good. I don't need to describe the features. The reason I like
them is probably related to neurochemistry?

Are you asking for a deep dive on how Dhall compares to alternatives?

~~~
GordonS
Then I apologise; because you posted I assumed you were happy to or wanted to
engage in discourse, maybe highlight your favourite features, possibly debate
the value it bring, that kind of thing, but I see my mistake now.

------
choeger
Hmm...

So the authors claim that their language is guaranteed to terminate for all
well-typed programs. That is actually a nice spot for configuration languages.
Yet, I wonder how

a) they guarantee it, as I have seen no obvious link to the language's
semantics

b) useful this is in practice.

Nevertheless, very nice approach, indeed.

~~~
codebje
Build systems tend to get very complex Turing complete scripts, such as gradle
for Java or Make for C. Having something almost as powerful but reducible to a
normal form is very helpful for CASE tools.

~~~
skybrian
Banning Turing completeness doesn't give you the property you want, though.
Knowing that reducing to a normal form eventually terminates if you wait a
million years may be something mathematicians care about, but isn't of
practical use.

What matters is that you can analyze the code quickly. To find that out, one
way is to try it and kill the process if it takes too long.

Or perhaps better would be to come up with a portable definition of what
"takes too long" means that you can put in a presubmit check. Something like
"running out of gas" in Ethereum.

------
mitchtbaum
Rust bindings tracking issue

[https://github.com/Nadrieril/dhall-
rust/issues/77](https://github.com/Nadrieril/dhall-rust/issues/77)

------
ilaksh
I'm sure people will be happy to crucify me for throwing this out there but I
don't see a big risk in just using JavaScript in most cases if you want
something like that. You could use template literals to replicate the example.

------
voidmain
How far does "non turing completeness" really get you in this context? It
looks easy to write a program in this language that will take longer than the
age of the universe to evaluate and whose result can't be represented
explicitly without collapsing the galaxy into a black hole. How much comfort
can you take in the fact that you know it doesn't diverge?

~~~
mbrock
How would you write such a program?

~~~
comex

        let replicate = http://prelude.dhall-lang.org/List/replicate
        in replicate 999999999999 Natural 1
    

(add additional nines if necessary)

------
javier2
I love this!

How small is a static binary to run this in my containers?

How are some ways to integrate the typed config in a language?

~~~
Gabriel439
The static binaries for the various interpreters and conversion utilities
(i.e. `dhall`/`dhall-to-yaml`/`yaml-to-dhall`) are all roughly 10 MB each

The following languages natively bind to Dhall:

* Haskell * Clojure * Ruby

... and the following language bindings are in progress:

* Rust * Go * Python * PureScript

In the absence of a native language binding, you can convert Dhall to YAML or
JSON and read that in.

------
arkh

       let input =
          { relative = "daughter"
          , movies   = [ "Boss Baby", "Frozen", "Moana" ]
          }
    

We don't frequent the same kind of "non-technical users" I guess.

------
amingilani
I thought the typo in the challenge was that the keys were in the root of the
user's home directory, instead of the `.ssh` directory. So, I added `.ssh/`
between the key and user home directory.

------
mitchtbaum
This looks very useful.

~~~
mitchtbaum
looking further, it seems that aside from repetitiveness, safety is the main
focus:

[https://github.com/dhall-lang/dhall-lang/wiki/Safety-
guarant...](https://github.com/dhall-lang/dhall-lang/wiki/Safety-
guarantees#types)

which in Rust, we're solving this via SANE and SCL:

[https://gitlab.com/bloom42/sane-rs](https://gitlab.com/bloom42/sane-rs)

[https://github.com/keats/scl](https://github.com/keats/scl)

I'm not sure how much need there is for an additional programming layer,
especially within config (the part of a program with the simplest syntactic
requirements).

for my projects where "ahead-of-time validation" is needed, we're currently
using SCL's parser for safety guarantees:

[https://github.com/foundpatterns/contentdb](https://github.com/foundpatterns/contentdb)

[https://github.com/foundpatterns/lighttouch/blob/d7ada4576a6...](https://github.com/foundpatterns/lighttouch/blob/d7ada4576a6f8865a625f6ffa18452ec90353db5/loaders/models.lua)

[https://github.com/foundpatterns/torchbear/blob/4dd2b9ea76ba...](https://github.com/foundpatterns/torchbear/blob/4dd2b9ea76ba0911d586ec5a0276f53053bd9738/src/bindings/text/scl.rs)

~~~
ff_
From a cursory look to SANE and SCL it looks like Dhall still offers some
more:

\- functions

\- a powerful typesystem

\- remote (HTTP) imports with sha256 checksums

------
desc
Programmable configuration is always and without exception a monumentally
stupid idea.

Programmatic _generation of static configuration files_ can be very useful.

Sufficiently complex examples of the latter might as well be the former as far
as maintenance is concerned.

If you need to write a program to configure your program, you're probably
doing it wrong.

~~~
nine_k
Configs allow to add flexibility past compile time, often dynamically at
runtime.

~~~
desc
Yes, that's the problem. I'd like to be able to look at a config file, on
disk, loaded at startup, which defines the initial state of the server without
having to think through how it was evaluated.

Generating the config during deployment, eh... often necessary. Best done with
transforms and templates because they're simple.

Executable config, run during startup or, worse, on each request? NO.

[edit] I think that's the main disconnect here: 'past compile time'. The whole
point of testing, strong type systems, etc is to lock down the set of states
the system can be in. If your configuration is so 'dynamic' you are
essentially abandoning all those benefits and saying 'yeah, do what you like
to our live servers'.

In short, configuration which is that powerful is indistinguishable from
running untested code in production.

~~~
jose_zap
Dhall give you exactly that, since you can store the normalised version of any
configuration. Or inspect it at will by running it.

~~~
desc
Yes, I'm not criticising Dhall so much as the behaviours it permits. IMO it
should be _difficult_ to 'program' the generation of a config file, because
the application should be designed such that that degree of flexibility is not
required at the level of configuration.

We've done things with generated config before. Looked necessary. We took a
few steps back and realised that it was never necessary, only permitted, so it
got fudged in deployment instead of being fixed in application design.

~~~
nine_k
If you operated services that should run at scale, or 24/7, or both, you must
have noticed that the ability to fix an urgent issue (which may be totally not
a fault of the deployed code) by changing just configs is valuable.

~~~
desc
Of the failure modes I've had to deal with, even when we did use a lot of
interpreted scripts which could be live-patched, very few of the important
issues were fixable that way. Because the stuff which broke was _rare_ and
_deep_.

One could argue that everything would be config-related if all the code were
interpreted and considered to be configuration. So absolutely everything could
be fixed in Production.

I'd argue that absolutely everything could be _broken_ in Production too, in
that case. The point is that you test the invariant stuff, and have a small
surface area of variables which define the permutations of Live behaviours.

Configuration is not code. Code gets tested and doesn't vary between Canary,
Nightly, Stable Test, Customer Test and Customer Live for a given build.

Because some of us build stuff for customers who won't justify the 'risk' of
updating every day, and have upgrade cycles measured in months.

------
isoprophlex
To me, worrying about config files seems like the ultimate exercise in
bikeshedding.

You either need a simple list of items (eg. dependencies) or key/value pairs.
Use a text file or yml or json or whatever.

Or you need templating, the use of functions, etc, like dhall provides. But
then, why not use the language you're already using for the rest of your
project, or a bash script to export some variables?

Might sound like I'm throwing sourness around, but I just don't see the niche
for this, except inventing a new thing for the joy of it?

~~~
leg100
> You either need a simple list of items (eg. dependencies) or key/value
> pairs. Use a text file or yml or json or whatever.

You clearly haven't wrestled with kubernetes configuration files.

Reams and reams of YAML, heavily indented to represent umpteen nested objects.

Templating, bash scripts, using your favourite language to roll your own
config generator - these are all well trodden approaches that fail to scale.

Official shitshows like Helm have come along with nothing more innovative to
offer than templated YAML. The next version uses lua to generate config, but I
remain skeptical given previous design choices.

We can question whether kubernetes has pushed the dial too far towards
necessitating mountains of config, but for now it is most definitely a problem
for us users.

~~~
mbrock
My favorite is when people write scripts that concatenate YAML files in such a
way that you have to be really careful about how this one file always needs to
be indented by 12 spaces otherwise everything breaks in horrible ways.

------
nhooyr
What's with the commas at the start of lines?

~~~
edoceo
Makes it easier when commenting out. Use this trick for SQL and JS too (to
prevent trailing comma issue)

~~~
dymk
I don't get why you'd build a language in 2019 which disallows a trailing
comma in lists.

~~~
andybak
Yep. The solution to comma issues isn't to put every single one in a place
nobody usually puts them - it's to be more forgiving about allowing the
occasional trailing one.

~~~
twblalock
The solution is to get rid of them. They are not necessary.

~~~
Gabriel439
Author here: commas are necessary to separate list elements in any language
where function application uses whitespace (i.e. Haskell-style function
application). If you're not familiar with the syntax, an expression like `f x
y z` is a function `f` applied to three arguments (`x`, `y`, and `z`),
analogous to `f(x, y, z)` in a more traditional language.

Nix made this mistake of using whitespace to separate list elements _AND_
using whitespace to separate a function from its argument and it is a very
common pain point for new users, because they will write something like this:

    
    
        [ theFunction theFunction'sArgument ]
    

... thinking it will be parsed as:

    
    
        [ (theFunction theFunction'sArgument) ]
    

... but it actually gets parsed as a list with two elements, leading to a
bizarre type error.

