Falling out of love with a language 24
So, Giles Bowkett asked me on facebook “Why Perl?”. This is the long answer.
I’m a Perl hacker. I have been for around 16 years now. Around 5 years ago, prompted by the Pragmatic Programmer and Adam Turoff, I started looking at Ruby, and Ruby on Rails and sort of fell into maintaining Typo.
Why? I was getting hacked off with Perl.
I was coming to the end of my tenure/tether as Perl 6 Summarizer: watching a language that I still want to use before I die taking forever to get done gets wearing after a while, especially when you’re spending 8 hours a week summarizing the activities of a development community that, in parts, was verging on the toxic (it’s way better now).
I was also getting annoyed by small niggles in the way Perl 5 works. This was in the days before Moose. Stevan Little was just starting work on what became Class::MOP (as a prototype of Perl 6’s metaobject protocol) and way before the days of Devel::Declare.
Ruby seemed to be, as Matz has described it, “Perl, done right”. All the things that were pissing me off about Perl were so much easier in Ruby. I’ve joked, in a Ha Ha, only serious kind of way, that I left Perl for Ruby because I got fed up of unrolling @_, but there’s more to it than that. “Objects everywhere” fits my head. The language is dynamic. Ruby code had less boilerplate in it. Oh, and Ruby on Rails was looking very cool, even if David Heinemeier Hansson didn’t seem to have a clue about RESTful/Resourceful principles (he has rather more of a clue now). The community looked vibrant. What’s not to like?
I was a very happy Ruby programmer. It’s a great language. If you haven’t taken it out for a spin round the block, you should give it a try.
A Perl 5 rennaissance
While I was away on my failed attempt to become a maths teacher and then my Ruby sojourn, Perl 5 was waking up. If Perl 6 were declared a failure tomorrow by the people who are actually working on it (as opposed to the people who aren’t working on it, but bitch about it anyway – see some of chromatic’s more intemperate posts about those people), then it will still have had value for the way it’s inspired members of the Perl 5 community to nick the good bits and make them happen in Perl 5.
Stevan finished Class::MOP and it got used as the basis for Moose, which is essentially a layer of sensible defaults which sits on top of the insanely configurable and slightly more agnostic Class::MOP, which in turn sits on Perl’s weird reduced instruction set object orientation. Moose even got fast enough that it’s usable in polite company (it was always faster than Ruby), so people did. It grew an ecosystem.
Another, more recent development, is Devel::Declare. Devel::Declare is, in accordance with the long history of Perl, completely batshit insane. What it does is lets you trip the perl parser up and, while it’s standing there looking at the pretty birds flying around its head, you can run ahead and rewrite the code that it’s about to parse. Well, I say run, but what I mean is hobble ahead wearing narrow blinkers and mittens. You can accomplish amazing things in such circumstances, but it’s not fun. Devel::Declare enabled my current favourite module on CPAN: MooseX::Declare, which I’ve talked about here:
An introduction to MooseX::Declare from Piers Cawley on Vimeo.
MooseX::Declare lets me kill boilerplate. Instead of writing:
package Something;
use Moose;
has an_attribute => (is => 'rw');
sub a_method {
my($self, $with, $parameters)
= @_;
...
}I can write:
use MooseX::Declare;
class Something {
has an_attribute => (is => 'rw');
method a_method($with, $parameters) {
...
}
}which makes me happy. This is being done by a module which is written in Perl. It relies on a couple of modules that are implemented in C, but the bulk of the work is done in Perl itself.
So, that’s addressed one of the annoyances that led me to Ruby. What about ‘objects everwhere’. I got used writing things like:
5.times { |each| ... }Surely I’m not going to able to write:
5->times(sub {...})in perl?
Well…
use Moose::Autobox;
sub Moose::Autobox::SCALAR::times {
my($count, $block) = @_;
1->to($count)->each_key($block);
}
5->times(sub {$_->say});Bingo! I’d like to be able to write 5->times { $_->say } but can’t quite manage it. Give PerlX::MethodCallWithBlock a little more time though…
So, while I was away, most of the issues I had with Perl, issues that had driven me into the arms of Ruby, had been addressed.
It’s not about the bike
The new Perl tech is great, but all it does is removes barriers. I wasn’t attached to the Perl language by some huge bungee cord which was crushing me against these barriers while I sojourned in Ruby land, all the while pining for Perl. I was loving Ruby. It’s a great language.
What I am attached to is the group of friends I’ve made in the Perl community over the years. Many of whom I’ve never actually met face to face.
I felt like such a curmudgeonly old fart in the Ruby community (more specifically, the Rails community). Everything’s shiny and new and awesome. And, I suppose when you’re coming to the language from something like PHP, it is shiny and new and awesome. But it gets wearing after a while. And the arrogance? My dear! The arrogance! Admittedly, some people have a lot to be arrogant about – I still cheer DHH’s “Fuck you!” slide, but others… not so much. The kind of “Look! Ruby is uniquely suited to writing DSLs!” bullshit1 that sends chromatic off in fits of apoplexy annoyed me too, especially when I was looking at the kind of examples they were presenting as exemplary and remembering Perl from 5 years before that did the same thing but with cleaner language-like interfaces.
Coming back to Perl may well be a straightforward retreat to competence. I may be rationalizing like mad. But right now, it feels like I left Ruby because the ruby community, in the West at least, isn’t a fun place for me to be. The sexism is just the icing on that particular cake.
1 Here’s my response to Rspec:
testclass exercises Something {
test that we can create an object {
isa_ok $test->subject->new, 'Something';
}
}Note the lack of perlish furniture in the test that we can create an object part. No need to quote the strings, no meaningless dos scattered about the place, no :symbols appearing at random. Okay, so I have to quote 'Something' in the implementation block, but the implementation block is unadulterated Perl. I don’t claim that only Perl can do this. I do claim that, right now at least, Ruby can’t.
Thinking about the virtues 3
I got a bit of stick on IRC last night for some of the choices I’d made when I was writing Test::Class::Sugar, in particular because one of the prerequisites is chromatic’s handy and opinionated Modern::Perl module. The ‘controversial’ aspect of Modern::Perl is that, when you use it, your code won’t run on any Perl before Perl 5, version 10.
The thing is, I don’t care about older perls any more. Version 10 features like ~~ and // are too convenient to fart about writing circumlocutions just to run on a version of Perl that I have no intention of ever using again.
Actually, that’s not quite true, those version 10 features are too convenient for me to fart about working around their absence. If you think that a module I write is useful enough that you want it to work on version 8, then of course I’ll accept your patch. But don’t be surprised if, when I start adding new features, I break the backward compatibility.
Also, on the happy day that version 10.1 escapes the pumpking patch, I’ll be setting that as my minimum perl version even if chromatic doesn’t bump the version number in Modern::Perl.
It’s all about the virtues
Your context is different from mine. I’m writing in Perl again for my own amusement more than anything. There are developments in modern Perl – tools like Moose and Devel::Declare – that I think are exciting and important. The Announcements project I started was as much about playing with the new tools as it was about trying to write something of wider utility. Test::Class::Sugar arose as a direct result of attempting to write Announcements and the desire to write test classes without hoopage. My principle drive then, is impatience to get Test::Class::Sugar to the point where I can get back to writing Announcements.
But then laziness and hubris kick in. So the code needs some polish. The parser and the code generator need to be disentangled, I need to get Adrian Howard to apply the little patch I had to make to Test::Class. Laziness demands I document it.
Impatience tells me to lean on the features of modern perl – that way I can get back to being a user of the new library as quickly as possible. Laziness tells me that I’m not going to need backwards compatibilty. Hubris tells me my work is good enough that someone who does will like it enough to send me a patch.
Everybody wins.
Magic vs Mundane: Keeping them apart
In which your correspondent does magical battle with the guts of Perl and emerges bloodied, but unbowed with a useful principle to code by.
Skip to the conclusion if you’re uncomfortable with the guts of the Perl runtime
Test::Class had me tearing my hair out earlier. There I was, happily transforming
test something {
ok 1;
};into something very like1:
*test_something =
Sub::Name::subname(
'test_something'
=> sub : Test { ok 1 }
);through the magic of Devel::Declare, but Test::Class didn’t seem to be playing fair. Instead of letting my tests run happily, it was complaining that it:
cannot test anonymous subs – you probably loaded a Test::Class too late (after the CHECK block was run). See ‘A NOTE ON LOADING TEST CLASSES’ in perldoc Test::Class for more details
The thing is, I wasn’t loading Test::Class too late. The problem is that, at the point I applied the Test attribute to my sub, the sub didn’t have a name and, because of the constraints you’re operating under when you’re using Devel::Declare to do code transformation, there was no obvious way to give it a name in time.
Incompatible magics
The trouble is, Test::Class does what it does through the magic of compile time code attributes, and, further, it relies on the fact that if a perl subroutine that gets inserted into the symbol table like this:
sub has_a_name {...}Then, when you get hold of a reference to that code by other means (say, in the subroutine that handles the setting of an attribute, that code ref knows its own name. However, if a subroutine that ends up in the symbol table like this:
*anonymous_ref = sub {...};Doesn’t know its name, unless you take advantage of the Sub::Name module.
So, in my generated code, I was giving my coderef a name, but it was happening to late. At the point that Test::Class::Test method was seeing the coderef, the coderef was anonymous.
My magic and Test::Class’s magic were incompatible.
The thing is, both sorts of magic are really just sugar for some pretty mundane donkey work. Test::Class does what it does through attributes because no flesh and blood programmer in their right mind would want to write something like this every time they wanted to write a test method:
sub test_something {
...
}
__PACKAGE__->mark_as_special_method('test_something', 'test', '3');In fact, mark_as_special_method doesn’t even exist as its own subroutine. The code that marks a method as special is just part of the body of the Test attribute handler.
Conclusion
Which brings me neatly to my conclusion.
When you’re designing a module that does anything magical, consider starting with a mundane core API that handles the business side of things. Then layer your magic on top of that API. Then document the API and the magic. Obviously the magic bits go up front in the docs, and the API goes in its own section (or even podfile) down at the bottom, where only eejits like me, who want their magic to work slightly different to yours, will bother reading it.
Obviously, I’m motivated by an issue I’m having with a particular module from CPAN, but the principle of separating the magic and the mundane is applicable everywhere. It’s called Separation of Concerns, or The Single Responsiblity Pattern. I call it a Just Story.
You’ll find the pattern in well designed websites that are using unobtrusive javascript to wave an AJAX wand over the site. You’ll see it woven through books like The Structure and Interpretation of Computer Programmers – where it’s called an Abstraction Barrier.
Patches sent
It turns out to be very easy to add mark_as_special_method (though I actually wrote it as ‘add_testinfo’ in the patch) to Test::Class. It’s about as straightforward an Extract Method refactoring as I’ve ever done – even without automated tools, I managed not to fuck it up. There’s a patch in Adrian Howard’s inbox, and I’m hopeful that it’ll be applied soon.
1 Not exactly – that’s the result of calling the shadowed test subroutine which was the result of the code transformation.
Check out the osfameron fork of Devel::Declare for the beginnings of some decent documentation which explains what’s going on.
Warnings are the new test failures 3
Have you ever tried to run Rails, Rspec, Rake or, for that matter almost any Ruby library or application that you’ve ever heard of with the -w flag? How about running Rails with taint checking on?
They aren’t exactly pleasant experiences.
Meanwhile, over in Perl land, it’s a very rare module indeed that isn’t at least clean under -w and, where appropriate, taint friendly. It would be a very irresponsible Perl Monger indeed who wrote a web framework that didn’t assume it was going to be running under the -T flag. Warnings and taint checking are annoyances, and sometimes they’re flat out wrong, but more of the time they’re useful. Which is why, in Perl, you’ll sometimes see blocks of code like:
{
no warnings;
# Code that does stuff which would trigger a warning
}If the author is being particularly careful, she will specify which warnings to suppress – after all, there’s no need to turn off all the warnings if all you’re intending to do is redefine a method. So the prudent Perl programmer would write:
{
no warnings 'redefine';
# Code that redefines an existing method
}However, there are often ways of achieving your aim even with all the warnings on.
If modules that don’t have use warnings are rare on CPAN, modules that don’t have use strict will get the unwary programmer laughed at in the street. There are modules that simply won’t work under use strict, but they tend to have no strict, either wrapped around the narrowest scope that won’t work under strict, or proudly displayed up front. The presence of a no strict implies to the interested reader that the programmer knows (or thinks he knows) what he’s doing. Writing code that does even the most implausible metaprogramming things without raising errors from strict or spamming STDERR with warnings is a matter of professional pride. Writing straightforward code that stays silent is the absolute baseline for Perl programming professionalism in my book.
Meanwhile, here in Rubyworld, there’s no equivalent of strict and it’s actively hard to start coding with warnings turned on because important frameworks like rspec and rails aren’t -w clean. In Perl, this isn’t a problem, use warnings turns warnings on lexically. Your code might well call all sorts of noisy code elsewhere but, unless you’re running with -w as well, you’ll only see the warnings for your code. If you set $VERBOSE, you’ll get all the warnings. Warnings in the log file should be like red Fs in your test output – a sign that all is not as good as it could be in your code. Sure you could just ignore the ones you know are harmless, then you’re in danger of losing the real problems in the noise.
As a gesture of goodwill, here’s alias_method_chain written so it should raise no warnings except when the ‘without’ method already exists.
def alias_method_chain(target, feature)
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
yield(aliased_target, punctuation) if block_given?
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation", "#{aliased_target}_without_#{feature}#{punctuation}"
alias_method without_method, target
remove_method target # Warning begone!
alias_method target, with_method
case
when public_method_defined?(without_method)
public target
when protected_method_defined?(without_method)
protected target
when private_method_defined?(without_method)
private_target
end
endI think I'm in love with an Axe
We’ve just spent the weekend on one of Robin Wood’s spoon carving workshops, which was my 41st birthday present from Gill. It was great fun, if a little tiring. There is something primally satisfying about turning a piece of wood into woodchips. Getting a spoon or spatula at the end of the process is a huge bonus. We came away with a bag full of more or less decent treen, a couple of woodcarving knives and a burning desire to own one of Robin’s small drinking vessels.
Oh. And I fell in love with an Axe. The Gränsfors Bruks Swedish Carving Axe to be precise. This is the tool you use for turning a log into a spoon blank, and for much of the rough shaping of that blank. During the course of the weekend, I tried both the Gränsfors axe and an English ‘Kent pattern’ axe of the sort that can be picked up at car boot sales for pennies and sharpened and rehandled easily (quite what you use to rough out the new handle is left as an exercise to the interested reader). The English axe was very nice, but the Swedish one was just lovely. In particular, there’s a move which involves gripping the handle right by the head and flicking your wrist. This takes the top half of the blade through the wood in a precise sweeping motion that slices off wood in a way that’s almost erotically satisfying.
Yup. I don’t get out much. Why do you ask?
My choice lies before me: an English blade for maybe a fiver from a car boot sale or a sultry Swedish beauty for seventy quid from gransfors.co.uk? It’s not even a choice. The Swedish beauty had me at ‘car boot sale’ – I’m not sure which circle of hell car boot sales belong in, but I’m certain I don’t want want to go there. Besides, I’m a photographer and a computer programmer. Most of the bits and pieces cost hundreds or thousands of pounds.
Now, where did I put my credit card?
And if there were, what then? 20
The Alpha Course people have been running a bunch of poster ads built around the slogan “If God did exist, what would you ask?”. The posters are filled with anodyne questions like “What’s the point?” or “Is this it?”.
They also tend to have large amounts of white space on them – I’m sure there are enterprising graffiti artists out there who look upon that as a fine opportunity.
So, here’s a few questions I’d ask god, if it existed:
What about that malaria parasite?
Because nothing says boundless Love like cooking up a disease that kills millions upon millions of people in the service of a parasitic lifecycle. Malaria’s been around so long that at some point during the long war between the parasite and humans, evolution cooked up a kink in the genome to try and keep the disease at bay. It works too. Sort of. Admittedly, if you get two copies of the gene, you get sickle cell anaemia, but malaria’s that awful that that bet seems worth making.
What’s the opportunity cost of religion?
Think about it. What proportion of humanity’s store of creativity, effort and money has been pissed up the wall in the service of religion over the years? Okay, so, the Sistine Chapel is a bit special, Bach’s Cantatas prod some serious buttock and it’s hugely good fun to sing from The Sacred Harp. But genius doesn’t go away if religion isn’t there. What would those artists have done, unshackled? And what might our scientists have done? The church has suppressed any number of scientific advances over the centuries and is still trying it on today. Look at the ongoing furore about stem cell research, cloning and all that other potentially good stuff.
Go to almost any place of worship and try to count the cost of it. It won’t be long ‘til you’re up to $lots. The money to pay for that comes off the backs of working people. For centuries, the tradition of tithing – giving 10% of your income to the church – wasn’t just a tradition, it was The Law. 10% of everything you earned, grew, made. For what? What might free people have achieved given that money and time to use as they saw fit?
Hitler, Pol Pot, Stalin, The Spanish Inquisition, Conquistadors… why?
Religious apologists would have you believe that the first three of those are proof of the awfulness of atheism. But they built their power and performed their atrocities by harnessing up the same religious impulses that gave us the Spanish Inquisition and the conquistadors. The religious impulse says “We are the Right People, they are savages”. Once you’ve got people convinced that they’re on the right side of the fence, it’s amazing what they’ll do to others in the name of a loving god.
If god exists, why were these people even born? You can tell me that god works in mysterious ways its wonders to perform, but I don’t really see how you can call genocide a ‘wonder’. If god’s going to claim to be the source of morality, then surely it should be held to those same standards. If god exists, then it has the power to stop atrocities. The fact that they happen leads me to infer that either there is no god, or any existing god is malevolent.
What’s wrong with women?
Look at almost any holy book you care to name, and women usually end up holding the smelly end of the stick. It may well be that sexism is endemic in human nature (I don’t think it is mind), but when you have religious authority for treating women as chattels, keeping them barefoot and pregnant and generally treating them as second class citizens… Well, it doesn’t help does it? Most of the holy books seems to have a pretty low opinion of men’s ability to keep it in their pants too. Otherwise why all the idiotic strictures about women keeping themselves covered up lest they inflame the uncontrollable desires of men. Come on! Blaming the victim’s so medieval.
Why should I worship you?
So, god made me. Big fucking deal. In the words of every teenager ever: I didn’t ask to be born. I owe god nothing. If I did want to worship my creator then I’d be far more inclined to worship my mother; I know she exists, and she went to a great deal more trouble to bring me into the world than anyone or any thing else that I can think of.
How do we get rid of you?
Seriously. God’s nothing but trouble. The suffering in the world’s dreadful when you stop to think about it. If we can lay the blame at the door of the cold, implacable machine that is Darwinian evolution, then there’s comfort in knowing that it’s nothing personal. It’s just the way the chips have fallen. There’s comfort too in knowing that there’s nothing to stop us as individuals and as a wider community doing everything in our power to make the world a better place for us, our children and the 8 billion other folks we’re sharing the place with. Because this is it. This is our only go on the merry go round. There’s no heaven, no hell, there’s just the world we make for ourselves and pass on to the next lot. It’s in our own best interests to look after it.
But if you have to lay the blame for the bad stuff at the door of some god, some conscious being who deliberately did this… It’s intolerable, frankly. That some being could choose to unleash malaria, TB, bubonic plague, syphilis, AIDS and the common cold on the world that it created is just… When we catch kids pulling the wings off flies, we tell ‘em off. When we catch god doing worse things, we (or a depressingly large fraction of us) worship the bloody thing. And because we buy the promise of a better world to come, we do a crappy job of making the world we’re in a better place. Great.
Does god exist?
I’m an atheist. I doubt anyone could prove, absolutely, the nonexistence of god. However, I fervently hope that there is no god because the alternative is so awful.
Arguments you wouldn't make in Alabama 11
I spent the weekend at the UK Sacred Harp Convention, singing blood curdling hymns to the glory of god, very loudly with a hundred or so others. Great fun so it was. There’s something joyous about hollering out a hymn that opens with the line “And am I born to die?” and ends with the stanza
Waked by the trumpet’s sound
I from my grave shall rise
And see the Judge in glory crowned
And see the flaming skies
Especially if you’re stood in the middle of a hollow square with the altos behind you hitting a high note that lifts every hair on the back of you neck.
Anyhow, at one point during the Saturday evening social I found myself arguing that, although we singers today may feel grateful to those congregations of singers down the years who have sung these songs and handed the practice down to succeeding generations, there’s no requirement to be grateful, or even to go hunting for ‘authenticity’. Every generation that’s sung these songs and many others haven’t sung them to preserve them or to pass them on. They’ve sung them because the act of singing them has helped them to get through their lives. The songs we have, we know because successive generations have found them to be worth singing or recording. And we sing them for similar reasons. Future generations can go hang, I sing this stuff because it makes me feel good, not because I have some kind of duty.
“It’s a Darwinian argument,” I said, “Though obviously, I wouldn’t put it like that in Alabama…”
Fat is an economic issue 11
Terry Pratchett once observed that a character of his was anorexic because every time they looked in a mirror, they saw a fat person. By that measure, I’m anorexic, though I tend to avoid mirrors. By more objective measures, I’m morbidly obese – 6’ tall, 346 pounds; the Body Mass Index calculation is never going to give a good number.
To listen to some sections of the press, I might as well be public enemy number one. A drain on the public purse, a morally bankrupt insult to the eye of the right thinking, Daily Mail reading healthy public. Apparently, I have the self control of an incontinent puppy and spend my time sat on my arse in front of the TV or looking at child porn on the internet, constantly stuffing my face with lard and chocolate.
Mmm… lard and chocolate…
Now, everyone’s entitled to their opinions of the morality of others. Catch me on another day, and I can rant for ages about the ugliness of the way diet and beauty industries stoke insecurities to sell product. Today I want to talk about the cost issue.
Fat people aren’t cheap to keep – we tend to die younger, and in the process of our dying we cost a lot of money. But dying can be an expensive business and however we go, we all do sooner or later. Fat people’s healthcare costs may well be higher than those of healthy people of the same age, but those healthy people could end up waiting ‘til they are 80 before dying of something horribly expensive like cancer, or Alzheimer’s.
When you add up the net lifetime healthcare costs of the average healthy person, and those of the average obese person, the healthy person costs more.
This is analogous to the “Long Tail” idea – the idea that the long tail of low sales of ‘specialist’ books/records/services adds up to being of greater value than the total sales of the top 100 or whatever. Obvious when you think about it, but running counter to traditional thinking in this area.
We’re really good at spotting the big things, but rather less good at spotting the slow accretion of small things. Each drop of water that falls from a stalactite to a stalagmite doesn’t appear to contribute anything. Nevertheless, the stalactite and stalagmite got there somehow.
I find this knowledge rather heartening. Okay, so as a fat git with diabetes, I’m likely to die young, but that’s my business. The pernicious idea that the broader population of tax payers is somehow suffering because of me and that because of that I should be denied access to health care isn’t just morally repugnant, it’s economically illiterate.
References
Lifetime Medical Costs of Obesity: Prevention No Cure for Increasing Health Expenditure from PLoS medicine. The paper describes a mathematical model rather than something which does the arithmetic on a real population, so it’s only as good as the assumptions, but it does seem compelling that the driver for high total healthcare costs over a lifetime is the length of that life. But, as I fat git, I might be expected to say that. Ho hum.
Code is data, and it always has been 3
I’m just back from the first Scotland on Rails conference, and a jolly fine conference it was too. Much kudos is due to Alan, Graeme, Abdel and Paul. It was hard to believe that this was the first conference these guys have run and I think all my fellow delegates hope it won’t be the last. As I said in the Pub on Saturday night, I’d had a talk proposal knocked back and, in that situation, it’s terribly easy to find yourself sitting in a session thinking “Bloody hell, my talk would have been better than this!”, but not at this conference.
A phrase that cropped up a couple of times was the old saw that “Data == Code” – it’s very hard to avoid the idea once you start talking about code generation or Domain Specific Pidgins, parsing… I first came across the idea in The Structure And Interpretation of Computer Programs where it’s elegantly phrased as “Data is just dumb code, and code is just smart data”. Traditionally, the idea seems to be attributed to John McCarthy, the inventor of Lisp. But it’s older than that. Way older than that. The idea is actually older than Computer Science. It lies at the core of Turing’s original paper On Computable Numbers, with an Application to the Entscheidungsproblem in which invents computer science on the way to proving that it’s impossible to decide algorithmically whether a given statement of arithmetic is true or false.
In the course of the paper, Turing posits what has become known as the Halting Problem:
Given a description of a program and a finite input, decide whether the program finishes running or will run forever, given that input.
Turing’s proof runs something like this:
Suppose we have a subroutine halts?(code,data) which solves the halting problem. Let’s use that to write something like:
def counter_example(code)
if halts? code, code
for (;;)
end
else
return
end
end
counter_example(File.read(STDIN))and ask the question “What happens when we run counter_example.rb < counter_example.rb”? If halts? reckons that counter_example would halt, given itself as input, then counter example will enter an infinite loop, but if halts? reckon that it would enter an infinite loop, then it would halt. Which is a contradiction. Which means that there can be no subroutine halts?, which means that maths is hard enough to be interesting and occasionally undecidable.
Look at how the proof works – it’s built around the idea that code can be treated as data. In fact, you could say that the Turing Machine looks like it does because Turing was working backwards from this core idea to describe a sufficiently powerful machine that could obviously treat it’s own description as data. Certainly when you compare the clarity of his proof that the halting problem is undecidable (given the idea of the universal Turing machine) with the contortions required to make mathematics swallow its own tail in similar fashion so that Gödel could prove his Incompleteness Theorem.
So, if you want to know who the idea that code is data is due to, the answer (as is so often the case in our field) is Turing.
Postscript
Incidentally, Turing is also responsible for the first ever bug – his original implementation of a Universal Turing Machine has a couple, one of which is probably a dumb typo (which even I could spot when I read the paper). Another is more subtle, but still fixable. Somewhat delightfully, a young grad student, (Donald W Davies, who invented packet switching) spotted these bugs and told Turing:
I … found a number of quite bad programming errors, in effect, in the specification of the machine that he had written down, and I had worked out how to overcome these. I went along to tell him and I was rather cock-a-hoop … I thought he would say ‘Oh fine, I’ll send along an addendum. But in fact he was very annoyed, and pointed out furiously that really it didn’t matter, the thing was right in principle, and altogether I found him extremely touchy on this subject.
Nearly fifty years later Davies wrote and published a debugged version of the code, which you can find in The Essential Turing. One lesson to draw from the above is that getting annoyed at people pointing out trivial bugs in example code is also at least as old as computer science. Rather splendidly, there’s also a story of the chap who wrote the first ever assembler getting a serious telling off from Turing because the computer’s time was too valuable to waste it on converting symbols into machine code when humans were perfectly capable of doing it themselves. Who knows, maybe Turing’s contention was actually true back in the days of the Manchester Baby…
Tragedy
There’s always a moment, in a perfect tragedy, where you dare to hope that maybe the heroes are going to break the surface tension of the plot and escape. That perfect moment in Romeo and Juliet where, no matter how often you’ve seen it, you hope that this time, Juliet’s message will reach Romeo. Or, when watching Cruel Intentions, you find yourself hoping that the writers have managed to wangle a happy ending.
It never happens of course, and we’d be disappointed if it did. We are taken to the critical point, when everything seems possible, when the characters are pushed to their utmost… and fail. Give me the life and death struggles of two teenagers for whom love is everything and life isn’t worth living without it over the pat solutions of the Dream, or give me “Fortinbras, knee deep in Danes” over the cross dressing, weddings and cruel taunts of Twelfth Night. (Not that I don’t enjoy the comedies).
What brought this one?
Why am I musing on tragedy instead of code?
The explanation is simple: I just watched the last ever episode of The Wire.
If you follow the show yourself, nothing more is needed. If you don’t, why not? Okay, so if you’re in the UK you’re reduced to paying the Murdoch tax, buying the DVDs or watching through Bittorrent (and only Bittorrent is up to date), but you should. All five seasons of The Wire add up to being the best thing I’ve ever seen on television. It’s impossible to describe how good it is without misrepresenting the whole. It’s the kind of campaigning documentary fiction which would make Dickens or Mrs Gaskell proud. It’s a sprawling epic with a huge cast of fascinating and flawed characters. It’s the story of how a cop destroys his career, a junky kicks his habit, a school system fails its pupils, politicians fail their constituents, a newspaper fails its readers and how a policy of prohibition fails a country.
Prohibition and its consequences are shot through the fabric of The Wire. It’s easy to see how drugs destroy addicts. Easy (for liberal old me at least) to see how the money spent in the War on Drugs could be spent more effectively. What’s not so easy, and what The Wire does so well, is to show how “the game” destroys generation after generation of the best and brightest of the urban poor too. Why bother working to get to college, or getting a regular job when selling drugs is so easy and so profitable? If you’re going to jail for selling the stuff in the first place, why scruple to put a bullet in the head of a business rival, witness, or some mope who calls you a coward? How many “mute, inglorious Miltons” end up dead and decaying in a walled up vacant, or stuck behind the barbed wire of the state pen serving out their natural lives with no hope of parole?
And what does putting them away achieve? For every small victory, we’re shown a corresponding fall. New characters slot into the rôles they have vacated and the cycle begins again. It’s a perfect tragedy – the game is still rigged and only the players change. The gods are unmoved by the struggles of poor mortals, the lawyers get richer, incompetence is rewarded and money is siphoned away from the streets into the pockets of rich white men who already have plenty.
Welcome to Baltimore. Have a nice day.
