Dhall is a programmable configuration language that is not Turing-complete
You can think of Dhall as: JSON + functions + types + imports
You will probably want to read the language-agnostic README here:
This repository (and this README
) focuses on the Haskell implementation of
Dhall
"Why not configure my program using JSON or YAML?"
JSON or YAML are suitable for small configuration files, but larger configuration files with complex schemas require programming language features to reduce repetition. Otherwise, the repetitive configuration files become error-prone and difficult to maintain/migrate.
This post explains in more detail the motivation behind programmable configuration files:
"Why not configure my program using Haskell code?"
You probably don't want to rebuild your program every time you make a configuration change. Recompilation is slow and requires the GHC toolchain to be installed anywhere you want to make configuration changes.
Given this Haskell program saved to example.hs
:
-- example.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall
data Example = Example { foo :: Integer, bar :: Vector Double }
deriving (Generic, Show)
instance Interpret Example
main :: IO ()
main = do
x <- input auto "./config"
print (x :: Example)
... which reads in this configuration file:
$ cat ./config
{ foo = 1
, bar = ./bar
}
... which in turn references this other file:
$ cat ./bar
[3.0, 4.0, 5.0]
... you can interpret the Haskell program like this:
$ nix-shell nix/test-dhall.nix
[nix-shell]$ runghc example.hs
Example {foo = 1, bar = [3.0,4.0,5.0]}
You can also interpret Dhall programs directly using the installed command-line compiler:
$ dhall
List/head Double ./bar
<Ctrl-D>
Optional Double
Some 3.0
... and you can reference remote expressions or functions by their URL, too:
$ dhall
let null = https://raw.githubusercontent.com/dhall-lang/Prelude/35deff0d41f2bf86c42089c6ca16665537f54d75/List/null
in null Double ./bar
<Ctrl-D>
Bool
False
Now go read the Dhall tutorial to learn more
Nix + Cabal is the recommended workflow for project development since continuous integration uses Nix to build and test the project. Other development tools and workflows are also supported on a best-effort basis.
You can build the project using only Nix by running this command from the root of the repository:
$ nix-build
More commonly, you will want to incrementally build the project using cabal
.
You can either do so inside of a nix-shell
:
$ nix-shell
[nix-shell]$ cabal configure
[nix-shell]$ cabal build
[nix-shell]$ cabal test
... or you can add nix: True
to your ~/.cabal/config
file and then you can
run the same cabal
commands without an explicit nix-shell
:
$ cabal configure
$ cabal build
$ cabal test
The compiler is built upon a theoretically sound foundation, meaning that if there are no bugs then the language will never crash and will always halt. However, in practice the compiler needs to be battle-tested to weed out any implementation bugs, so please open issues! ๐
Read the following guide if you would like to contribute: