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.
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:
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.