Language Agnosticism Leads to Real Software Engineering

Dennis J. McWherter, Jr. bio photo By Dennis J. McWherter, Jr. Comment

You may or may not have heard this term thrown around before: language agnosticism. It may sound scary at first, but all it means is€“ more or less€“ language independence. That is, your ability as a software engineer should not be limited to a very specific set of languages. Instead, you should be able to quickly learn new paradigms which fit your needs and use them effectively. In particular, I argue that software engineering is not simply about writing code: it€™s about architecting a correct and well-designed solution to a problem. As a result, code is merely an expressive tool for realizing the engineering task you just performed.

Alright, while you can€™t entirely isolate construction from the practice of software engineering (i.e. writing code), it should be noted that a lot of the real work comes in finding a solution to a problem. Moreover, different types of problems present themselves in a software engineering project. For instance, I could be presented with the task of solving the traveling salesman problem but after that comes another set of software design and architecture problems that are often times best solved by whiteboarding rather than pounding out some code. Obviously, whether it is best to write the code or plan it depends on your project, environment, deadlines, and whether or not you actually need to use the software beyond 10 minutes from now. In any case, it is arguable that€“ for software which needs to be supported/maintained€“ the developer should be spending his effort architecting a clean solution.

So you€™re asking now, €œhow in the world does this relate to language agnosticism?€ Well, the point is that the tasks I€™ve alluded to above is what software engineering consists of (in a grossly over-simplified way). I have not actually talked about writing a single line of code, yet we somehow got from a problem to a solution to a feasible/maintainable architecture. All of this and it was done relatively cheaply (erasing a whiteboard is easier/faster/less painful than decoupling 20 classes in C++). But now, this is where code and languages come in. The point is not that they are unimportant; on the contrary, they are clearly vital to a software project (otherwise you just have an idea: not a product) but they are tools used to aid you in building your solution.

As a review, let me boil down the software engineering process in general steps. I am saying very generally and outside of any methodology, so please don€™t get caught up in the details here:

  1. Define your problem
  2. Constrain your problem to evaluate potential solutions
  3. Solve your problem (or solve it €œwell-enough€)
  4. Architect a software solution in an abstract yet clear way (no references to any language)
  5. Choose a language in which your architecture naturally fits and is within constraints
  6. Build the proposed solution

As you can see, the vast majority of the process has no concern about language (in fact, only 1 out of 6 steps actually uses a language at all). Though it is likely that much or most of your time will be spent in step 6, the time spent here is proportional to how well you executed on the previous steps. My point is that you can see how little the language choice should effect the engineering process. It should be a choice determined near the end of the design and right before you actually begin to build your solution.

So what benefit do you get by thinking doing things this way? Well, obviously, you€™re simply going to have more well-thought out and cleaner code: everyone wins€“ especially you when, in 6 months from now, Bob breaks encapsulation and asks you how that one method in that one class is implemented (dammit, Bob). We can go on all day about the benefits (and trade-offs) of planning code before you write it, but the idea is that your language should support your solution rather than dictate it. An easier and more understandable design amounts to better code quality, shorter development time, and many other things. So if you let the language dictate design, it is possible that it no longer becomes understandable and you lose some of the benefits previously mentioned. On the contrary, if you have an elegant functional solution and you choose Java as your language over, say, Haskell, you now have to contort your design making it, again, less understandable.

Aside: Now you Java buffs, I know what you€™re thinking, €œHey! What about FJ?€ and I argue that Functional Java is currently a bit of a hack and the syntax is very clunky/less readable (at least in its current state)€“ not to mention you likely have to break the functional paradigm at some point to interact with other parts of code (yeah, yeah, IO ruins this in Haskell too). Rather than get into a holy war, let€™s agree to disagree on this one€“ it€™s just an example and these are the kinds of arguments you should be having in step 5!

Now that I have convinced you that selecting a language is unimportant until well after you have solved your problem, there are some real personal benefits to being language agnostic as well. In particular, you become more valuable.

  • You lose the labels. Rather than being a €œJava developer€ or a €œC++ developer,€ you can really say that you are a €œSoftware Engineer.€ In general, if you love what you do, you probably already have€“ minimally€“ hobby experience dabbling in new languages and technologies. But this aside, even if you do not know Haskell or Scala right now (and have no experience), in 2-3 weeks you should be able to pick it up with sufficient proficiency to get started on your prototype of your solution. This keeps you very versatile and quality/versatile/agile/other_buzzword_here engineers are in short supply and high demand (this is good for you).
  • You learn how to think. Even though a particular language itself should not constrain how you solve a problem, using various languages will certainly influence how you approach future problems. This is a good thing since you now have a variety of frameworks in which you can think about your problem and this will lead to a cleaner/more effective solution.
  • Caveat. This assumes you don€™t simply €œhack€ in a language and you actually learn the language. For instance, if I don€™t use any object-oriented features in my C++ code and pass everything around as a pointer, I am not really programming in C++. I am programming in C using a C++ compiler. Learning a language is not equivalent to writing code that compiles. Languages often offer different features to perform certain tasks effectively; figure out what those things are and how to do them well in that language.
  • If you can conceive a solution, you can build it. What I mean by this is really motivation/chance of success. For instance, if I want to do something which involves numerical integration my de facto would be to use Python with some libraries or MATLAB. That is, if I go right to C++ and have to implement numerical integration myself, this will be a much less pleasant experience and the likelihood of timely completion of the project is drastically lowered (particularly if it€™s a hobby project). Now, after you have completed the project and have reevaluated project constraints (i.e. it needs to be fast), you can start trying to fit a language such as C or C++ into your design to be more performant. Since you€™re not tied to a single language in your toolbag (i.e. you€™re language agnostic) you can actually start taking time-critical components and abstract them to other languages. Some people dislike mixed-language solutions, but I always suggest using the best tool for the job at hand. That said, I will, again, leave this holy war alone.

Language agnosticism leads to good software engineering which leads to good software. In turn, good software leads to happier developers (since they will have to maintain it) and happier developers are more incentivized to continually improve their skills and become better software engineers (but hopefully not necessarily produce more code). The cycle repeats; everyone is happy.

comments powered by Disqus