Date
Tags essays , cs

Intro

The "polyglot approach" is a strategy wherein multiple programming languages are in use inside a single company/department/team. For the purposes of this essay, let's also assume this means actual day-to-day production code (i.e. not legacy, skunk-works, small experiments, or tiny one-off in-house tools).

You're already committed to working with and/or hiring the best people you can find, right? In that case, I think going polyglot is almost always a good idea, but a lot of people will disagree. Typically employers agree that the best programmers have experience in several languages and paradigms, but opinion about whether it is actually smart to design products or projects using a bunch of different technology will be much more divided.

Obviously modern web development already involves at minimum HTML, CSS, front-end JS, some SQL, and your server-side language of choice. But it's not really my intention here to talk about "full stack developers", 1 Rather, at least in the context of web-development, I think of "polyglot" as meaning that at least a few different server-side languages are in play (for example with vert.x).

Rationale

1. Polyglot is Good for Business. Almost all software development today leverages open source to some degree. The reason why is dead simple economics.. development is costly and taking advantage or prior art reduces those costs. By the same logic, a polyglot approach gives companies access to more prior art, thus helping them to remain competitive in a rapidly changing market.

2. Specialization is for Insects. Good software engineers should be just that.. software engineers. Not "microsoft engineers", and not "golang engineers", not "java engineers" or "python engineers" or "javascript engineers". Specialization is for insects.2

3. Polyglot Programming is Part of Responsible Engineering. When all you have is a hammer, everything looks like a nail. Using the right tool for the job is just a fundamentally important part of being a good craftsman. To add a bit of concreteness to exemplify cliches.. sometimes typing is important, sometimes performance is important, and sometimes dynamism, reflection, agility or glue are really what you need to solve problems. It's rarely the case that one language does all of these things well at the same time, but it is often the case that individual projects must solve many types of problems. To put it in another way, problems today are poorly served by coding cultures that insist on monolingual, monoparadigm approaches.

4. Polyglot Programming, or the Mere Possibility of it in the Future, Encourages Good Design. This point is tough to nail down, but something about keeping interoperability concerns front-and-center just tends to naturally encourage architectures that emphasize separation of concerns, KISS, and the unix philosophy in general. This results in teams that are more likely to converge on sane architectural decisions almost effortlessly. The alternative to "sane architectural defaults" can mean a need for more explicit consensus-seeking (i.e. endless meetings) or a nearly constant burden of direct architectural oversight (i.e. senior devs and architects are so overwhelmed with gate-keeper code review duties that they cannot make other contributions).

5. You're Most of the Way There Already. Modern software systems are often simply too complicated to conceptualize and build as monoliths. Thus we see that distributed, modular, and highly-available designs are rapidly becoming the norm. It's also the case that well designed system modules tend to

  • have well-defined responsibilities and boundaries, and
  • operate at least somewhat autonomously and asynchronously, and
  • communicate via message-passing

The devil is in the details, and frankly no one is saying these design considerations are always easy to deal with. However, typically there is already a strong business need to address them for one reason or another. Conveniently, the same patterns in the solutions to these problems are reusable to help your polyglot-environments communicate and retain interoperability.

There are lots of other trends that promote interoperability between languages:

  • Transpilation technology is getting better and better.

  • Things like the JVM and Erlang's BEAM host multiple languages now, and some level of support for passing data between systems is common.

  • Sufficiently large projects almost always eventually require message queues for something.

  • Still no message queue in your shop? Well there are many, many options for persisting data now, and infrastructure is increasingly effortless to setup and maintain. Hosted offerings like SQS mean that you don't need to commit to dealing with the operational hassle yourself.

  • In recent years there has been a massive revival of interest in the functional paradigm3. Especially compared with OOP the functional paradigm is usually more amenable to interlanguage interoperability. With OOP one faces the hassle of serializing objects to queues, or the operational necessity of fronting objects with services that then need to be versioned and load balanced, etc.

  • Even if you're not on board with full-blown microservices you're probably already using RESTful APIs everywhere right? Consider speaking swagger or JSON-schema to implement contracts between subsystems.

  • IDLs often inspire extremes of love or hate, but at least we can say there are stable and mature options. For instance Thrift and protocol buffers have both been around for like a decade now.

  • First-class, language-level support for calling or embedding alien code is a feature that more and more people want, especially for things like data science (ex: Julia)

6. Polyglot Enhances Quality of Life for Engineers. Thinking only in terms of one tech-stack is like trying to dance in a straight-jacket. This is not a plea to allow every engineer to chase whatever shiny new technologies have captured our fickle fancy this week. This about letting your trusted experts exercise the expertise they were presumably hired because of. As engineering professionals, we should all be aiming to make informed, data-driven, merit-based decisions. So-called "resume-driven development" is stupid, selfish, and extremely unprofessional.. but because one person should not be calling all the shots by themselves, resume-driven development should never be able to become a real problem in a mature organization with mature engineering processes.

Issues

In this section I'll try to give brief rebuttals for the usual objections to adopting a polyglot, poly-paradigm culture in the workplace.

But, multiple languages and multiple paradigms add complexity. Naturally this is true, but so does everything else! Managing complexity is in many ways the fundamental problem of computer science, and for that matter a fundamental problem of engineering / design in general. Since complexity cannot be avoided, the only way to move forward is to be thoughtful and deliberate about it, exercising our best judgement to only add complexity when and where it suits us. The rebuttal here just comes back to what I've already said about leveraging prior art and using the right tool for the job.

But, multiple languages and multiple paradigms make hiring difficult. It's true this makes things more difficult for interviewers, because they need to ask thoughtful questions and not syntactic trivia, but on the other hand it should actually increase your candidate pool. Anyway, assuming you are committed to hiring/working with smart people, this concern should really be a non-issue. It's often the case that learning a new framework in the same language can be more difficult than learning a brand new language. People with serious talent or lots of experience can learn a new programming language for breakfast and contribute by lunch. Other competent programmers should almost always be able to get up to speed in 2 weeks or less, especially with access to a large library of pre-existing example code and a bit of patient tutelage from colleagues.

But, specialization is actually good because it allows for efficient division of labour. There's a kernel of truth in this, but at the same time almost everyone has had the experience of being burned by specialization when the only person who understands a system decides to leave. Polyglot cultures tend to mitigate this problem somewhat insofar as they encourages high-level documentation, well-defined system responsibilities and boundaries, and a small-is-beautiful approach to design. It's also worth noting that it is often in the best interests of the both the employer & employee to mutually agree to only temporary specialization. Just consider how many engineers have career goals that move them into management, and how many workplaces routinely promote their engineers into leadership.

But, we don't have the expertise in-house. This is related to, but slightly different from the oft-referenced hiring problem. Again, to be blunt, the fact is that if you have an architect that can only critique design proposals on the .NET platform then you don't actually have an architect at all! You should consider getting one :) If you have developers that cannot conduct a simple code-review for code written in familiar paradigm but an unfamiliar language, then you might have lazy developers. Doing a decent job of code review for a language that one does not write should be possible, even if it requires more back-and-forth conversation until everyone is up to speed.

But, using multiple languages complicates operations and CI/CD. In my opinion this concern is the most legitimate thus far. However.. many shops are already in a position to sidestep this issue more or less completely because they are taking advantage of containers, PaaS, IaaS, and other cloud offerings.

But, sharing code is problematic. This is another very valid concern, but is only a complete shower-stopper in the kind of work environments where everything is a library or everything is in the same monolith. If this describes you, then regardless of whether you want a polyglot culture, it might be worth considering a refocus on building tools, services, and APIs instead. In most circumstances interface-specifications are harder, more interesting, and much more important than the vast majority of actual implementation effort. If we take that as a given, then it seems clear that regardless of whether we want a polyglot culture, we should still try to follow a design by contract approach as much as possible. In conclusion if you're already using design-by-contract and creating APIs, then the response to the code-sharing problem basically reduces to what's already been hinted at in the You're Closer than You Think section.

  1. Unfortunately I think that "full stack developer" is mostly a phrase that has been hijacked as shorthand for "As an employer, I want one person to handle graphic-design, operations, web development, and QA".
  2. "A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects." - Robert Heinlein, Time Enough for Love
  3. One could argue this began with massively scalable map-reduce implementations becoming available to the masses, and is culminating now in functions-as-a-service, like AWS Lambda)