roman / Haskell-etc

Declarative configuration spec for Haskell projects
MIT License
47 stars 7 forks source link

Why do you need to read a spec file at runtime? #55

Closed langston-barrett closed 6 years ago

langston-barrett commented 6 years ago

I'm trying to understand why this library has runtime file dependencies. It seems like you could just construct an element of ConfigSpec in your Haskell source and avoid the trouble of locating files at runtime and including Aeson as a (massive) dependency. What's the advantage to having a spec file? Or am I misunderstanding something?

roman commented 6 years ago

Hi Langston!

Thanks for your feedback, I'll try to give some rationale around the why of some of these:

It seems like you could just construct an element of ConfigSpec in your Haskell source and avoid the trouble of locating files at runtime and including Aeson as a (massive) dependency.

Yes, in theory, you may be able to create the ConfigSpec record in Haskell, there is nothing stopping you to do that, you will still require aeson for the default values though. I've been pondering with the idea of providing a more generic Spec.ConfigValue and ConfigValue types that do not rely on JSON.Value for their default value, but most of the API will lose it benefits rapidly, also for the ConfigValue side of things, the compositionality may suffer a bit.

In regards to locating files at runtime, you are right, having to locate the configuration spec file at runtime is a bit silly, I've been doing recent work to make this step a compilation step (via TemplateHaskell). For every other file though, it makes sense to look them up at runtime, the place where you run your application is unlikely to be the same place where you compile it, and you may have sensitive values in those configuration files that you don't want to include in the binary.

In regards to aeson being a massive dependency, it may be massive, but it is also ubiquitous (you'll likely have it already on your package local db); I went with that fact as something that made it a sensible choice.

What's the advantage to having a spec file?

It's the whole point of the library really, the spec file is the canonical place where all configuration things are considered, currently you define:

With this spec, you separate the source and precedence of your configuration values, from their usage. When you are using a Config map that is derived from the ConfigSpec, you have a pure data-structure that knows (and hides out from your program) where values come from and how to prioritize them.

Hope this helps, if it does, would you be able to rename this ticket as an update to the FAQ with your questions? (or even better a Pull Request).

Cheers.

langston-barrett commented 6 years ago

@roman Thanks for answering promptly and thoroughly! I meant "What's the advantage to having spec file over setting the values in a Haskell record?", and we apparently agree it isn't necessary. Seems like TemplateHaskell would be a great way to go!