January 19, 2008.
What is the similarity between Java and Scheme1?
Well, there are a lot of differences. Java is an imperative language that inspires angry rants about its syntax and lack of power. On the other hand, Scheme is a functional language whose lack of syntax is the subject of doe-eyed Petrachean sonnets. Scheme by virtue of being a functional language doesn't provide effective support for imperative programming styles, and Java--an imperative language--doesn't provide effective support for functional programming styles.
So why is it that Scheme is a Language For Smart People, and Java is a Language For Masses?
Reading essays on LFM versus LFSP we usually come up with a pleasant explanation of the difference:
A LFM was designed to intentionally limit the power of its users because power is too dangerous, whereas a LFSP places no unnecessary limits on its users.
However, looking at this explanation we find some holes.
First, Java was designed to be predictable and consistent rather than necessarily limiting its power out of fear of its users. Java is limited to provide a service to its community at large, and is willing to inconvenience its individual users to do so. Universal consistency is being valued above individuals having access to their prefered abstractions and constructs2. Java wants you to build abstractions by writing encapsulated libraries with public APIs. Although we rarely think of Java in these terms, it is a language obcessed with the One And One Way Only mantra popularized by Python3.
The second hole in this summation is that Scheme intentionally restricts its functionality with its laser-like focus on the functional style of programming4. We don't mind because Scheme is a functional language and we don't expect a functional language to have stellar support for the imperative style of programming. People who don't like functional style stay away from Scheme, but never decry it as a Language For Masses.
Translating this to buzzword speak: Scheme isn't arbitrarily limited, its opinionated.
The thing is that Scheme is arbitrarily limited by the opinions baked into its design.
So why are we willing to accept Scheme's opinions, but not Java's? Because we like Scheme's opinions more. Scheme has a "pure" reason for hampering imperative programming: its making a statement that functional programming is a superior way to code than imperative programming. But in reality, all Java does is make a different statement: imperative programming is a servicable approach to general purpose programming.
Getting angry at Java for its poor functional support is as ludicrious as complaining about Scheme being an awkward language for imperative programming: these are not flaws, but opinions. We do ourselves a disservice by treating opinions we don't like as something for the unenlightened masses, and opinions that coincide with the current academic fashions as enlightened.
Lets get back to saying what we mean.
Instead of describing Java as a Language for Masses, lets just say "I don't like writing Java because of its emphasis on imperative programming." or "Java's approach to building abstractions places too much value on the community compared to the individual." Instead of smiling about our favorite language being a Language for Smart People, lets just say "I really like functional programming" or "My feelings about macros probablly can't be expressed hiegenically." To do otherwise is to give sway to the spectre of elitism.
Scheme and Java are being used as specific examples of programming language archetypes. This article isn't really about Scheme or about Java, and both could be replaced with other languages with only minor modifications about specific language details. In particular Haskell might make a stronger point than Scheme, but it seems more appropriate to speak about a language I am familiar with.↩
I'd argue that Python 3000 is showing us something similar in its simplification of the language to acchieve a greater overall consistency. The shining example would be removing magical print and replacing it with a function whose syntax is consistent with the rest of the language.↩
With due acknowledgements that Java, in its never-ending quest to remain relevant, is adding more language features and becoming less OWAOWO as time moves forward.↩
If Scheme's reluctant allowance of non-functional functions makes this point feel to weak to you, please substitute Haskell, or instead consider the lack of a standard imperative for loop.↩