If you want some insight into my motivation, mood, and personality when it comes to the difference between the industry standard languages like Java and the esoteric languages that commonly get passed up in corporate environments like Lisp or Haskell, then this post has a part 1. Go check that out. However, if you're strapped for time or just want to get to the point and pass judgment, feel free to start here.

I already mentioned the classic objective measure for programming languages. Is it turing complete or is it sub-turing complete? With a turing complete language, we know how to create functions that can perform every calculation that we know how to perform. With sub-turing complete languages, we can still create functions that can perform calculations, but we can't create all of the functions that can be created in a fully turing complete language.

I want to add one more idea. Fixed functionality. Think about it this way. If a turing complete language can create a light, it can create lights that can do anything that is doable. Red lights, blinking lights, moving lights, whatever. Well, sub-turing languages can create lights as well. They can't do as much as the turing complete language can, but perhaps it can make red lights and blinking lights. The fixed functionality language can't even be called a language. It's either there or it's not there. If you use it you get a light, but you have no control over the light. It's a red light that's always on. If you don't use it it's not there.

Now, fixed functionality isn't necessarily bad. The down side is pretty obvious. If you want a green blinking swaying light, then you are out of luck. You only get red lights with fixed functionality. But on the other hand. If you happen to need a red light, and you don't want to think about it very hard. Then you get yourself a red light. You don't have to tell the language to make a light, and then make it red, and then make it stationary, and then make it constant. You just say LIGHT. And you get exactly what you wanted. So there's a sort of cognitive simplicity provided.

So now we can quality languages as turing complete, sub-turing complete, and fixed.

Before we go onto differentiating languages, let's talk about some of the features in languages. Well first of all every language is parsed. That is, you provide some sort of textual input to the computer that humans can understand, and the computer turns the text into a bunch of bytes that the CPU can understand. Also there are keywords. These are specific special words in the language that have a single meaning to the computer. And finally, let's say function dispatch. So normally, if you call a function, then you get a very specific set of calculations. Sometimes, though, you can get one of several different sets of calculations depending on the applications of some rules.

Okay, so as far as a language goes. It doesn't make a lot of sense to have a fixed language. That's more of a light switch than something that you would program with. But what about those features I just mentioned. Well, in Java the parsing is fixed, the keywords are fixed, and the function dispatch is sub turing complete (interfaces and inheritance allows a non-fixed decision as to what the actual function actually is). The C programming language has a sub-turing complete parsing process (macros), fixed keywords, and mostly fixed function dispatch (although there are function pointers). Now consider Common Lisp. Turing complete parsing (reader macros can call turing complete functions), turing complete keywords (macros can call turing complete functions), and … well I'm not sure if the common lisp object system (CLOS) actually allows arbitrary function dispatch, but it does allow quite a bit, so at the very least we can call it sub-turing complete.

So nearly every language is turing complete, but the differentiation I'm trying to raise here is where else is it turing complete. The super languages tend to have a lot more turing completeness available. Haskell has turing complete parsing (at least it has a Quasi Quoting extension that provides this), turing complete keywords (again the Template Haskell extension), and a turing complete type system. Forth has turing a turing complete parsing process. Etc etc.

The industry languages tend to have less turing complete features available. With the canonical example of Java, nearly every aspect of the language is sub-turing complete. And generally features that are turing complete are considered harmful. Most people distrust macros in C and templates in C++.

This is why people talk about being able to do *more* with Lisp. The final product is just as turing complete as everything else, but with Lisp there's so many more places where you can take advantage of turing completeness to help you do your job.

However, this isn't always a good thing. And I think this is why we won't be able to say that the Super languages are better than the industry languages for a long while. Most people aren't entirely sure what to do with turing completeness. On the one hand if you gave them a sub-turing complete language, they wouldn't be able to figure out how to transform their problem into a representation that is actually solvable by their language. And when you give them a turing complete language they immediately begin messing things up. After all, if you're able to calculate all calculations that are possible … you can write a bunch of terrible code (up to the limit of what humans can comprehend and beyond as long as you remain lucky) and there's not much objective evidence for claiming that it's bad … because it does sort of work in the end. Then once you give them a language that has a lot more turing complete aspects and features, they mess things up in more places. I think this is a natural consequence of computer programming being a relatively new discipline. Most people don't seem to understand the right way to do things. Those who do, don't understand how to teach it to others. And finally it's not clear how much of a good technique is due to it's objective goodness and how much of it is due to the way the person using it thinks.

Anyway, at the end of the day I don't think it's useful to give high praise to many of the esoteric super languages. I think a much better categorization technique is to indicate which features are turing complete, sub-turing complete, or fixed. Then continue to describe why you need what features to be what status in order to best solve the problem in your given domain.