Fig: Simple and Extensible Configuration

Hi everyone, I released a tiny #lang for configuration:

Fig is a domain-specific language for composing configuration files. Fig is a super-set of JSON with some additional features to reduce repetition and increase correctness. These features include:

  • Variables: Don’t repeat yourself! Name and reuse parts of the configuration.
  • Input: Include an environment of input variables to generalize the configuration to different contexts.
  • Merge: Create small, reusable objects; then combine them into more complex parts.

Here’s a configuration for a web service that demonstrates these features, saved in a file named config.fig:

#lang fig
 
let user-info = {
  "username": @username,
  "email": @email
}
let server-info = {
  "base": if @local then "http://localhost:3000" else "https://website.com",
  "endpoints": ["/cats", "/dogs"]
}
user-info & server-info

Here we have two objects, user-info and server-info that expect a few input variables (each prefixed with the @ operator) to be provided: a username, an email, and a flag for if the service is running locally. These two objects are merged together using the & operator.

Then, in the following Racket program, we instantiate this Fig configuration by providing the required variables:

#lang racket/base
 
(require "config.fig")
 
(fig->json (hash "username" "cat"
                 "email" "cat@email.com"
                 "local" #t))

By requiring the Fig file, we obtain the fig->json procedure for that configuration. By applying this procedure to a table of inputs, we obtain the following JSON output:

{
  "username": "cat",
  "email": "cat@cat.com"
  "base": "http://localhost:3000",
  "endpoints": ["/cats", "/dogs"]
}

For more information, see the documentation and the source code.

8 Likes

This looks real cool. Thanks for sharing!

1 Like