Question

(1)

  • The oldmakeutility looks at timestamps, and if the output is newer than the input, it skips (pointless, time-consuming) re-compilation of e.g. C files.
  • The same is true for many languages and compilers. “Lazy” thumbnail generation in web aplications skips those thumbs that are newer than the source image.
  • “Smart” file syncing tools do the same, looking at time stamps, to reduce transfer volume.

I used to refer to this as “lazy”. However, looking at web citations, the term “lazy” in Computer Science seems to actually mean something different: „do something as late as possible“.

  • only load that extra part when it's necessary
  • initialize lazily, aka as late as needed
  • only evaluate that part of the equaption, when you get to it...

So is my term wrong? And what would be more correct, for all that „is-newer-based“ skip optimizations?

Was it helpful?

Solution

Yes, make is lazy. It's avoiding doing work that it's determined it doesn't need to do.

From Wikipedia's page on lazy evaluation (added emphasis is mine):

lazy evaluation, or call-by-need is an evaluation strategy which delays the evaluation of an expression until its value is needed (non-strict evaluation) and which also avoids repeated evaluations

Re-running steps (compilers, linkers, loaders, preprocessors, or whatever) that have already determined to be suitably run is a clear "repeated evaluation." The whole point of the Makefile is to specify dependencies and determine what constitutes necessary or superfluous evaluation.

It's also fair to call it "incremental," "just-in-time," or "on-demand." But it's also, very much by design, lazy.

OTHER TIPS

"Lazy" usually means putting things off until the last possible moment, e.g. initializing a module only when it's actually needed, or computing only as many numbers of an infinite sequence as the user actually reads. Alternative terms are 'just-in-time' or 'on-demand'.

The key concept here is that this is only a good idea if you don't know exactly what the program will do at runtime. In practice that means that it's appropriate for interactive systems that depend on a stream of user input. If you knew exactly that a module will always be used, you might just as well initialize it on booting, because it's easier to code and doesn't make the user wait later when they're in full getting-things-done mode.

Not repeating compilations, as make does, isn't really comparable. First, whatever you want built is definitely going to be wanted - there isn't anything in the rule set that may or may not be necessary. Once you've given a target to make, you know that all preconditions will have to be satisfied. And no matter how long you wait, the source file is only going to get older, so the compilation will only get less and less necessary, so to speak.

So you don't have interactive functions, and you know exactly what is and isn't necessary to do (because knowing this is kind of make's job description. Therefore, I would say that not repeating compilations unnecessarily is just an instance of judicious caching - also a widespread practice, just a somewhat different one.

Licensed under: CC-BY-SA with attribution
scroll top