The excellent Pragmatic Programmer book suggests that you should learn a new language every year – this is something which I strongly agree with. By learning a new language it does not mean C# 4.0 (when you already know 2.0 and 3.0), or how to create Silverlight applications. Instead, make the effort to learn a language with a different mindset and approach to what your used to and actively engage in that community. Coming from a JavaC# background, Ruby was an eye-opener for me and approach to software development. The priorities and principals are different, for example Ruby has much more emphasise on elegance, solving problems and testability where software is treated as an art form while still being pragmatic in their approach – it’s never prefect and can be improved at some point. This importance is also being effectively communicated throughout the community from the Ruby guru’s such as Dave Thomas and Chad Fowler to the developers writing applications on a day-to-day basis. As a result of learning more about the Ruby language,
I feel I can approach a solution with a more opened minded approach.
How should you learn a new language?
This is something which I have been thinking about for a while, what is the most effective way to learn a new programming language? There are a couple of approaches you could take, but this is my approach (if you have your own suggestion, please leave it as a comment).
1) Buy a book, but not just any book – the best book. Personally, online materials are great but I still find the most effective way to learn something is to have a physical book by my side. However, be sure to pick your book wisely, I recommend you research the influences within the community and either buy their book, or the book they recommend. The wrong book could take you down completely the wrong path.
2) Start writing tests
Once you have picked your language and book of choice, you need to start grokking the concepts. After trying a couple of different techniques, I’ve found the best way to learn a new language is to actually write tests. This isn’t as crazy as it might sound, the test will define your expected outcome from your sample and give you something to aim for. This will help focus your mind on the task in hand, while giving you a clear signal as to when you are complete – the test will pass.
For example, with C#, if I wanted to know how to write a line of text to a file I might write the following test with the implementation.
public class IO_Examples
{
[Fact]
public void Write_Hello_World_To_The_File_HelloWorldTxt()
{
MyFileAccess.Write(“Hello World”, “HelloWorld.txt”);Assert.True(File.ReadAllText(“HelloWorld.txt”).Contains(“Hello World”));
}
}public class MyFileAccess
{
public static void Write(string s, string file)
{
StreamWriter streamWriter = new StreamWriter(file);
streamWriter.WriteLine(s);
streamWriter.Close();
}
}
I have also found tests to be a much more natural starting point for interacting with a language, with C# my starting point was a command line application, however this wasn’t the most effective way of learning as I was constantly commenting out calls to various methods to execute the correct block of code. By using a test framework and a test runner as your starting point, I would have been able to run the samples more quickly and effectively while still keeping everything readable.
However, if your anything like me, while learning you will end up going off on a tangent or being distracted mid-task, I can recall too many occasions where I have been deep in the middle of learning the inners the underlying code only to read a blog post which takes me in a different direction and then completely forgetting where I was. By having a test, or a series of tests, guiding me I am able to quickly get back on track by seeing which tests are currently failing. Because the tests will describe my aim, I will have a much better chance of remembering what I was actually doing.
Finally, once you start moving onto real applications and solving real problems using the language, you will be able to look back and refer to the tests as a reference regarding everything you learned. If you keep your tests in a source control repository, you will even be able to see how you adapted over time. This could be extremely useful a year down the line where you want a very quick refresher.
3) Solve a problem!
Once you have an understanding of the language with a series of tests describing how to do various different tasks, the next thing to do is solve a problem you, or someone else, is experiencing having. While this isn’t always possible, it’s a great motivator to finish the job. I enjoy automation and improving productivity (it allows me to spend more time on twitter), I find it really interesting to see how problems can be solved in a more effective fashion using tools and technologies – if a new language can help me with that then all the better. Not only will I learn the language in a more ‘real world’ context, but it will be helping me in the future.