07 architecturalist papers: How micro-services made picking a programming language different

Cross posted from here: http://wrongtool.kostadis.com/07-architecturalist-papers-how-micro-services-made-picking-a-programming-language-different/

Once you become an operational or strategic architect, programming languages become an option in the toolbox. And then the question becomes which one to pick.

The most important considerations when I started my career were:

  1. Can the language interface with pre-existing code
  2. How mature and stable is the programming language
  3. How many programmers can you hire that know the language
  4. Does the language have a debugger and a profiler
  5. What tradeoffs does the language impose regarding performance and safety and portability.
  6. What specific libraries and tools and constructs does the language provide for making the project go faster

With large monolithic systems of the 1990’s, #1 forced you to keep the same programming language indefinitely. Unless someone signed up for a rewrite, you had no choice. Even in the case of a rewrite, you always wanted to leverage some of the pre-existing code.

And in the 1990’s the most important piece of code you had to leverage was OS system services.

Microsoft and other programming language vendors attempted to invent program language technologies that allowed applications to call from one another, but the tools didn’t quite work, and they locked you into a specific vendor and OS. The first C compiler I bought from Microsoft in 1987, had a long discussion of how you could get basic and C to work together.

And you still had the whole problem of cross-OS portability.

Attempts at standardizing libraries through things like POSIX didn’t work at all.

What changed in the 2000’s was the movement to multi-process application architecture using databases as a mechanism to exchange data. The database was cross platform, and vendor neutral and language agnostic. And all of a sudden, choice became an option.

And more importantly, C++ was a real option because it was designed to solve #1 and #5.

In 2004, when I had an opportunity to pick a language as the operational architect for the NetApp Performance Advisor, I chose C++.

I agonized over the decision for a month, because — based on my prior experience, this was a once in a decade decision.

And the reasons for C++ were:

  1. C++ could call into all of our C code.
  2. C++ was much more mature than Java at the time
  3. C++ programmers were easy to hire, and C++ programmers could work on the C parts of our system.
  4. Working debuggers and profilers
  5. Allowed us to trade off some performance for safety (string class instead of char*, and reference counted pointers) with no loss of portability across the platforms we care about.

My old school thinking decided that the Java Native Invocation was just too clunky as a mechanism to leverage our existing C code base. And I had spent a lot of time in college writing C++ wrappers and had no time to do that for the huge Data Fabric Manager code base.

Furthermore, I remember thinking that C# would crush Java because it made calling code from C# into C/C++ easier…

Except…

Java, in the end, won, because the service architectures were just a better way to write software, and using the database as a way to get different parts of the system to talk to each other made it easy to add Java to a system.

Applications no longer needed to call into libraries, they could use the database to share information. I believed that this was a dead end architecture because database — increasingly became a bottleneck, and that would lead to large monolithic Java systems and that would lead to a stable Java dominated ecosystem except…

The emergence of SOAP and JSON and REST made it even easier to combine programming languages and circumvented the DB bottleneck.

In the 1990’s picking a language was a once in a decade decision, now picking a language became a pretty standard decision. And that leads to a new problem for strategic software architects, given that operational architects can pick any language at any time, what guidance do you give them?

In short, the basic model still holds, except for one minor tweak:

  1. Can the language interface with pre-existing code
  2. How mature and stable is the programming language
  3. How many programmers can you hire that know the language — and how easily can they move between languages.
  4. Does the language have a debugger and a profiler
  5. What tradeoffs does the language impose regarding performance and safety and portability?

And that last tweak is hugely important. Each service has a life span, and engineers have to be moved between services as business priorities change. And having different languages creates friction in your ability to move people.

At Zynga, Cadir was adamant that we only support two backend programming languages (C and PHP and Java) because he valued the ability to move engineers easily very highly.

I, personally, loathed PHP and found C to be too low-level and could never quite get over my initial interaction with Java in 1994, but he had a good point and fully supported his decisions. One time, I forced a team to rewrite their Ruby code in PHP because of our policies.

And Cadir’s decision was a huge win because it people could easily move across the company, and sharing code was very easy.

And this leads me to the conclusion that the real list now is:

  1. How mature and stable is the language including debuggers and profilers?
  2. How easily can programmers move between services
  3. What specific tools or constructs does the language provide for the domain problem.

You’ll notice that this, the most important property in 2004, got dropped,

  • Can the language interface with pre-existing code

Because that’s basically a solved problem.