top | item 35589506

Build systems à la carte (2018)

61 points| quick_brown_fox | 2 years ago |dl.acm.org

6 comments

order
[+] leetrout|2 years ago|reply
Code is available at https://github.com/snowleopard/build

I skimmed the paper - this is interesting on many aspects but I liked the breadth of what they analyzed... they use Excel as one of the examples!

I know it is a valuable skill to be able to efficiently break down problems into abstractions but I suspect you would still end up with "porcelain"[0] that would hide so much of this it might not be worth it. Or maybe it is so generic it becomes a standard of sorts (or certainly a standard way of doing things) with flavors of implementations on top of it?

In the conclusion they say:

> ... a simple recombination leads to a design for a monadic suspending cloud build system ...

Totally over my head as I still don't grok monads despite my belief I use them or something very close to them all the time without realizing it. I could not implement one. Anyway, I digress... neat paper and I will keep working on digesting it.

[0] https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Po...

[+] endgame|2 years ago|reply
"Monadic" here means being able to handle build steps that build build steps. The fundamental operation for a monad is `join :: Monad m => m (m a) -> m a`, which merges two layers of `m` into one. A hypothetical `Build (Build a)` (not literally in the paper but giving you the flavour) would be a build which describes how to build a build which describes how to build an a. If your build system was monadic, you could "squash" those two builds into a single one by building the inner build step, loading it somehow (maybe restarting your build system, like `make` does, or Nix's import-from-derivation feature), and then following the new build instructions to build the `a`.

Where does this arise in practice? If you had a `build :: Build x` and a function `f :: x -> Build y` that described how to compute new build steps from that `x`, then mapping `f` over `build` gives you a nested build `Build (Build y)`. This is like saying "Okay, suppose I know how to build `x`. Then since I can make a `Build y` from `x`, I can make a build that makes a build that builds `y`". If the build system is monadic, we can use `join`; this map-then-join pattern is packaged up into Haskell's "bind" operator: `(>>=) :: Monad m => m a -> (a -> m b) -> m b`, which does something equivalent to mapping the second argument over the first, and then joining the result. `(>>=)` is used in the desugaring of `do`-blocks, of which there are a few in the paper.