We see this question quite a bit in programming by people who are just getting started. Which language should I learn first? The answers can vary, but inevitably the most popular choices that get recommended are dynamic languages like Ruby and Python. While both of these languages get high marks for getting a new developer to hello world quickly, I have noticed some pretty big issues with the personal growth of developers who start there. So at the risk of a flame war, I will lay out why I believe that learning a static typed language first is a great way to start your programming career. Note that this is a very contentious issue.

What is the difference between static and dynamic languages?

In a static typed system, the compiler that creates a running program from your code requires you to let it know what types of data are being used and enforces that they must be compatible.

For example, in a language like C#, we could declare a variable that stores a string (text) like so:

string message = "hello!";
message = 37;

In C#, this code will not compile, it will give you an error message along the lines of “can not convert int to string”. When we declared the message variable, we told the compiler we would store text in it (text in C# is placed between double quotes “”). However we turned around and tried to put an integer in it. The types don’t match, and that is not allowed.

However in a dynamic language like JavaScript:

var message = 'hello!';
message = 37;

Works just fine. Now let’s look at a method in C#:

int Add(int x, int y)
{
return x + y;
}

Here we can see that the method Add takes in two integers and promises to return an integer. The method syntax in C# is ReturnType Name (params).

Going back to JavaScript, types don’t matter:

function Add(x, y) {
return x + y;
}

Note the lack of types. So it’s perfectly ok in JavaScript to say Add(1,2), it will return 3. But you can also say Add(“blue”, 5) and it will return “Blue5”.

Wait what? You can add “Blue” and 5?

Sure, that’s part of the beauty of a dynamic language. The argument is that you don’t have to think about types, so it just gets out of your way and lets you “Just Write Code”. You can redefine anything at any time. You can add new functions and data to an object at any time. Whether or not this is a good thing is a source of fierce debate.

Do Dynamic Languages Create Working Code faster?

Well it depends on how you define working code. My definition of working code means the following:

The code is written
The code is debugged
The code is documented
The code is maintainable

The important thing here is documented and maintainable. In software development, particularly in the enterprise, we aren’t just concerned about the code now, we’re concerned about how the code can be maintained down the road.

I tend to believe that static typed languages create working code faster, and are a better experience for the new developer.

Static Types Make Finding and Fixing Simple Bugs Easy

When we teach JavaScript to our C# and Java students at The Software Guild the most common errors we come across are relatively simple. We misspelled a variable or function name or some data we were expecting to be a string was instead a number.

Type errors in static typed languages let you know at compile time that an error exists, what file it is in, what line it is on, and a hint as to why it is a problem. These errors can often be fixed in a few seconds.

But What About Unit Testing?

Most of your dynamic languages like Ruby require lots and lots of unit testing and would go so far as to claim this eliminates the benefits of static typing. However, in practical usage, a unit test in this case only tells you that a bug exists, what module it was in, if you’re lucky a stack trace (but usually not), and the ability to reproduce the bug.

Don’t get me wrong, Unit Testing is important in static typed languages as well. The difference is that in dynamic languages oftentimes the unit testing is taking the role that compiler serves in static languages, so again with the working code, you aren’t duplicating the effort of the compiler.

Welcome to the debugger! In this case errors can take seconds if you are very fortunate, but in reality it’s usually minutes or hours to figure out the issue.

Large Scale Programming != Prototyping

When you are working on tens of thousands of lines of code for applications that live for years with many developers… the benefits of static typed languages really start to shine. This is why most established enterprises use Java, C++, and C#.

As I noted above, in a dynamic language “blue” + 5 is meaningful. Fans of dynamic languages will say “don’t do that”. Well, that is fine when we are working with a small team and small application where the domain and team conventions are more easily understood by everyone. But “Don’t do that!” does not scale to large teams and when you can’t hold large parts of the domain in your head.

As a team grows larger, the probability of having an idiot on your team grows to 100%… quickly.

Now, idiot is a mean word, but I use it to mean everyone. Everyone is an idiot sometimes. We get tired, we forget things, we remember things to wrong way. Static typing prevents you from committing idiot errors, like say, adding an int to a string.

In a large scale project documentation is exceptionally important! Not only that, but it is harder because more code means more dependencies and more complex interactions. When you can quickly look at a method and ascertain what the return type is, a well written method becomes self documenting. And if that return type is a class, you can quickly jump to the definition of that class. So static typed languages are more self documenting.

Code Must Change

Change is the only constant in code, and your function’s behavior is going to change. What today returns an int may someday change to be a nullable int because a new case dictates that is now valid, and then later we might want to also return a status message, so now it’s going to be returning a new type of object.

When these requirements change and your return types change.. now we have to ask the question “What needs to get fixed now?”

What code is using this function?
Where does that code live?

Unit testing will tell you “Something is broken”. But static typing will tell you “this code right here on this line is broken”.

The time savings are enormous in refactoring static typed languages. Time savings save you money. A lot of money.

Static Languages Make You Think About Structure

The primary argument I tend to get from fans of dynamic language first people is that it saves time because you don’t have to think about structure. It gets your code running faster. Initially, I do agree with this premise, but I have witnessed over time that it will eventually get out of hand, and new developers will not understand what is going on anywhere! Not having clearly denoted types requires the developer to keep a large amount of source code in their head in order to trace the chain of the application.

I have news for you though. In a typical developer career you will spend orders of magnitude more time reading and attempting to understand code written by others. This is where static typed languages really shine. They force you to actually think about how to organize your classes and objects. They don’t allow you to just kludge new members onto objects whenever you like. So if you want to know what a class does, you just look at the definition.

I think this is a very important benefit to the neophyte coder. The hardest thing about learning to program is not the language syntax, it is how to think about problems. Since languages like C# and Java require to you define you inputs, outputs, and class structures it helps the beginner to really examine the structure and flow of applications. It teaches them good organizational habits that they can carry over to dynamic languages.

In fact, one must realize that all problems have a given level of complexity. You can move complexity around and try to shift it to another area, but you can not completely destroy complexity. Even if the language doesn’t require you to declare the data type you are using, you still must know what you are modeling and you must make sure you’re doing this correctly. There is no escaping thinking about structure and solving the problem. The main difference for me is that in a static language, it’s clear to me when a method returns a customer object and what the members of that object are. In a dynamic language you often have to dive into the code at a more detailed level to figure that out.

In Conclusion

Do not take this as a slam on dynamic languages in general. I think they’re great in their domains. JavaScript is a must have for a web developer. Python is a wonderful language that is increasingly becoming the go to for network admin related scripting. Ruby with Rails can fire up a data driven website faster than almost anything out there. In the hands of a skilled practitioner these languages can accomplish much with a little.

However, when learning, the focus should be on the structure, organization, and flow of clean, maintainable code. My experience in teaching and as a professional developer has shown me that people that start with static typed languages can move to dynamic languages fairly easily and be productive. People raised on dynamic languages who try to move to static typed ones tend to really struggle because of that difference in thinking and defining structure before you write the code. While any language can allow for an application that turns into a Big ball of mud, it is much easier to accomplish this in a dynamic language!