In Beating the Averages, Paul Graham formulated the Blub paradox. In short a programmer who only knows a language called Blub looks down on all languages that don't support features that Blub has. At the same time, he1 is incapable of understanding why he would want to use some weird language that has features that Blub doesn't have. The Blub programmer is so used to thinking in Blub that he can't get his head around anything non-Blub.The question is, how do you know if you or somebody else is a Blub programmer? Of course it goes without saying that anybody who reads this blog is kind, highly intelligent, open minded, and motivated to learn.
The comedian Jeff Foxworthy had about five minutes of fame with a schtick of starting each joke with "you might be a redneck if..." Five minutes is a lot more fame than the average blog entry gets, so I thought I'd steal his formula for success.
Here, with a slight modification of the formula, I present
That Jerk on the Internet Might be a Blub Programmer If...
He dismisses other language features as "mere syntactic sugar"
Of course its syntactic sugar. Anything above raw machine code is syntactic sugar. Syntactic sugar is what helps programmers think and work at higher levels. Look at it this way: C and C++ have "goto" and "if". But they also have "while" which is really just syntactic sugar for the right combination of "goto" and "if." C, C++, C# and Java have "for", but it's just syntactic sugar for a certain kind of "while" loop. C++ has object oriented programming, but C++ type OO can be created in C using the right combination of structs and pointers.
In other language families I could go on and on about list comprehensions, pattern matching, type inference, regular expressions, function composition, currying, etc. But one in particular deserves mention: Lisp's most powerful feature is all about syntactic sugar. Lisp macro facilities (including quasiquotes, @ splices, etc) are syntactic sugar that make it easy for a programmer to create new syntactic sugar. If you understand macros then you'll think they're damned cool or damned scary (or both), but you won't dismiss them as "mere" anything. In On Lisp , Paul Graham creates an entire embedded Prolog in Common Lisp. Or take a look at Qi. It creates an incredibly powerful, statically typed, Haskell like language on top of the dynamically typed Common Lisp using a whole lot of macro black magic.2
He dismisses most examples as "toys" that don't show a feature is useful
Face it, most teaching examples are going to be a toys. Real world code is frequently complicated with error conditions, domain specific logic, and adherence to proprietary code standards. None of these things help demonstrate the feature being demonstrated, so examples tend to be small and focused on something that most people are familiar with or can learn in a few minutes. Refusing to try to grok a feature because the example given isn't immediately pertinent to you is a failure of one's imagination.
He questions why "anybody would want to do that in the real world"
The phrase "real world" is highly loaded. It depends entirely on the domains you have experience in. You might not see why C's unsafe casts and unions are useful but let me assure you that for extremely low level performance critical code they can be critical. Haskell's concept of monads might seem arbitrary and weird, but monads have been used to statically prove significant aspects of real programs. And Ruby's dynamic metaprogramming facilities really do help create an environment that is extremely productive in non-trivial systems.
He says his favorite language "can do that" and then creates a giant ball of crufty boilerplate to prove it
Most programming languages are Turing complete. All such languages can perform the same computations somehow. But if you have to create a ball of cruft every time you want to do some particular action, how often are you going to use that feature? If you had to recreate all of number theory every time you wanted to multiply two numbers wouldn't you stop tipping waiters?
Again Lisp is special here. Any feature in another language can be implemented in Lisp using a bit of macro cruft; the difference is that in Lisp the cruft only has to be created in one place. Besides that, macros can be surprisingly uncrufty - most look very much like the syntax they're trying to generate.3
He denies that another language is more powerful than his because "they are all Turing complete"
Hmmm, is he writing raw machine code? If not, he's implicitly admitting that some languages are more "powerful" for some sense of the word "powerful". Powerful is a surprisingly tricky concept to pin down, but because our Blub programmer has chosen Blub and not machine code he must have some definition beyond the computational theoretic meaning. Either that or he's splitting hairs about "powerful" vs "expressive" or some other term.
He dismisses language feature because the syntax isn't "intuitive"
If you think blocks must be denoted using curly braces then you're going to miss out on a very rich set of languages that use some other arbitrary choice. All programming languages are artificial creations and nothing about them is "intuitive" except in the narrow sense of "similar to something you already know." For example, most imperative languages use the single equal sign (=) to mean (re)assignment. It might seem "intuitive," but what's intuitive about using a symmetrical symbol for a fundamentally asymmetrical operation? Before programming languages stole it, that symbol already had a deep history and meaning in mathematics that is completely incompatible. Frankly, Scheme's "set!" and Smalltalk/Pascal's ":=" seem like more reasonable choices, and what could be more intuitive than "<-". But try getting any of them past the Blub lawyers.
This isn't to deny the utility of working on syntax when adding a feature to an existing language. The sense of "intuitive" given above definitely applies here. It's just to say that dismissing a feature in another language because it has a different syntax is pure parochialism.
Help Stamp Out Blub Programmers
This post has been unusually strident for this blog. I mostly intend to present my thoughts with more gentleness and good humor.In a sense, though, this entry is all about preventative medicine. In my future posts I intend to talk about several languages and features. In the process I expect to get many poorly thought-out comments from Blub programmers. It's my hope that this post will at least slow some of them down to think, "if I write this, will everybody think I'm that jerk on the Internet?"
It probably won't work, but that's never stopped me before.
Before I close this out, there are a few things that do not make you a Blub programmer:
You probably aren't a Blub programmer if...
You can admit ignorance
While ignorance is a key ingredient for Blubness, it's not the only ingredient. The Blub programmer is willfully ignorant, actively pushing back against anything new. But ignorance itself is just a temporary condition if its joined with an open mind.
You've tried something and just don't like it
Hey, not every feature is all the hype promises it to be. Not liking something that you have tried isn't the same as not liking something you never want to try. Just be open to the possibility that the feature might work well in some other environment, in another language, or with a better implementation.
Footnotes
1. The usual apologies about using "he" instead of "he or she." One Div Zero officially recognizes that women have full and equal rights to be jerks and Blub programmers.
2. Liskell does the opposite. It puts a Lisp like syntax, including macros, on top of Haskell.
3. One complaint that even thoughtful people have leveled against both Common Lisp and Scheme is that they seem more like Language Development Kits than languages. In part this impression is created by the fact that the standard definitions for both are getting a bit crusty with age. Sure, you can build a nice list comprehension macro but wouldn't it be nice if a standard one came in the box? The counter argument is that the language development kit allows you to move your environment into domains that are too specialized for a standard.
3 comments:
I agree with the position to be open minded and select the best tool for the task. However, you must also consider the probability that this application written in this language could be around for several years. When choosing a language for an application or parts of an application you must also consider the operational aspects. Is there a team capable of supporting this? Is this a fad or will it be around in a few years? What will it cost to train others to support this when the author is gone? It is fun to pick up new tools with cool features. If the application is just for fun use what you like. If the application will run a business pick something that is sustainable.
My post never talks about how to pick a tool (although Paul's article does). Mine only talks about being open minded to learning about other tools. You might say I subscribe to the weak Sapir-Whorf hypothesis when it comes to programming languages: the languages you know influence your ability to solve problems even in other languages.
Naturally, learning and picking aren't unrelated. You won't pick something you aren't willing to learn.
You talk about "picking the best tool for the task" but if you've already decided you won't look at languages that aren't "sustainable" then how do you know whether a tool might be so much better for the task that it would justify training time? Or, let me put it to you this way, if the right language (or whatever tool, or combination of tools) can give you or your replacement one order of magnitude improvement in productivity then for any sizeable task won't training time quickly disappear into the noise? And one order of magnitude is not at all an unreasonable possibility depending on the domain and the tool (it's actually unreasonably small).
Excellent post. I can identify many blub necks at my place of work ...
Post a Comment