Dirty Little Schemers
A post or two ago, I advocated a potential solution to adding explicit tail-call optimization(TCO) to Python. In this forum, it seemed like a reasonably popular idea. Hell, even reddit seemed to think it was somewhat useful, barring some grumpy old men who, to their credit, learned me a thing or two about TCO and continuations. I proposed this to the Python ideas forum and it died. I didn’t see why it could be so popular outside of Python, yet so dull inside. Who was reading my blog, Schemers?
Really, the entire debate was a culture clash between Schemers and Pythonistas which I walked into blindly.
After reading the BDFL’s posts, and the counterposts, it seemed that it was a forgone solution that TCO was ‘useful’, just that it had problems being ‘pythonic’. That is, easy to learn and consistent with the rest of the Python mental model (Ha! Take that all of you who want a definition of Pythonic! (What’s that, you say, I’ve just moved the goal posts? What’s the Python mental model? Why, anything that’s Pythonic of course!)). In a stroke of geniusluck, and idea occurred to me that many of Guido’s criticisms could be side stepped if we just made TCO not so much of an ‘optimization’ as an explicit part of the language. I proposed an overloaded use of the ‘continue’ keyword, which, after having many debates on the color of the bike shed, would probably be better stated as ‘return from’ (to mimic yield from). By making the syntax explicit, and checked, many of the perceived drawbacks would disappear. The community offered solutions to the traceback problem and other details.
After submitting this idea to the Python ideas forum, I was confronted with a new argument – that TCO is simply not a useful thing to have. “There is absolutely no use case for it in Python.” I mentioned the litany, that I had learned from others, of message passing, true unbounded recursion, state machines, even navigating websites.
First though, an admission. In the practicality versus academic political leaning of languages, I lean academic. Whenever I see a new idea in programming, I want to try it and understand it even if I don’t have any use for it. I have a love and passion for the stuff. Thus, I came at the TCO debate assuming that if it could be put in the language cleanly, and there was at least SOME use for it, then the proposal should be taken seriously. I mean, I still haven’t found a common use for coroutine generators, but that doesn’t mean there isn’t one.
In my opinion, there are three ways to solve problems in software. There is breaking a problem down into smaller pieces (componentization), there is identifying similar patterns in the pieces and building them back up into a single construct (abstraction). There is also a third way, one which is less practiced and closer to the ‘refactoring’ ideal, and is derived from how mathematicians solve problems. You transform the problem you have into an equivalent one in which you already know the solution. I felt like TCO was an example, at least in Python, of the final sort of approach. The transform/refactor approach to problem solving requires you have a large ‘bag of tricks’ to work, since it is limited by the methods of transformation you know and the solutions you already have. TCO was one of these solutions looking for a problem, I thought, and in time we’d forget how we got along without it all along.
I now want to talk about culture. I gave a pretty bad defense of TCO because, to be quite honest, I don’t know much about it. It’s a new idea to me, I thought I could add something to the community as an outsider to the debate via the simple explicit keyword solution. I didn’t realize at the time that it wasn’t a debate over whether TCO should be in Python, rather it was, as frequently breaks out in our community, a religious war between programmers. When I approached the Python community with my idea, some were skeptical, some were interested, but some were downright hostile. To them, I was yet another dirty little Schemer in their midst trying to ruin their ‘perfect’ programming language. I was to be told I didn’t understand the Python way of doing things, that in Python, you didn’t need the solutions TCO provided. And after the BDFL advocated the use of the ‘elegant’ trampoline solution in his blog, that became dogma. The trampoline was now to be the standard ‘Pythonic’ solution to the problems solved by TCO.
There was only one problem – I don’t know Scheme. Not a bit of it. I’m only loosely familiar with Lisp-like languages in the first place. I understood the basics of TCO, and understood the arguments of those who argued for it, but they were not themselves Pythonistas, but Schemers. I listened at the table of the Schemers, and brought back what I had learn to my home, Python, and was treated like a Leper. There is a large underlying hostility here that I suppose I was too naive to believe existed.
Fast-forward (or rewind) to the recent Ruby on Rails uproar. Two separate incidents that cause a bit of a question of just how ‘mature’ the Rails community is. Take everything I say with a grain of salt (read the disclaimer on the right!) as I’m very likely talking about something I’m completely ignorant of.
But if we didn’t do that, very few people would say anything.
Anyway, first there was the porn thing, then Robert C. Martin using terminology like “masculine” to describe C++ languages (“a man’s language”) and “feminine” or, worse, “insipid” to describe languages like Java. Ironically, and hilariously to his counterpoint, he was claiming to bring professionalism to software. Here’s a hint, Uncle Bob, if you want developers to be a profession, perhaps we should stop insulting entire genders like a bunch of cigar smoking misogynists from the 40’s. But that’s beside the point. (I need another snifter of brandy, damnit! And a sammich!)
After critiques of these sorts of talks took place, the Ruby community for the most part reacted like a ten year old child, claiming that it was really the people who were offended’s fault for complaining in the first place. Good way to take constructive criticism. This was all a microcosm and a side show for what really bugged me, and what has bugged me about many of the isolated programmer cultures that develop. The rails community continued to more or less believe they had invented programming. This was the underlying theme of the entire debate. When outside criticism erupted, of anything, the knee jerk reaction was to distrust outsiders, circle the wagons, and shoot first. After all, they don’t really know programming like we do. There was no openness to criticism, which is indicative that there is little sharing of information at all. When a new idea hits Ruby on Rails, it is assumed to have been invented there by those in the community (Read: Test Driven Development). For the most part, they are the youngest members of our overarching programmer community, and should be expected to lash out like this. The problem is, it isn’t just them and never was. As I showed above, even more established communities like the Schemers and the Pythonistas can jealously guard their ideas and distrust anything new.
In the case of the Schemers and the Pythonistas, it was the old saw that Scheme is an ‘academic’ language and Python is a ‘pragmatic’ language. Which would be untrue, if it even meant anything. What the advocates of the language are actually saying is that ‘only academics’ use Scheme, but real programmers (pragmatic types, we) use Python. Real programmers don’t have time to debate theory and angels on the heads of pins. We’ve got deadlines and customers. What could a “schemer” possibly teach us? I believe this debate originally started, and is perpetuated primarily by the amateur programmer versus computer science major, basically the two ways to get into our field.
There is no ‘real’ split here, though. For example, take Haskell, one of the most ‘academic’ languages and C++, never a more ‘pragmatic’ language (although, pragmatic in another sense, i.e., runtime efficiency). Haskell has an idea called Type Classes that, oddly enough, do the exact same thing C++ ‘concepts’ do. I doubt either of these two communities openly talk about how similar such ‘academic’ and ‘pragmatic’ languages are, because both secretly want to take credit for a structural typing idea that is sure to have been around since the 60’s (citation needed). The point is, I can’t imagine a larger divide between communities, and yet there really is no large divide there. The devil, quite literally as a force of hate pulling us apart, is in the details.
Let me finish by clearing up a few things, to anyone who will listen. Just because you haven’t read SICP, you aren’t an idiot. But just because you have read SICP, you aren’t necessarily a genius. There are a whole bunch of good ideas and concepts in that book, like many of the books in our shared ‘cannon’ (I’m working through TAOCP, I swear!). While I disagree with Uncle Bob that we might all one day be ‘professionals’ (or that we should be), we can certainly all be friends. We are united by the fact that we all love and have a passion for this stuff, we should not let that passion for our particular solution, implementation or language divide us. We have too much to learn from each other. Python isn’t a child’s language (or, perhaps it is, but in a sense that even a child can learn it). Haskell isn’t too dense (because, ironically, it has been taught pretty easily to children too!). Scheme isn’t just academic, C++ isn’t THAT ugly. And rubyists aren’t that immature. Ok, well, some of them are, but we love them anyway :) When it comes to programming, when it comes to what we do, what we’ve chosen to create, I’d rather have a friend by my side than a ‘professional’ any day, even if that friend is a dirty little schemer.
3 Comments »