Wednesday, July 18, 2007

Dynamic Language Weenies Victorious After All

I just had the "pleasure" of being introduced to Hacknot, a blog on software development by an author hiding behind anonymity, but whom we will, for convenience, call "Ed Johnson". In "Invasion Of The Dynamic Language Weenies" he derides dynamic languages, claiming they are not easier to code in, produce no real benefits and are generally the tools of bad programmers, those who live in the thrall of some juvenile fan dementia. He makes so many mistakes here it's hard to know where to stop criticising. So I didn't (stop, that is), and wrote this reply instead.

The effluent Johnson takes 8200 words to make two points, that language evangelists over-state their claims (shock! horror!) and that some of their behaviour is unkind to those who disagree with them.

The last point we can dispense with immediately, since his own behaviour is equally unkind. The article is full of statements like "get back in your high chair" and derogatory labels like "fanboy" that negate any moral high ground he may have otherwise had.

This frees us up to get into the meat of the article, or perhaps "gristle" is a more appropriate term. I will do so by presenting a number of sections corresponding to his own supposed rebuttal of various dynamic language evangelist claims.

Benefit: Application Code Size Reductions

Johnson1 defines "Dynamic Languages" in terms of three attributes and then goes on to show that they do not produce enough in the way of code reduction to justify a claim of 80-90% savings (made by Stephen Deibel2).

But perhaps he should have widened his definition to include the fact that Python (the specific target in this section of his article) contains very high level library support. This means actual application code is dramatically reduced. I go further than Deibel: the fact I can instantiate a web server in two lines of code reduces my application volume (in this case) by 99%3.

He does get to discussing libraries after about 1200 words explicating why his own limited definition gets him no closer to understanding the claims he is supposedly refuting. But when he does get around to it he only mentions the subject of libraries to dismiss it entirely. "But any saving in code that occurs from the use of third-party libraries has nothing to do with the dynamic nature of Python." Perhaps not according to his own limited definition.

Forget "third-party", it is the completeness of the standard library that provides a substantial benefit to Python developers (the community uses the phrase "batteries included"). Having a complete high-level and standard library that you can be sure the entire installed base has access to is a boon to developers. Apparently Johnson is blind to the advantages of this, having learned nothing from the history of C, C++ or Java.

Add to this the very real benefits from the three attributes of dynamic languages he does admit to and we start to glimpse the substantial, perhaps even profound, advantage dynamic languages offer.

Bias Evident, But No Evidence

Johnson goes out of his way to shoot down studies and opinions contrary to his own. Without evidence.

He attacks Lutz Prechelt's "Are Scripting Languages Any Good?4 for various methodological errors, and fair enough. But he provides us with no similar study that contradicts the conclusions, or was done with a less flawed methodology. So, on one side we have a comprehensive though flawed study, and on the other we have... nothing.

When he slams the Java versus Python code comparison he forgets to mention that the author goes out of his way to mention that it is, in fact, subjective. Rather than acknowledge the honesty of the author he chooses to disparage him. Again, without any contrary evidence.

It is not enough to state that Python code is no briefer than Java; examples must be forthcoming. But I'm not surprised Johnson backs off trying to prove the impossible. His cases would have to be far more contrived than those put forward by his "victims".

Advantage: Dynamic Typing Increases Development Speed

Johnson rebuts this claim by saying that type declarations do not add appreciably to code overhead, but this is a simplistic claim which does not take into account the need to build templates, track and convert between types, etc. All of this adds not only to the code but, far more importantly, to the cognitive overhead needed to manage a code base.

Certainly there are advantages to strict compile-time type checking, but these may be offset by using tools to perform static analysis of your source code5. This avoids having to enforce the overhead of strict types continuously throughout the development process. Even static languages benefit from these, witness Lint et al.

Yet this argument would not convince Johnson. He sees nothing good about being flexible, seeing it only as "an opportunity to err".

I imagine that's because he has never used Python to open a string object and then treat it as if it was a file, even though it is not. Polymorphism equals convenience and all out of the box. I am not sure how this flexibility necessarily leads to errors, but it is immediately apparent how it increases productivity6.

Advantage: Interpretation Increases Development Speed

Johnson states quite rightly that compiling code does not always take hours, so that the benefits in raw time gained by not needing to compile might be small. He notes that code components that are static can be made into libraries, then linked into code that is currently being tested, in order to decrease compile time.

Never mind that this is a tacit admission of the problem, how does this affect workflow? In a dynamic language all the time spent managing those "temporarily static" libraries, determining when parts have changed enough to require recompiling, publish various versions etc. gets reduced to zero. The coder can instead focus attention on more valuable aspects of the programming job. Looks like a productivity increase to me.

Advantage: Reduced Code Volume Increases Development Speed

Johnson writes about syntax only to dismiss improvements to it as a mere "keystroke-saving mechanism". Here he refuses to think about how clarity of syntax improves the comprehensibility of code and boosts productivity, especially across larger development teams.

As usual he exaggerates to make his point: "Many language comparisons performed by DL enthusiasts focus on concision as if it were the sole measure of programmatic worth." Well, Johnson, how about we admit it's not the "sole measure", just an important one. Happy now?

He dismisses claims for syntax improvements by saying that examples could be tailored to the situation at hand. Sure, a given example might be chosen to emphasise a point. I mean, what else does he really expect of an example? That it should be chosen to disprove the assertion? Tailored or not, his opinion of a given example hardly invalidates the original claim.

As the Problems Change, People Use New Languages

Johnson rebuts this claim in two ways.

1) Ruby development only exists because people love Ruby.

2) Ruby was used once on a project he was involved with in an inappropriate context. It must have been chosen because it's a "new toy."

I kid you not, that is the sum total of his argument. There's nothing here about other dynamic languages7. Nothing about different domains, changing demands, the actual world we live in... you know, context.

Just off the top of my head, here's four pieces of historical evidence to support the original claim.

1) As the demand for desktop applications swept middle management, a need for easy-to-use GUI-based tools emerged. Enter Visual Basic to fill the gap.

2) As more technically trained people got into server management there was a need for powerful parsing-based tools. Perl evolved with a terse syntax well suited to the problem domain, which included server-side web scripting.

3) As more non-technical people got into web development there was a growing need for a quick and easy way to glue databases to CGI applications. Enter PHP.

4) Dramatic improvements in hardware capabilities (processor speed, memory, disk space, bandwidth) rendered the differences between software execution models negligible. At the same time awareness of "programming for all" hit the mainstream. Enter dynamic OOP languages with friendly faces, like Python.

Johnson will continue to argue that these tools were only used because they were fashionable, not because they actually filled a niche. Unlike his own choice of tools, of course.

Syntax Can Be Natural

Johnson states that "Any claim that a DL has a more natural syntax that [sic] another language is just an attempt to elevate one personal preference over another." I agree that claims for "naturalness" can never be totally justified, as such of course depends on context. But the author is doing what he does so often, over-exaggerating a point and finding the baby is missing with the bathwater8.

Does he really think that the strangulated syntax of Perl, or the arbitrary statements in Visual BASIC or xBASE variants are as "natural" as Ruby or Python?

The best way to "prove" this is to offer code snippets to those who do not know the given language and see if they can figure out what is going on. I'd love to see such a study.

But the results are anticipated by Johnson's own foray into Ruby. His attempt to guess syntax for summing the elements of an array is as follows:
for every x in [1,3,5,7] { total += x }

In Python it is:
for x in [1,3,5,7]:
total += x

(Providing you initialise "total" of course. I assume he knows that.)

So, I guess he is helping prove that Python does have more intuitive syntax! Good luck guessing what the appropriate statements would be in a static language, since you might have to link in a library just to get a list container. And then you'd have to rewrite your code for some other object that was iterable but not a list. And so it goes, the ever-increasing spiral of repetitive work required to code anything significant in a static language.

No Harm, No Foul

This section is very strange. Johnson objects to people who say "what's the harm in adding Ruby to your toolbox" by comparing such people to... wait for it... rabid Creationists. He reminds us that Creationism is not on par with evolution scientifically. Might I remind him that coding is not science at all, and so any possible comparison of this sort is best made after ingesting a tab of LSD?

Things The Author Chose To Forget

There are so many advantages of, say, Python over, say, C++ (to pick one dynamic versus static case -- using the author's own divide) that it's hard to imagine how Johnson could have neglected to mention them, unless he's just being very dishonest. In Python I never have to worry about memory models, pointers or any other aspect of memory management; have powerful data types built in; have robust cross-platform compatibility; have highly polymorphic code; can use introspection features out the wazoo; take iteration, late binding, and other high-level functionality for granted; and so on and so forth.

But the best thing is, I do not necessarily even need to know what all these fancy features are, I can just get on and use them, in a safe way, with no risk of core dumps or buffer overflows. The risk of my finished application doing anything untoward is reduced, the accessibility of my solution is increased, the maintainability of the source is improved, etc. etc.

There is simply no comparison. In 99% of the problem domains 99% of people need to code in, a high-level dynamic language like Python is the best tool for the job. No, it's not "pure". No, it's not perfect. No, it's not scientific. It just works.9

A Couple Of Things The Author Gets Right

"Structure, commenting, consistency, naming, performance and maintainability all influence the efficiency with which programmers can work on a body of code." So does a good chair, lighting, being respected for one's work, and not having to deal with lame blog entries shooting down your tool(s) of choice.

"One of the features distinguishing fact from delusion is the presence of measurable, reproducible evidence that permits independent and skeptical scrutiny." A shame Johnson provides no evidence, then.

"At eight thousand words, this article requires far longer to read than the attention span of the average dynamic language weenie." That's actually true, because the author is so long-winded. The fault is his, but he chooses to blame his readers. And it's not just this article. In "To Those About to Hack" he takes 2200 words to say "Think twice, cut once", even admitting as much himself. Even with some topical exposition, what he had to say there should only take about 500 words.

"There are many interrelated factors influencing overall development speed. It's not valid to consider one factor in isolation." Strange, then, that his own analysis consistently ignores the synergistic effect of combining efficiencies. Syntax clarity, dropping the compile cycle, very high level standard libraries, reduced code volume and dynamic typing all offer benefits in isolation. But taken together they point the way to a new paradigm of coding (call it Agile, XP or whatever) that is having a huge effect on programme development.

Or, you can just deny it all and hope it goes away, thumb your nose at the kids and call them names.

An approach Eddie Baby obviously prefers10.


1 I will call him this but not "Eddie Baby", "sweetie", "sugar plum", "pussycat" or "angel drawers". For more fun, see the script for "It's the Arts." It's a Python thing.

2 I would love to reference this quote but Johnson does not know how to provide references. Actually, he lists a lot of references (poorly) as though this somehow bolsters his argument.

3 Not that lines of code is the only, or the best, measure of productivity.

4 Available in PDF.

5 For Python there is PyChecker, for example.

6 Examining a data type for only the interface you require at that moment, and then treating it as though it was that type is a technique known as "duck typing". As in, "If it looks like a duck and quacks like a duck..." Coined by Alex Martelli.

7 Johnson switches from Python to Ruby depending on what he wants to slam, but consistently fails to provide evidence against dynamic languages in general.

8 Odd too that he should discuss syntax in two different sections when he does not even acknowledge it as a factor when defining dynamic languages.

9 If you want all those other things I suggest Lisp.

10 Whoops! I mean "Sir Edward".

Thanks to Paul Jensen from bringing the original article to my attention.



robin said...

Masklinn: you are totally correct. No single point made for or against languages by any of their attributes singly is going to be true or all of them. Counter-examples can easily be found.

Sean said...

Hacknot does not allow for comments. This was not always the case, it would appear that after being called out in them too many times the author chose to turn them off and hold forth in splendid isolation.

robin said...

Sean: Indeed! I wonder what the point of blogging is if you don't want discussion? Personally, I have learned a lot already from the critiques of my article and am rather wanting to rewrite a few sections for clarity.

chromatic said...

The best way to "prove" this is to offer code snippets to those who do not know the given language and see if they can figure out what is going on.

Actually, that's the worst way to prove anything about language syntax. Are you going to hire people who've never used language X before to hire a system written in language X?

Post a Comment