Neal and I have been talking a lot about Essence vs. Ceremony this summer. In most of the examples I give, it is easy to tell which is which.
But that isn't always true. Consider this example from Scala. Does the application trait improve essence, or lead to more ceremony? I will post my answer next week.
Comments
It’s a tough call. It certainly looks to improve essence, by declaring the class to be the application start point. And it reduces the necessity of the ceremony of defining the ‘main’ method. I think the question is whether the programmer would have to override the defaults that the trait provides. The author of the blog post seems to think that’s the case, but the comments seem to indicate that if you keep things simple in the constructor, that’s not the case.
On the whole, I’d say that it’s essence, with some caveats.
http://talklikeaduck.denhaven2.com/
I think that what you’ve stated as the metric of Ceremony
- specifically, the surface-level complexity of code and how much “unecessary detail” it contains due to requirements of the the platform -means that the Application trait indeed lowers the “Ceremony” of code using it, as it replaces a boilerplate mantra with a briefer and more meaningful label. However, it does so at the price of increased platform complexity and extra special cases(), meaning that code which uses the platform, even though it seems simpler and increases the “expressiveness” of code, actually increases the unnecessary complexity of the whole equation, and makes the platform more difficult to use effectively.() And, in fact, reducing Scala’s measure on your “Rich Consistency” metric, since you now can’t use two features
- threading and Application entry point functionality -together.I think the reason for all this is that is that, in attempting to remove what they saw as an “obnoxious special case” because it looked boilerplate-y, they ended up abusing a very consistent general case (object initialization code, which is otherwise generally a short-lived slice of an object’s lifetime, but in this case actually lasts the object’s entire lifetime) and, in so doing, stretched inherent limitations that were perfectly reasonable in the intended usage of that functionality to the point that they were nonintuitive and actively dangerous problems. And even after all that, they didn’t even remove the need for the original boilerplate: one still needs to use that construction if one wishes to receive command-line arguments.
So all this leads to an opinion on the “essence vs. ceremony” issue (which I’ll give a briefer label with higher semantic weight: SNR): the SNR is worth increasing only to the point that it reduces redundancy and noise. When it begins introducing new special cases, the scales shift, and eventually high-ceremony code which uses only general-case capabilities is more powerful, flexible, maintainable, and robust than low-ceremony code which employs very limited, inflexible special cases. The differentiator between these extremes is the amount of code reduction vs. the number of special-case, limited-purpose capabilities used.
From another perspective: increasing essence and decreasing ceremony is almost precisely equivalent to decreasing the entropy of code. Which is a noble purpose up to a point: after that point, it becomes manual compression, and obfuscates the intention and meaning of code behind an inflexible veneer.