Bending a language to your will
Just watched the talk by Guy Steele – Growing a language. In it, he points out that a language should be designed to grow, rather than have many features. It should have just the right amount of tools, that will help users create more tools on top of the existing ones.
The interesting thing is that this talk is from 1999. He advocates about expanding the Java Programming Language by adding Generics and operator overloading to it.
Here are we now, 2009, the Java language does have generics, which seem not thought well enough1, but doesn’t have operator overloading. It may never have it.
And here are we again, 2009, we have the Scala Programming Language. It can satisfy both requirements Guy mentions explicitly – operator overloading and generics. But Scala has pushed these concepts further.
Actually, it doesn’t have operator overloading – it has a way to do operator overloading by allowing people to define methods that look like operators.
Compare the use of Java’s BigInteger class
import java.math.BigInteger def factorial(x: BigInteger): BigInteger = if (x == BigInteger.ZERO) BigInteger.ONE else x.multiply(factorial(x.subtract(BigInteger.ONE)))
and Scala’s wrapped version – BigInt
def factorial(x: BigInt): BigInt = if (x == 0) 1 else x * factorial(x - 1)
It looks natural, clean and concise2.
Scala also has generics, but, yet again, pushed one idea further. They are called type parameters. Just like a method may receive objects as parameters, the same way it may receive types as parameters. This allows one to write methods (or classes) in a way that they work with any or some types without explicitly defining behavior for each supported type and puts the control in the hands of the developer that writes the class.
object Queue { // constructs a queue with initial elements ‘xs’ def apply[T](xs: T*) = new Queue[T](xs.toList, Nil) }
Here both the class Queue and the method apply are parametrized by type [T]2.
Growing your language is not a new idea – in 1993, Paul Graham wrote about Bottom-up programming where he proudly stands behind this idea that a language should grow with the user and be grown by the user. Lisp have had this for years decades, but for (some (strange (reason))) never hit mainstream3.
A couple of years ago all this fuzz about Ruby and Domain Specific Languages, Internal Domain Specific Languages to be precise, hit the scene. And Ruby has a lot of ideas from Lisp in it, but with better syntax.
Ultimately, the perfect language will be one with no primitives – everything can be defined as a library and the language will be able to be grown by it’s users, but not one that is ultimately flexible as it will produce very different and divergent styles with hard-to-cache errors. In my opinion Scala is the one that stand the best chance of satisfying those requirements.
__________________
1 Try using wildcards in a combination of framework and user code, where you do not own both.
2 Examples are provided for completeness and not explained as their explanation will blur the main topic of this post.
3 Lisp being mainstream or not is arguable, without defining “mainstream”, but even it’s most passionate defenders will agree that in terms of popularity in can do a lot better.
“Bending a language to your will”