Skip to content

Comment on Imperative configs are out; Declarative configs are inparent

Comments

This is also not declarative vs imperative. It is declarative with a functionalty vs imperative without it. A shell script could also check which parts are missing or outdated and do incremental build. I’m not any good at shell scripting so here is a similar pseudocode:

  import cc, ld, glob, make

  // make defined as:
  fn make(to, from, how) {
    if (exists(to) && mtime(from) <= mtime(to) {
      return
    }
    how(to, from)
  }

  make("foo.o", "foo.c", cc)
  …
  make("a.out", glob("*.o"), ld)
It’s basically the same as Makefile, except that out “make script” doesn’t know about goals anymore, only steps to take. Do we need that goal-knowledge in a declarative format is an open question, because you can wrap these make() calls in a function named aout() and that becomes your declarative goal. However declarative your config/data is, you still pass it to some evaluator like `make` at the end of the day.

An important difference here is that your shell script executes the steps in the order you defined. Make performs a topological sort on the required rules, so in the general case, a Makefile doesn't explicitly define the ordering of the steps, but instead the make runtime figures out an order on its own based on the dependencies.

The Makefile is a (default) goal and a sea of possible actions from which make creates a plan of action.

The shell script steps are manually ordered by the programmer.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.