tlhIngan pejatlh (I Speak Klingon) – Programming in Many Languages
Perhaps like many of you, over the course of my career I have been consistently surprised by my capacity to change technology stacks while still matching my peer group’s standards of technical ability.
Here’s the collections of technology I’ve worked with so far (not counting my internships):
|First Job||Second Job||Third Job||Current Job|
|ASP .Net||ASP.Net||Java / Spring / Hibernate / Groovy||PHP / Symfony / Doctrine / Composer|
|MS SQL Server||MS SQL Server||PostgreSQL and DB2/400 SQL||MySQL / InnoDB|
|No JS Frameworks or usage||VB6, WinForms, WPF||Vanilla JS / AngularJS / jQuery / Dojo||AngularJS|
|No Build System||TFS Build Agent||Jenkins||Bamboo|
|File System… not really version control||SourceSafe and TFS||Git||Git|
|No Configuration Management||VMWare||Puppet||Chef|
Hopefully this doesn’t come across as bragging (or overwhelming or ludicrous) that I’m sharing it with you. I’m mostly using this to help me reiterate something that John recently made exceptionally clear while he marketed his course about learning in his emails to his newsletter subscribers (you can sign up too if you haven't already!).
Our biggest asset as programmers/engineers is our ability to learn, quickly. It’s also something that many of us struggle with, day to day. John brought this to our attention, and shared that he has some material about being a better learner. Thankfully, with teachings like this, even though I had a sharp learning curve to deal with each time I changed jobs, never once did I feel like it inhibited me from rapidly becoming an active contributor to my team.
Learning a Foreign Human Language
I’ve only got a barely rudimentary knowledge of the Spanish language – but it’s enough of an understanding that I could say the wrong thing and end up with a live chicken instead of some McNuggets. (Chicken the animal and chicken the food have different words in Spanish, you know, like Cow vs. Beef. Chicken in a farm = la gallina. Chicken on the table = el pollo). One of the things that always helps me when I brush up on my Spanish is finding ways to compare its words and phrases to ones I know in English. A couple of trivial examples, then I’ll explain how my autodidactic learning applies to programming languages, too:
- calor = hot
- Calorie -> the energy needed to raise the temperature of 1 gram of water 1°C
- amor = love
- Amorous -> showing, feeling, or relating to sexual desire. (This one’s a small stretch because love ≠ lust, but it’s close enough that it works.)
The main thing to understand about learning a language like Spanish is that it’s got Latin roots, i.e., it’s a Romantic language. Much of English also has Latin roots, so the easiest way for me to learn Spanish is to associate it with English words that really seem to make sense in the same (or very similar) ways.
Programming A Foreign Computer Language
So, let’s say that you’ve spent 3-5 years getting comfortable in the Java ecosystem. Specifically, you’ve started using the Spring framework and all that it implies.
Most of the patterns you use in Spring (and other related dependencies) can translate easily to patterns that apply in Symfony (a version of Spring I’m now using for PHP programming). AngularJS offers a similar dependency injection (at least in 1.x).
The most important things to look for when you’re trying to translate your current knowledge into a new environment are patterns that you can use as metaphors to help you understand the way the new language does things that the other one does, too.
While every OOP type of language implements these shared patterns a little bit differently, you can count on all of them being present and use your metaphorical shorthand for them when changing it up. What follows are some of the helpful patterns I lean on, though I’m sure others are out there, too.
Getters and Setters
Though it may seem like a really obvious statement, one of the first things to look for in a programming language is the way that domain classes manage their properties. By looking at the getters and setters for a given language, you can gain at least a rudimentary starting point construct for how they work.
By looking at the simple constructs in getters and setters, you notice that PHP uses $ for variable names and -> for setting values, Java uses ‘.’, and .Net tends to favor PascalCase over camelCase. Here’s a contrived and very trivial example to show you what I mean:
One of the more obvious things that you can see by looking at this is the difference between a statically typed and dynamically typed language. Both Java and C# explicitly define that boolean is the property storing this Starfleet Cadet status as a Klingon speaker. PHP has no such requirements or assumptions, and, in fact, the only way you can even indicate that these functions expect a boolean is with good documentation. This method of association is not going to help you learn the more complicated constructions of the language, but at least it will help you to see how your current language skills might translate syntactically into one that’s new to you. Once you’ve done that, you can start looking for other things. Some suggestions follow.
Programmers work with databases. Whether or not we enjoy it, avoiding it really isn’t an option. One way or another, we have to convince someone else’s machine to put an application into a given state, and the most ubiquitous way of doing that is storing object data within the database. These days, most major players will make use of some kind of ORM (Object Relational Manager). A friend of mine calls these “object relational mangler.” While I’m not leaning towards disagreeing with him, nevertheless you’ll often find that your codebase also makes use of ORM technology. That will give you a good comparative starting point for working in a new codebase, too. Don’t get me wrong – I’m not a fan of mangling to fit ORM patterns. But, when they’re already present, they’re a good tool for finding parallels. All of the languages I’m most familiar with offer more direct access to database constructs as well. PHP has PDO, Java has JDBC, and C# has ADO.Net. All three of these more or less resolve database data into the concept of an array/map/collection where each row is represented by a single indexed entry in the collection, and each column is referenced similarly by a name. If you find plain SQL, hopefully it will serve as a building block for learning how data objects are transferred back into your application.
Plenty of people feel like code should be self-documenting, myself included. However, working in a place that enforces strict discipline of modularity and variable naming that allows self-documenting code to work isn’t always a reality we can depend on. If you don’t work in a place that has code which is self-documenting, hopefully you’ve got the next best thing where all of the PHPDoc/JavaDoc/etc. are well formatted, well groomed, and accurate. And, hopefully your inline documentation tells a good story about the code too. Trusting your code to adhere to decent self-documenting standards is kind of iffy. Sometimes documentation can actually be really helpful in understanding an unfamiliar language. And sometimes you get this:
Honestly, I’ve got mixed feelings about how documentation works in a codebase. For more reading on the subject (and many other amazing topics about the right way to code) check out this book: Clean Code: A Handbook of Agile Software Craftsmanship. Seriously. This is one of the books that most developers should read at least once and reference often.
Unit / Automated Testing
Hopefully you’re working inside of a codebase where you can run unit tests to get an idea of coverage and functional acceptance. I think that regression protection through an appropriate automated test pyramid is one of the foundational building blocks of being on a good project/product/team.
One of the biggest reasons that I advocate heavily for test automation is that it also teaches a person how to use the code in front of them. Hopefully, the tests are well written and can act as a guide through the code by allowing you to learn little bits of functionality as you understand what each test proves.
If you really want to dive in headfirst into a code base, start with the test suite. I promise you no test suite is ever done. You can always find some place to add another test that can help make your code a little more regression resistant. Plus, it’s a very low barrier to entry – if you start learning the code by writing automated tests, you’re not going to break anything.
Just make sure you don’t check in a test that fails to compile (or turns red) unless you want a senior team member sending you here.
I live in the world of Web APIs that communicate with JSON. If there’s one thing you can absolutely count on to map out cross-platform similarities, it’s that HTTP request and response patterns all follow a strict contract regardless of the back-end server infrastructure in use.
If you can figure out how your application server turns /api/v1/starfleetCadets/ into traffic that goes to your services layer regardless of which language you’re learning, you’re going to see similar patterns emerge. As long as you have a well groomed code base, the only thing the web API controllers should do is direct traffic from the HTTP request to the application logic.
This is one of the first places I start looking when I’m trying to learn a new language. JSON is pretty universal and ubiquitous in the web API world, so it’s also a great springboard for finding areas of comfort in a new place.
So, which language is my favorite?
As I’ve heard before, though, there are two kinds of programming languages. Those that everyone hates, and those that nobody uses. And then there are those that just make you want to quit programming and go join the ballet.
All of the languages I’ve used are my favorites for different reasons. They all have drawbacks, sure. But they all have strengths that I find appealing and love applying to the right solution spaces when it makes sense.
Most of us don’t work in a place where we get to choose which language(s) are the right ones for the specific task at hand. Usually, we’re coding to a part of a technology stack and have to make do in the space we work in. However, that shouldn’t limit our understanding of the other options at our disposal.
Programming is as much an art form as it is a science. No one language perfectly solves every problem in a given domain. By striving to create consistency in the chaos, you'll end up mastering more languages than you ever thought possible.