Monday, June 15, 2009

So just what is a Dynamic Language anyway?

It's remarkable to me how many friends I have in the business who aren't really sure just what the heck a dynamic language is anyway. Many things they say to me indicate that they don't know what a dynamic language really is. For the record, let's clear it up.

Let's start with a quartet of distinctions.
  1. Object Oriented Language
  2. Interpreted language
  3. Weakly typed language
  4. Dynamic language
  • An OOPS language is not necessarily interpreted, weakly typed, or dynamic.
  • An interpreted language is not necessarily OOPish, weakly typed, or dynamic.
  • A weakly typed language is not necessarily OOPish, interpreted, and not necessarily dynamic. This is one of the most frequent bits of confusion. Many believe Weak = Dynamic.
  • A Dynamic language isn't necessarily interpreted, but it is always OOPSy and weakly typed.
  • With that said, most dynamic languages are interpreted and weakly typed.
Here is a list of languages that are not dynamic, although some think they are:
  1. JavaScript
  2. VBScript
  3. Perl
  4. PHP
  5. Lua
Here are a list of languages that are truly dynamic:
  1. Smalltalk-80
  2. Python
  3. Ruby
  4. Groovy
So, you will notice that most of the popular and well known interpreted scripting languages are not dynamic. More obscure choices, selected by the ubergeeks, are the dynamic languages. Being weakly typed is necessary but not sufficient to be classified as a dynamic language. I would have said that being interpreted was necessary also, but then along came IronPython.NET and blew my world appart.

So what is the key? What distinguishes the dynamic language? The answer is in the meta-programming model. In a dynamic language, no class is ever final, not even at run time. It is not only possible, but common for a dynamic interpreter to mock-up or attach methods to a class or object at runtime. I can also tack on additional properties at runtime. I can also write code that edits its own source code, and dynamically reloads it on the fly. I can create self-mutating code. This is the key feature which permits research into genetic algorithms.

Can I attach new methods and properties to a class at run-time in Java and C#. No, not per se. There are ways to try to achieve a similar effect, but these belong in the category of dirty hacks. This approach is absolutely not supported by either of these languages. How about VB.NET? Nope. How about VBScript? Please! This isn't even an object oriented language! How can you attach new properties and methods to something that is not a class in the first place? Same thing goes for JavaScript.

So why the hell would I want to dynamically dispatch new methods I never intended to be a part of my class when I designed a wrote it? Why would want to dynamically attach additional properties to the object at runtime? Isn't this unsafe and unsound? Aren't I allowing the interpreter to alter my architecture in ways I did not intend?

Maybe, if you don't know the language and don't know how to use it.

What if I do know the language and do know how to use it, doesn't the mere existence of such a feature open the door to entirely new categories of unintended consequences and unpredictable behavior?

That is the rub now, isn't it? We have put out finger on the exact point of critique which serious computer scientists have been arguing about for several years now. Decades really. Ever since Smalltalk-80, this debate has been running among serious men of great learning and skill.

The majority have chosen not to use dynamic languages. The majority have chosen statically typed OOPs. A rather small minority have chosen dynamic languages.

So, why have those who have chosen dynamic languages chosen dynamic languages?
  • Very loose coupling. You can pass anything to anything. If it works it works. Very large systems can be built this way.
  • Interpreter safety: If it doesn't it throws a soft error and you make a correction. The OS does not crash.
  • Auto-Mocking. These days, we have come to recognize that we need automatic testability for all code. We call this Unit Testing. We aim for 100% code coverage. This means we want every line of code automatically tested in a unit test project. To facilitate this process, you need something called mock objects. These are objects that doppelgangers for dependencies your test unit needs to function, but they do not produce the real world side-effects. Real files do not appear and disappear. Real records are not created, read, updated, and deleted.
  • Mocking in a static language like C# and Java is a real pain. Python and Ruby just construct Mocks for you, dynamically attaching empty properties and methods for your. You never need to write Mock object when doing TDD in Python or Ruby.
Isn't there a substantial performance penalty for this approach?

Yep, Ruby and Groovy are the two slowest languages currently accepted in the world. Although Smalltalk and Python are faster, they are not that fast. We can pretty well destroy them with C#.

With that said, a fully compiled variant of Python, called IronPython.Net is now making some waves in the world. IronPython's compiler is written in C#, and it cranks out CIL like all the languages on the .NET platform. This CIL assembly is locked and loaded by the CLR and handed over to the JIT for transformation to x86 or AMD64 code. That code is greatly fattened and slowed by the dynamic approach to things, but it is real machine code. IronPython is now something like 8x faster than standard C Python. It is still not as fast as something like Java or C#, but it is still far better than it's brother and cousins in terms of performance.

I personally am very interested in IronPython.Net. However, I am more interested in Scala.

My religion is generally opposed to Dynamic languages. I believe in static typing. I believe in a strong compiler. I believe in things like checked exceptions. I love design my contract. I love annotating requirements on code. C# does not give me as much static verification as I would like. I hope Scala is better. Python means busting my version of the 10 commandments. This is risky, and I dislike the notion. However, I am trying to keep an open mind, and determine whether IronPython can provide some wonderful new service to my .NET applications.