Wednesday, October 15, 2008 10:18 AM
The Future of Programming Languages
Yesterday, my coworker Lou Franco pointed me to a fantastic talk by Anders Hejlsberg on the future of programming languages. In this talk Anders argues that the future of programming language development will be focused on three events: the explosion in the use of Dynamic Languages, the creation of many new Domain Specific Languages and the rising need for Concurrency.
In this article I'm going to focus on Dynamic Typing and Metaprogramming in particular. It's interesting to consider what the impact on the maintainability of our code from their increased prominence might be.
Dynamic vs Static Typing
Over the last decade the use of dynamic programming languages has exploded. Working at the higher level of abstraction that dynamic languages provide allows the programmer to spend much more time building things and much less time worrying about the details. For sure, when prototyping or experimenting the speed of dynamic languages is a huge boon. However, without type checking at compile time the potential for really difficult to track down bugs is huge.
Just think about the kinds of strange bugs that can happen when any type can be passed into any argument of any method. It gets even worse when you consider that these types may be silently converting themselves. Without great care, the number of potential execution paths in your program could skyrocket.
This can be offset by really strict unit testing and
extremely high code coverage. However, I have yet to see a large real
world project that had this level of testing.
For these reasons I find the new C# "dynamic" keyword rather
worrying. It allows the programmer to declare variables which are only
type checked at runtime instead of at compile time. I would hate to have to
maintain a code base where it was liberally used.
Anders also mentions F#'s static but implied typing system. He talks a bit about the two worlds of static and dynamic meeting in the middle in this kind of way. I agree, this is really the best of both worlds. You gain the "dynamic feel" but get almost none of the downsides. The security of static types without all the extra typing.
I agree that Metaprogramming is a powerful tool, especially for testing. In a ecosystem designed around objects having meaning, it only makes sense to be able to ask questions about those objects and be able to dynamically manipulate how they operate. However, I am worried that it may in some cases become a substitute for well designed architecture.
Also, because of it's nature, in many cases Metaprogramming necessitates the use of strings to represent information about the application. Strings whose contents will not be checked at compile time. Because of this it is very easy to make breaking changes to an application which won't be caught when the program is compiled.
Take for example the idea of a class with a single property. In the code for the application in which that class lives, a code branch depends on reflection to check if that property exists. If you were to rename that property that path would no longer be taken and a bug would result. If the creator of that code had used an interface instead of reflection it would have broken at compile time.
I'm not saying that these kinds of powerful tools shouldn't exist. They are extremely useful in many cases. We just need to be very careful in their use. As Steve Hawley likes to say, when you have a shiny new hammer everything starts to look like nails.
Edit: I want to note that I had intended to include a
subsection on the direct modification of abstract syntax trees but ran
out of time. Also, a good friend of mine also pointed out to me that
Lisp style macros actually do let you work with the underlying code in
a much more meaningful way than C++ style text manipulation.