Re: Taste and Aesthetics
Posted: Feb 18, 2003 4:54 PM
I disagree with an implication that Ken makes about the relationship between internal and external simplicity:
"Ken Arnold: Some people view simplicity -- and again, I mean the external simplicity, the user's view -- as something that happens if their system is internally simple. I am saying you should strive for external simplicity on its own. "
I believe that the *only* way to robustly implement simplicity in an extenal view is as a consequence of the internals... that way, all the generalizations of the external view that you could never have anticipated all come out right, without you needing to think about it (or at least, much more so than if they differ!)
Another way of saying this is seeing the program as a "theory of the problem", and Occam razor says that the simplest (ie shortest) solution is the "right" one. Lots of fakes and hacks and mapping code make a longer solution - and so aren't "right". Occam's razor is very satisfying in itself - but it is more than that! The "right" solution generalizes well, and so pragmatically is better also.
Example: before Copernicous, planetary motion was modeled with very complex models ("epicycles within epicycles within epicycles") - it was often slightly wrong, and they just added another epicycle. In other words, it didn't generalize well, because it wasn't the right model. Whereas the heliocentric view makes superb predictions - even if that particular situation had never been seen before! It sheds light in the dark places, instead of having to bump your nose up against every wall! "The sun at the center" is the true model - it is the reality.
Having the same model internally and externally means that your code generalizes in the way that users expect. Otherwise, they will often be bumping their noses.
There's one extra bit to this: you *can* write shorter code that is less readable... I think the "length" of code shouldn't be measured in bytes, but in "thought units". Thus, a for-loop in java is probably one unit... and a pattern (if you personally are familiar with that particular one) is also a "unit" for you. Whereas some clever bit-shifting is probably several units (unless they are so second nature to you).
Yes - the simplity of a particular piece of code is subjective; it's not an absolute. In Bayesian theory, this is the "prior expectation" that a particular theory is true. Older, experienced developers will have different priors from younger ones - partly because they have more experience with the typical problems; and partly because they are more familiar with the older ways of solving them.
The evolution of languages and patterns and idioms is actually the evolution of the priors behind the language - in other words, they make some things simpler to express, and some things more complex. Typically, this makes the "common problems easier to solve, and the rarer ones possible". It also means that the best way of solving an old problem may change, as the priors change. What drives this evolution? Well, the patterns that do better at modelling the problems that people typically come across get used more (in the long run). Of course, market-like factors influence this as well, like what gets promoted more, what makes sense in terms of what most people already know, and what problems are most common, what group of people communicate better with each other, where are the really smart people and are they able to communicate their ideas.
Summary: The shortest solution (in terms of your thought-units) is the "right" solution, in the sense that it best generalizes to cases that you would never have anticipated.
To reap the generalization benefits of this, your code needs to be internally simple in the same way as it is externally.
Yes, sure you can be clever, and make it *appear* differently (and this is sometimes necessary) - but are you clever enough to anticipate *all* the generalizations of the external model, and make your internal model match up with it? Or in practice, will you be forever patching it up, as bug reports come in? (that is, assuming that this code is exposed enough to get exercised in many different ways).
The *only* way to robustly implement simplicity in an extenal view is as a consequence of the internal view.