Synthesis is harder than analysis

10 points by typesanitizer


ryan-duve

For indefinite integrals, the ones without numbers above and below, I don't get the "derivatives are more local than integrals" point. If f(x) = x^2, the derivative is 2x and the integral is x^3/3. Both of those are true for the entire "global" number line; plug in any number you like. As f gets crazier, the difficulty gap widens but nothing has become more local/global.

I don't think this takes away from the author's main point. Looking at part of a thing is easier than putting different things together, e.g., it's easier to tell which objects are in an optimally filled knapsack than figuring out which objects would optimally fit in an empty knapsack. I just don't see how the difference in difficulty between calculus derivatives/integrals supports this.

pyon

I get that the author invokes calculus only as an analogy for an engineering problem, but I can't help myself. There exists an entire branch of mathematics dedicated to quantifying the obstructions to computing global solutions by patching local solutions together. The converse act, taking a global solution and restricting it to a local solution, is essentially free.

With that off-topic out of the way, and returning to computing, my feeling is that it's important to find system decompositions ("analyses") that don't make the subsequent integration ("synthesis") work unnecessarily hard.

Splitting a large state machine into smaller interacting submachines can make the implementation effort more manageable, but it also forces you to define the interfaces between the submachines with great precision. These interfaces must describe not only the inputs and outputs of each submachine (which are ordinary data structures, file formats and protocols), but also the precise conditions under which it's meaningful to run them (which are predicates on the information contained in these data structures, file formats and protocols).

If your programming tools are incapable of enforcing these conditions statically, then your state machine decomposition has created a dynamic failure mode that's not inherent to the original problem. And now you have to balance the benefits of splitting the implementation into submachines vs. the costs of dealing with this new failure mode. This is why I'm particularly interested in how programming tools enforce the correct use of abstractions.

Notice that I've used the word "enforce", rather than "verify". To illustrate the difference, suppose you have a database with a very complicated invariant that's impossible or too expensive to express in SQL. You can enforce the invariant by verifying every single application that uses the database. But you can also enforce the invariant by routing all uses of this database through a service whose API doesn't expose ways to break the invariant to begin with.