Search This Blog


Sunday, January 6, 2008

Dynamic Typing Reduces Code Complexity?-- A Reply

My post Dynamic Typing More Superior ( a more appropriate title would be Dynamic typing reduces code complexity?) elicited quite a few responses, mostly from readers who don't share my view. Some of the comments are quite insightful and interesting, and I would like to respond to them here.

Jeremy Weiskotten pointed out:
However, the issue just doesn't come up that often in the real world. You don't find yourself wondering, "Is this argument a String or something else?" Even when improving existing code that you've never seen before, it's usually not much of a problem as long as variables and methods were named well.

In fact, in your example, typing the argument as an array of string doesn't help much. What does it mean for a currency to be a string? Is it a standard abbreviation like "USD" for US Dollars, or is it spelled out "US Dollars", or is it simply "dollars"? Are they currency amounts (in which case I'd expect the type to be numeric)? There are many potential levels of ambiguity that you'd need documentation/tests/trial-and-error to resolve.
I agree with him on the inadequacy of my example. In fact, the parameter types in my example method are confusing at best, or outright wrong at worst. But I believe that everyone gets my point so I won't correct it.

But Jeremy asserted that the typing issue is not so much of a concern, as long as variables and methods are named well. I didn't share this experience. In my projects with JScript, I often found myself scratching my head over the methods of objects that I defined, probably because my projects entailed the definition of more complicated objects beyond the most primitive ones such as integer, or string or double. Even if my method names or variable names are clear, there is a big possibility that I could get the methods of the objects wrong.

So I need to keep a handy reference to any objects I used, and to type in the object's name and its property carefully or else I need to wait until the runtime to find the problem.

Imagine if someone else were to take over my code. How much trouble he would have to suffer.

Mikkel Garcia argued that because static typing checks for types at runtime, so some developers actually took false comforts in it and didn't do unit test.
As others have mentioned, coming from a C++/Java background into Ruby or Python - it can be difficult to understand the merits of a dynamicly typed language.

(In my experience) Many teams I've encountered in the Java world only have the barest of unit tests, or sometimes no unit tests at all. One of the reasons I've attributed to this is that the compiler tells the developers if there is something terribly out of place. That warm fuzzy feeling of compiler acceptance is mistaken for program correctness.

In an interpretted dynamic language, there is no fuzzy feeling - leading to more developers seeking to test program correctness (instead of compiler acceptance).
It is certainly sad to see developers not doing unit tests, no matter for what reasons. The fact that the developers felt that typing checking was enough to verify the program correctness is doubly more appalling. They need to be properly educated ( or reeducated) so that they could start doing unit tests for their code.

But to say that typing checking is bad because of this is not convincing. Suppose that some drivers mistakenly believe that the safety belts can protect them from harm in accidents, and so they drive recklessly and get themselves killed, can we therefore blame that the safety belts are responsible for their death? Of course not.

Type checking is like safety belts; it's designed to catch type errors ( and real typing errors). If anyone believes that he can write code without unit tests just because the code is checked for type correctness, then that's his problem.


Anonymous said...

This is Ruby:

myStr = "A dog jumps over a lazy cat"
myStr1 += "truth"

That causes this error:
"NoMethodError: undefined method `+' for nil:NilClass
at top level in untitled document at line 2"

Dynamic typing doesn't mean it doesn't catch these typo kind of errors. myStr1 was never created in this case, so an error is raised as it is doesn't exist.

Also, be careful not to confuse weak typing with dynamic typing; as they are separate things. Ruby, for example, is dynamicly typed, and also strongly typed. JScript, which you meantioned in your article is dynamic and weak typed. I would say that weak typing causes more serious problems than dynamic typing does.

Here is a handy reference of the types of popular languages:

Either way, what is the point of all this discussion? Smalltalk, which is dynamically typed (very similar to Ruby), has existed since 1969; this horse is officially dead and beaten.

Statically typed languages are appropriate for some types of applications and dynamically typed languages are appropriate for other types of applications. Don't settle for a tool, demand a tool box.

Soon Hui said...

Anonymous, good point about my example.

Maybe I should modify the example to the below:

myStr = "A dog jumps over a lazy cat"
myStr1 = "truth"
Assert("truth", myStr)

In this case, dynamic typing would not be able to catch this kind of problem.

Of course you can say that the above example shows a very strong odor of code smell. The definition of the variables is unclear and one should never programmed like that in the first place. In in reality, I have seen code which is far, far worse than that.

And the code didn't have unit test coverage.

Imagine the trouble I had to go through to fix bugs :(.

What's the point of all these arguments?

Actually, I wrote this post and the previous one just to show that
1. Dynamic typing does not necessarily lead to smaller codebase
2. Dynamic typing does not reduce code complexity
3. I prefer static typing!

But somehow subsequent discussions seem to evolve into some other directions :-)

Ricky Clarkson said...

"The fact that the developers felt that typing checking was enough to verify the program correctness is doubly more appalling."

Actually, static typing can not just verify program correctness, but prove it.

It can't prove that you did what the customer wants, but it can prove the absence of runtime errors. It's quite difficult to make static typing do that for most code (it turns out that if you write your code with the intention of having it statically checked, it's easier to statically check), but each time you go a step further you can delete a whole wadge of unit tests.

So I wouldn't say "appalling", but "optimistic", unless the programmer is a type-system expert.

Jeremy Weiskotten said...

"The definition of the variables is unclear and one should never programmed like that in the first place. In in reality, I have seen code which is far, far worse than that.

And the code didn't have unit test coverage."

So is the problem really with the typing system or the people who wrote confusing code without unit tests?

You can write bad code in any language and it will be difficult to work with.

Anonymous said...

If your experience with dynamic typing was JScript, I see why you prefer static typing.

Do yourself a favor, spend a decent amount of time with Ruby, Python, or Groovy. Make sure you make full use of the language, don't just write static type code in them. Then make your decision.

My preference is Ruby, but the others are very nice also.

Anonymous said...

You're right about your second example not producing an error in some languages:

myStr = "A dog jumps over a lazy cat"
myStr1 = "truth"
Assert("truth", myStr)

However, this isn't true in all dynamic languages. You can stop this kind of error by requiring that you explicitly state that you are initializing a variable. For example in Perl:

use strict;
my $sum = 10;
$sum1 = $sum + 10;
print $sum;

This produces an error, because you never explicitly create the $sum1 variable. This is still dynamically typed, but it solves the "spelling error" problem nicely.