A Slight Delight - Compile-time checking things

This was a short-but-sweet thing that struck me while working with a client code-base. It was trivial but both useful and delightful and it is a type of thing I haven't been able to do in Python, PHP and Javascript in quite the same way.

Initially, the code was something like this:

defmodule MyApp.Schemas do alias ExJson.Schema def my_schema do %{ "properties" => %{ "email" => %{ "type" : "string" , }, "password" => %{ "type" : "string" , } } } |> Schema . resolve () end end

So for this JSON schema library the Schema.resolve function verifies that your JSON schema is defined in a valid manner and lives up to the JSON schema specification. So it doesn't do anything related to user-provided data or parsing JSON data. While familiarizing myself with the library I saw that you should probably avoid calling resolve repeatedly. Which makes sense, if the schema doesn't change, why call it again. Some previous developer probably missed that. It happens.

What I ended up doing was:

defmodule MyApp.Schemas do alias ExJson.Schema @my_schema Schema . resolve (%{ "properties" => %{ "email" => %{ "type" : "string" , }, "password" => %{ "type" : "string" , } } }) def my_schema do @my_schema end end

So what does this give us? Well, module attributes are resolved at compile-time. This is why @my_secret System.get_env("MY_SECRET") often leads to unwanted behavior. But in this case, our schemas are part of our code and will not change at run-time or between environments. So we can shift the resolution to happen at compile-time and never have to do it at run-time.

The cost of calling Schema.resolve is paid up front at compile-time.

is paid up front at compile-time. Errors in defining JSON schemas show up at compile-time rather than run-time when you attempt to validate something.

Having put much less time into compiled languages this was delightful. Being able to shift some checks back to compile-time is incredibly useful. I've also had a reason to write some macros which was fun.

If you have some suggestions, corrections or thoughts on this let me know at lars@underjord.io.