RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Polyglot Programming: Building Solutions by Composing Languages

This article delves into the motivation, benefits, and challenges of writing applications using polyglot programming—leveraging the multi-language nature of the CLR to create simpler solutions to vexing problems.

ack in 2006, I coined the term polyglot programming in a blog post. It is not a new concept (being at least as old as Unix and probably much older-I just attached a modern term to it). That blog post was a response to what some are calling a renaissance in computer languages. Polyglot programming refers to using special-purpose languages combined in the same context to create better problem solutions. To illustrate the concept, this article reviews some recent history about the abstraction mechanisms that developers use to solve problems today, and points to a new way to do so in the future.

A Historical Framework
For the last 20 years or so, developers have been building virtually all applications using object-based languages. Object-oriented programming appeared first in Simula 67 (in 1967), but wasn't widely adapted until Smalltalk became popular.

One of the promises of object orientation is ease of code reuse. Certainly, the core characteristics of object-oriented languages provide the facilities for reuse: encapsulation, polymorphism, and effective abstraction. But developers found it hard to achieve large-scale reuse using these atomic building blocks. So, they've resorted to two approaches that use object-oriented features as building blocks: components and frameworks.

Components work extraordinarily well for visual reuse. VBX, and later, ActiveX controls showed that it's possible to create a vibrant ecosystem of reusable components. Building non-visual behavior is harder. Windows platform developers have seen several attempts carrying acronyms as COM, COM+, MTS, BizTalk, etc. And that's just the .NET space. The Java world took the good ideas of MTS and went down a long, dark path with Enterprise Java Beans. And yet none of these techniques for achieving business domain reuse has worked well (which is why we keep trying).

Components rely on a certain physical ecology to work: tools that understand how to display property inspectors, event mechanisms, and lifecycle control for the components. This ecosystem represents the other great example of code reuse—frameworks.

Frameworks have become the preferred reuse mechanism. Frameworks consist of a large number of related classes with shared context. The most pervasive is, of course, the .NET framework, which includes several smaller frameworks (ADO.NET, ASP.NET, etc). Ancillary frameworks exist outside the Microsoft-supplied ones: log4net, nHibernate, iBatis.net, nVelocity, etc. None of this is news, of course; as a .NET developer, you've been steeping in this abstraction style so long you no longer even notice it.

But underlying this abstraction mechanism is the idea that you can have one true language to solve every problem. The one true language in .NET is either C# or Visual Basic. These general purpose languages let you interact with components and framework reuse mechanisms. This works well for many of the kinds of applications you need to write, but it also has its shortcomings. The idea that you can create a single computer language that solves all (or even most) problems ignores the vast variety of problems that developers must solve. Extending the one true language with frameworks helps with difficult abstractions, but masks the fact that sometimes the language you use is poorly suited to the problem you are trying to solve.

Object-orientation is an effective abstraction mechanism because it organizes things in hierarchical fashion. Most of the world (as viewed by developers anyway) is hierarchical or can be mashed in to a hierarchy. But developers keep running into cross-cutting concerns: transactions, logging, security, etc. These don't fit well within our existing hierarchies. This idea is illustrated in Figure 1. Thus, aspect-oriented development was born.

Author's Note: The concept of aspect-oriented programming was introduced in 1997 in a paper by Gregor Kiczales and others in the Proceedings of the European Conference on Object-Oriented Programming, vol.1241.

Figure 1. Cross-Cutting Concerns: We need cross-cutting concerns to handle some of the problems that routinely arise.
For those not familiar with it, aspects weave code into existing hierarchies. Aspects have a specific syntax (different from either C# or VB) that describes pointcuts—places where you can inject code (using a special compiler) directly into the compiled artifacts. As an example, aspects let you define logging code in one place. Then, the aspect compiler adds the code necessary to make all your logging calls by injecting byte code into your compiled program. That happens without you having to alter the code in your program manually. Consider this simple class:

   public class MyClass {
     public int ProcessString(String s, 
         out string outStr) {
       // ...  
If you want to add logging calls that let you know when this method begins executing, and when it stops executing, you'd have to hand-write the code like this:

   public class MyClass {
     public int ProcessString(String s, 
         out string outStr) {
       log.debug("entering ProcessString 
       // ...  
       log.debug("exiting ProcessString
But with aspect-oriented development, you can add an aspect that intercepts particular method calls for a class, as shown below for the ProcessString method discussed earlier:

   using DotNetGuru.AspectDNG.MetaAspects;
   using DotNetGuru.AspectDNG.Joinpoints;
   public class AspectsSample{
     public static object 
      Interceptor(JoinPoint jp) {
        log.debug("entering ProcessString");
        object result = jp.Proceed();
        log.debug("exiting ProcessString");
        return result;
Both the class name and method name can use wildcards—like the namespace in the example above—which allows this mechanism to work on a wide variety of classes. This example uses the AspectDNG AOP compiler for .NET, one of several open-source options.

This is far more convenient than writing all that logging code by hand in every place it's needed. But it also shows that the abstractions offered by the underlying language (C# or VB) are not suited to solving every problem.

And that's fine. We'll probably never create a language that's suitable for every situation. In fact, we should stop trying. Microsoft designed the CLR to host multiple languages with a common intermediate representation (IL). Why not leverage that more aggressively than we have in the past to create solutions by composing languages within the same solution?

Editor's Note: This article was first published in the September/October 2008 issue of CoDe Magazine, and is reprinted here by permission.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date