|
Re: Are Dynamic Languages Going to Replace Static Languages?
|
Posted: May 5, 2003 11:23 PM
|
|
Sure it's a bit of a pain (in Java) to add "throws" specs or catch blocks in a dozen places because you decide to throw a new exception, but as Arnold deVoos points out, this does maintain the validity of your interface contracts--which is more important on a large multi-person software project or a library, than it is for experiments, prototypes, and modest projects. Another plus is that it helps you to think about important things: to take the example of Java exceptions, it reminds you to go through the hierarchy of callers and ask the question, "Does this exception need to be handled at this level or can I burden my callers with it?" Remember finding the callers can be a tricky problem to solve using grep because method CallerFunc may match the search string because it calls MySpecIsChangedFunc, but method UberCallerFunc may call CallerFunc, and thus it may need to know about your exception, even though it doesn't match "MySpecIsChangedFunc". Under strong typing, iterating the fix-compile-fix cycle a few times allows you to find all the callers, and all the callers' callers.
More generally, static typing can often help find the location of errors. It's no substitute for unit tests, but typically when a unit test fails it just reports FAILURE, and leaves you to find the problem. In a language like Python, my experience is that the errors you see are such as "Empty list on line x" (paraphrasing here), which doesn't throw much light on the problem. But in a really good typed language, such as ML, you get something more along the lines of:
Passing type "Pet list". Expected "Pet list list".
which might suggest to me that I took the car instead of the cdr (if you can forgive my dated LISPisms).
But the more popular static languages are too restrictive--that's the clarion call that I heard in this forum. For example, the problems with multiple inheritance in C++ often necessitate to type hierarchies instead of more fluid type dags or other more fluid relationships, which SmallTalk or Python can handle easily. When new requirements come up and an existing type hierarchy becomes inappropriate, this can put C++ programmers in the damnable position of choosing between completely restructuring the class hierarchy, or hacking around it (say, with a wrapper class or by using a lot of downcasting) which invalidates the whole benefit of static typing. Java's interface/implementation distinction may be an improvement, since it permits one common form of "multiple inheritance" while retaining the static-typing benefits, but it still leaves a lot of cases uncovered.
Languages such as ML (which alleviate the need of dilligently declaring variables, yet still detect type errors) solve a lot of these problems but are wildly unpopular, in part because of their sometimes obtuse syntax (but then, Perl somehow took off). Maybe ML also compiles slowly--can anyone speak to this--Krish? ML is not perfect but lots of its ideas could be usefully put to work (how about function closures in a future Java so we wouldn't have to clog up our code with those one-method anonymous classes so often?) I'm optimistic that it might be possible to create a beautiful language that would have a type-system as strong as ML's or C++'s, one that's at least as flexible as Java's, and would allow a looser style of coding as ML, Perl, or Python.
|
|