This can unleash so much hate mail, but here it goes, my inbox is ready!
Are dynamic languages just a temporary workaround? I’m not sure! I’m switching between the two types of languages all the time: Java, Python, C#, JavaScript. I’ll try to make the long story short.
Statically typed languages, like Java and C#, are nice because when you do
blah.bleh()
you know that blah’s class has a bleh method, at compile time. But better than that, when you typed “blah.” you get a list of methods, and you already know whether there’s a bleh method or not, and if you typed bleh and it doesn’t exist, the IDE lets you know, no need to wait for the compiler. Also you can do very deterministic refactoring, renaming all “bleh” for “bluh” for example.
Statically typed languages are not nice because they are very verbose and require a lot of boilerplate (if you’ve used Haskell, just bear with me for now please), so you end up with things like:
List[Car] cars = new List[Cars](); foreach (Car car in cars) { car.Crash(); }
How many “cars” do you read there? And that’s a nice example. There are worse. So come dynamically typed languages and you can write:
cars = [] for car in cars: car.crash()
You have less cars, and less (no) lists. That means you are more productive. You start chunking out code faster without having to stop and think “What type of object will this or that method return?”. But crash() can crash your application instead of just the car because you can’t know if it exists until run-time. That might be OK or not, testing and whatnot.
Then comes C# 3.0 where you can do:
var cars = new List[Car](); foreach (var car in cars) { car.crash(); }
And you can see that syntactically it got closer to Python, which is what gives you the productivity. Don’t know the type? type “var”. But semantically, it’s still statically typed, like the previous statically typed example. You know that car is going to be of some class that has a crash method. You can actually know car’s class at compile time, no need to run it.
That’s called type inference. You don’t have to specify the type where the compiler is capable of inferring it for you. C# type inference system is still very limited (but better than Java’s). Let’s see an example in another language
cars = [] map crash cars
That means, create a list called cars, call the function crash on each car. Would you say that that is a statically typed language? or a dynamic one? I’d say it is dynamic, but it is static. Very static. It’s Haskell. Haskell’s compiler will infer all the types for you. It’s amazing, you’ll write code as robust as with C#, but as terse as Python’s (Monads will then kill your productivity, but that’s another story).
In Python 3 you can define types for arguments. They are mostly useless, but it’s an interesting direction. I think the best it can do is that when a program crashes it’ll tell you: “function blah expected an int, but got a float, not sure if that was the problem, but you might want to look into that”.
Now, my question is, are dynamically typed languages just a temporary workaround? As our compilers get better, our computers faster, will statically typed languages keep giving us as many or more reassurances about our code and utilities while at the same time they become as simple and terse as dynamically typed languages? Or will dynamically typed languages start to gain types and over time be more static without the programmers that use them ever noticing?
My question is, will we in the future, 50 or 100 years, look back and said “Dynamically typed languages where a temporary workaround to statically languages being painful to use when human beings and their toy computers were so primitive?” in the same way we can say today that “non-lexical scope was a limitation we had and have due to the limitations of computer hardware 30 years ago”.
Reviewed by Daniel Magliola. Thank you!
Related posts:

#1 by Nes on 2009-10-20 - 19:57
It is more of a trade-off. The fundamental problem is that to get good type inference is hard and takes a lot of compiler effort (LOC/size in the compiler). The second is that you can’t properly typecheck 50% of a program with the rest provided in the future as plug-ins. That makes it a bad fit for a small implementation of an embedded scripting type language.
Also type errors in inference based languages like Haskell can sometimes be really hard to understand. And it is frustrating for a programmer to have a compiler error and not knowing how to fix it. Runtime type errors on the other hand are very specific: “this particular thing didn’t work”.
#2 by Hueoogle on 2009-10-31 - 10:35
Pablo, I think you are asking a rediculous question. Its not a question of which one is better. Its a question of which one is better for the requirements of the current project. If this means, that I need to purchase widget A from Widgets incorporated, I want it in a static language. Ever try to learn hundred of lines of code of a third party API in a dynamic language? When docs are horible to begin with? My hats off to you if thats what you can do. But static languages have there place when you are learning that third party, which, in a sense, you could even say that ‘JAVA’ IS….. with all of its SUB-API’s, could you imagine all of that being written in a dynamic language and trying to master it? No way. I am saying, statics dominate currently for a reason. Dynamics do certainly have there place. But have you been at a new job, sat down, and been given 10 thousand lines of dynamic written code in javascript that isn’t working properly to fix? GOOD LORD, you just want to get up and leave. Written in Java? or any other strong typed language, you might go home happy your first day!
#3 by Onne on 2009-11-26 - 07:45
Imagine sending a message to a remote server? Can your compiler know how to invoke that routine on the remote server? Can it statically check it? Does the remote server have to be implemented in your language?
No.
So dynamic typing is something akin loose coupling.
#4 by GDR! on 2009-11-26 - 15:11
Hueoogle – I can’t agree with you. If you were given C code (C is a static language), you will probably fail as hard as when you are given Javascript. Every C project has its own way of managing memory, usually also its own implementation of data structures and such.
It’s more about programming philosophy – Python’s “there is only one way to do it” makes it easy to read *good* code, even though it’s dynamic.
#5 by dirtside on 2009-11-26 - 16:31
Human beings and “their” toy computers? Are you suggesting someone besides humans is going to be looking back on our programming architectures 100 years from now? ;)
#6 by josh on 2009-11-26 - 17:06
You example for static typing being more verbose is a straw man argument. It doesn’t show how type inference makes things less verbose, and it is also trivially small.
#7 by sys on 2009-11-26 - 22:01
Man, I sure hope so. That’s why I hope Go will catch on and become as ubiquitously available as perl is.
IMHO, loose coupling isn’t always a good thing. I’ll take Ada over Ruby any day of the week.
#8 by Cyril Gupta on 2009-11-27 - 05:38
Pablo, you’ve already noticed that statically typed languages are taking on the characteristics of dynamically typed ones. C# 4 has enough dynamic typing features to make a lot of things possible, and Scala too introduces new synergy between statically typed and dynamic typed languages.
So I guess the right path is the medium path, just as Buddha said.
#9 by RogerV on 2009-11-27 - 20:54
Go has the benefit of static type checking and type inference as well for eliminating unnecessary syntactic cruft.
Unlike Perl and Python, or other scripting language solution approaches, it blazingly compiles/links into a single executable for ease of deployment to the end user.
Deploying script languages solutions to end users is just a mess. You have to insure the user has the right runtime version and often times they’ll need certain C libraries to be installed too, and then for complex apps/tools, there may be many script files involved and you have to deliver the app in such a way that none of the package/module references get screwed up at runtime. Or else buy a commercial SDK from ActiveState to roll Perl or Python apps into a single executable (which, doing that with such solutions is still not a simple endeavour).
The shear simplicity of the Go approach (static linking) is a breadth of fresh air relative to the scripting languages. Plus the compile/link process is lightening fast.
The crown jewels of Go, though, tend to be the goroutines and channels approach to concurrency programming. Facilitating robust, scalable, and low boiler plate concurrent programming will be important in programming languages going forward. Go will be stellar in this regard.
Plus the approach to OOP in Go is rather interesting and refreshing too.
Alas, Go is so young that there’s not (to my knowledge) any IDE support that does code completion yet.
#10 by Kazimir Majorinc on 2009-11-28 - 09:19
From my point of view – I do not need any kind of debugging help from programming language. I do not need static typing, lexical scope, asserts, contracts … I need only expressive power, and if I’ll need some debugging help, I’ll take care about that.
I understand that other people have other priorities, so it is only an illustration of possible opinion.