| If you're taking feedback, I'd like to disagree on your examples of "accidental complexity". To me, accidental complexities are quirks of design that everyone would agree to do over differently if history replayed itself. Examples like that would be: -- Java calendar (and C Language ctime) months have index starting with 0 which means 0..11 for Jan..Dec but for days, it's index 1 which means 1..31 -- PHP inconsistencies such some functions being verb_obj while others are obj_verb and some have underscores and some do not -- MS Excel has incorrect leap year calculation for 1900 which means all other spreadsheets must duplicate this "bug" to be compatible Those are the types of "accidents" that arise out of ignorance or uncoordinated thinking. Andrei Alexandrescu (expert in C++ and D) has a similar concept he calls "unforced errors". On the other hand, you compared a Tomcat servlet container as being "accidental complexity" and Go as "reduced complexity" because the http hosting is all built into the exe. To me this is an example of moving complexity around so you don't feel it for your particular use cases of the Go language. In other words, if the Java community had a chance to do it again, I'm not convinced that Tomcat servlet would be baked into the standard Java distribution. If you bake it into the JVM, you've made the JVM Specification[1] more complex. If you leave it out of the JVM but include it as a standard class library, you've made the API library reference more complex[2] (Alternative universe: Why is the class library reference 3000 pages long?! Because it includes 200 pages to document a servlet container that most don't use.) Complexity (in totality) wasn't reduced. It was only shifted around. I'm not saying moving complexity around isn't desirable because it is (hence we have "abstractions") but it's not an example of solving accidental complexity. I think what happens is that we programmers find some language, or framework and if it matches our use cases, it's subjectively less complex. For the others who need generics to write algorithms, they write homegrown template code generators or resort to copy&paste which is more complex. So sure, Golang omits generics but it only makes it less complex from a language-specification perspective. However, it's actually more complex from a total project perspective. I think this explains all the contradictory posts about Django/Rails/etc being "simple" while other posts say it's "complex pulling teeth". At this point, I don't buy that golang without qualifiers of use-cases is objectively less complex. I'm writing server-side web services with golang and for that use case, I think it's less complex than other alternatives such as C++ or Nodejs. For Windows GUI apps, using C++ with Qt is less complex than Golang. [1]http://docs.oracle.com/javase/specs/jvms/se7/html/
[2]http://docs.oracle.com/javase/7/docs/api/ |
Once piece of consistent feedback that I've gotten is that I didn't do a good enough job of clarifying that I was specifically dealing with the complexity of running applications. I'm pretty sure most people who have deployed Ruby or Python web applications would agree that deploying and running those applications is more complex that it needs to be. The examples of accidental complexity you gave are great examples of how it can manifest in code design.
I really liked your last point about the importance of use cases. I briefly alluded to that in the conclusion of my article, and I'm glad that you brought it up here. Use-case is extremely important.