tag:blogger.com,1999:blog-45221897641851393142024-02-21T12:13:24.940+00:00Senate House PassageMeredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-4522189764185139314.post-56303185100147456742015-02-01T01:05:00.001+00:002015-02-01T01:07:46.775+00:00On EssaysA friend recently suggested to me that there was no way she could do well at [humanities subject]. Despite being reliably articulate, and having a deep interest in the subject, she was convinced she could never be so virtuosic as to write a Good Essay, like a proper Student of Literature. I found this pretty horrifying, but I suppose it's not hard to see why certain parts of the humanities might cultivate this sort of harmful mystique about basic writing skills.<br />
<br />
In particular, I point the finger at literary criticism, which has spent the last few decades in a desperate struggle to prove its own worth and relevance. It's not that lit crit shouldn't exist; someone ought to be keeping an eye on our civilisation's cultural output. But as a discipline, it is embarrassingly insecure, and it's not hard to see why.<br />
<br />
<a name='more'></a>All that critics do is read books (or consume other culture) and write essays about it. And if reading is easy, of course they'll be invested in the idea that writing an essay about it is some mystical skill that justifies their place in the academic pantheon. Viewed in this light, Postmodernism is a pretty transparent effort to make the process of writing (and reading) criticism as arduous as possible - specifically, to make it something that requires expertise. If you fill your work with <a href="https://www.google.com/search?q=extimacy">words for which no satisfactory definition has been agreed in the half-century since their coinage</a>, then it becomes impossible to understand what you are saying, let alone argue against it and be taken seriously, without the sort of thorough understanding of that fifty-year history possessed only by your comrades in arms.<br />
<br />
Historians, by contrast...well, they at least study something real. The past, you see, actually happened. And, sure enough, while they flirted with postmodernism, historians gave up on the obscurity quite quickly. Unlike the literary theorists, they knew they had <i>shit to get done</i>.<br />
<br />
This isn't an abstract question. Anyone who writes essays for a living - including cultural critics and, more famously, journalists - is right this moment getting their faces rubbed in the fact that good essays just aren't that difficult to write. So much so, in fact, that the world will voluntarily do it for approximately free.<br />
<br />
This turns out to have a bunch of bad side effects, because "paying people to write essays about current events" had a bunch of positive externalities like "incentivising people to research and gather news". These incentives are rapidly collapsing, as the market for "essays about current events" becomes much more efficient. But the very fact that they are externalities proves that writing the essays wasn't the important or valuable thing. The valuable thing was having something to say - and when it comes to news, nobody has worked out to compensate people who uncover things for us to talk about.<br />
<br />
By contrast, when it comes to cultural criticism, there turns out to be a bottomless well of people with interesting things to say. The more abstract sort of feminist academic discourse, for example, has been largely supplanted by the bloggy online kind, with little of value lost. (News gathering, on the other hand, turns out to be....well, thank heavens for the BBC, imperfect as it is, because one way of ending that sentence is quite possibly "...in need of direct non-market subsidies if the whole edifice of democracy is not to come tumbling down"). The only defence, then, against the idea that the world is already doing your job for you, for free, is to claim that they're <i>not doing it properly</i>.<br />
<br />
<br />
And so, a disturbing number of people will imply that writing essays is so Hard and Important that not just anyone with something to say can do it. They are wrong - and one should back away slowly from anyone whose self-esteem requires that to be true.<br />
Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-81298149346257763312012-10-28T00:19:00.000+01:002012-10-28T02:33:07.155+00:00Easy mocking with Clojure [tech]<i>Attention conservation notice: Technical post of interest to programmers only. If you just want the link to my <a href="https://github.com/meredydd/expect-call">mocking system for Clojure</a>, click it.</i><br />
<br />
I hate testing.<br />
<br />
I know that when I have a computer checking and re-checking the behaviour of my code, it's more reliable. I know that I can make changes more confidently, knowing that if I accidentally break something, it will probably get caught. I know all this, and yet I am still put off by the sheer tedium of building all the scaffolding any non-trivial piece of code usually needs.<br />
<br />
So here's a library to make it easier, in my current favourite language.<br />
<a name='more'></a><br />
You specify a sequence of function calls that your test will perform. The library mocks them out, and verifies that they are called in the right order with the right parameters (specified with destructuring pattern matching from <code>clojure.core.match</code>, so you can specify them as loosely or as tightly as you like).<br />
<br />
You can add extra keywords to:<br />
<ul><li>Fail the test if a certain function is called (<code>:never</code>)<br />
</li>
<li>Allow any number of extra calls to a certain function, provided they match a pattern (<code>:more</code>)<br />
</li>
<li>Fall through to the original function after executing the mock (<code>:do</code>).</li>
</ul>You can put any code you like in the mock functions, so you can write additional tests or compute return values.<br />
<br />
<h2>Example</h2>I end up writing code like this a lot, when I'm dealing with hardware:<br />
<br />
<div class="highlight" style="background-color: white; border: none; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 22px; margin: 0px; padding: 0px;"><pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px;"><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="kd" style="border: 0px; font-weight: bold; margin: 0px; padding: 0px;">defn </span><span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">launch-rocket</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[]</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">when-let </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">[</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">key </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">launch-key-present?</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)]</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">start-fuel-pump</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">while</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">< </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">get-fuel-pressure</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span> <span class="mf" style="border: 0px; color: #009999; margin: 0px; padding: 0px;">1000.0</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">Thread/yield</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">))</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">ignition/enable-with-key</span> <span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">key</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">when </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">< </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">get-fuel-pressure</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span> <span class="mf" style="border: 0px; color: #009999; margin: 0px; padding: 0px;">900.0</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">abort!</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">))</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">send-email</span> <span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"mission-control@example.com"</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">str </span><span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"We have liftoff at "</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">java.util.Date.</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)))))</span>
</pre></div><br />
Now, writing test cases for code like this is easy:<br />
<br />
<div class="highlight" style="background-color: white; border: none; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 22px; margin: 0px; padding: 0px;"><pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px;"><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">deftest</span> <span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">successful-launch</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">with-expect-call</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">[(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">launch-key-present?</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[]</span> <span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"secret key"</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">start-fuel-pump</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; Check it doesn't go anywhere until it has a good</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; pressure reading</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">get-fuel-pressure</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[]</span> <span class="mf" style="border: 0px; color: #009999; margin: 0px; padding: 0px;">860.0</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">get-fuel-pressure</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[]</span> <span class="mf" style="border: 0px; color: #009999; margin: 0px; padding: 0px;">1001.0</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; After this, we don't care how many more times it</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; checks the pressure</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="ss" style="border: 0px; color: #990073; margin: 0px; padding: 0px;">:more</span> <span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">get-fuel-pressure</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[]</span> <span class="mf" style="border: 0px; color: #009999; margin: 0px; padding: 0px;">950.0</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; ...but it definitely fails the test if it aborts</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; on this input data.</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="ss" style="border: 0px; color: #990073; margin: 0px; padding: 0px;">:never</span> <span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">abort!</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; Does it use the right key?</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">ignition/enable-with-key</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[</span><span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"secret key"</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">])</span>
<span class="c1" style="border: 0px; color: #999988; font-style: italic; margin: 0px; padding: 0px;">; Use a binding to capture and examine the email body</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">send-email</span> <span class="p" style="border: 0px; margin: 0px; padding: 0px;">[</span><span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"mission-control@example.com"</span> <span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">body</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">]</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nb" style="border: 0px; color: #0086b3; margin: 0px; padding: 0px;">assert </span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">re-matches</span>
<span class="o" style="border: 0px; font-weight: bold; margin: 0px; padding: 0px;">#</span><span class="s" style="border: 0px; color: #dd1144; margin: 0px; padding: 0px;">"We have liftoff at .* ..:..:.. 20.."</span>
<span class="nv" style="border: 0px; color: teal; margin: 0px; padding: 0px;">body</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">)))]</span>
<span class="p" style="border: 0px; margin: 0px; padding: 0px;">(</span><span class="nf" style="border: 0px; color: #990000; font-weight: bold; margin: 0px; padding: 0px;">launch-rocket</span><span class="p" style="border: 0px; margin: 0px; padding: 0px;">))</span>
</pre><div><br />
</div></div><br />
Wasn't that more fun than dependency injection?<br />
<br />
The code's <a href="https://github.com/meredydd/expect-call">on GitHub</a> – go try it out!<br />
<br />
Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-65675512046683794272011-12-09T01:29:00.005+00:002012-10-28T01:11:02.292+00:00The Social Messages of "Tangled"Pixar has historically been slightly tone-deaf on gender issues. This jaw-dropping quote, allegedly from a Pixar executive, embodies the problem:<br />
<blockquote><a href="http://www.vastpublicindifference.com/2008/06/pixars-gender-problem.html?showComment=1238100300000#c453231808703962113"><i>"We're very aware of it and we're trying to change. But sometimes it's just so hard to find a way to justify adding a female character to the story. We want to be fair, but every character has to have a reason to be there."</i></a></blockquote>(If you can read that without thinking that something is obviously, glaringly wrong in the imagination of the speaker, you might want to skip this post - it relies on premises I'm not going to go into right now.)<br />
<br />
But come back, Disney animation, all is forgiven. <i>Tangled</i> has genuinely strong female characterisation, a frank description of emotional abuse, and is quietly packed with positive messages.<br />
<br />
<a name='more'></a><br />
<br />
<br />
The central conflict of the film revolves around an emotionally abusive relationship between the female lead, Rapunzel, and her adoptive "mother", Mother Gothel. Happily, I cannot comment on the accuracy of the depiction - but it is portrayed convincingly, and matches what I have read online and heard from less fortunate friends. Mother Gothel does not follow the usual villanous clichés of physical violence or outright intimidation. Instead, she uses guilt, manipulation and even love to keep Rapunzel in her place. These are the tactics that make it so hard for so many people to accept that what they experienced was "real" abuse.<br />
<br />
<br />
The manner of Rapunzel's imprisonment has moved with the times. She is no Cinderella: as she narrates in the foot-tapping opening number, most of her day is spent on genuinely enviable creative hobbies. This evolution mirrors a shift in the socially conservative attitudes these stories are fighting. No longer is the anti-feminist message a straightforward "women should stay home and do housework". Societal change has rendered that line untenable. Now, it is the gilded cage: women should find self-expression and fulfilment through "<a href="http://www.ladiesagainstfeminism.com/tag/womanly-arts/">womanly arts</a>" (making sure <a href="http://www.salon.com/2011/01/15/feminist_obsessed_with_mormon_blogs/">everybody knows</a> how fulfilled they are), but remain largely inconsequential to the outside world.<br />
<br />
<i>Tangled</i> is a broadside against this message. Better to risk the dangers of the world, says Rapunzel, than sit at home doing crafts and forever wonder what those lights over the mountain really are.<br />
<br />
<br />
"Disney feminism" has a bit of a bad rap. After all, how much daring social progress <i>should</i> one expect from a large media company which produces innocuous, profitable children's stories? But Disney both reacts to and defines middle America. Disney is a bellwether, because they won't say something unless millions of American parents are ready to hear it. But once they do, their powerful, pervasive stories will drag the others along.<br />
<br />
Put it this way: Since the day this film was released, purely emotional abuse - even wrapped up in terms of love and protection - isn't just maybe-bad, it's-just-sometimes bad, he-tells-me-he-loves-me-it-can't-be-that-bad. It's <i><b>Disney villain bad</b></i>.<br />
<br />
<br />
There's a nice symbolic fillip at the end, too. The male lead, of course, gets his climactic moment of Big Disney Sacrifice. But how does he do it? <i><b>He cuts her hair off</b></i>. From <a href="http://bible.cc/1_corinthians/11-6.htm">Biblical times</a> to the <a href="http://www.guardian.co.uk/lifeandstyle/2009/jun/05/women-victims-d-day-landings-second-world-war">Second World War</a> to <a href="https://www.youtube.com/watch?v=0EWnPG_yKYk">modern culture</a>, cutting off a woman's hair is a humiliating symbol of de-feminisation. So Flynn cuts off Rapunzel's hair. He severs her power to heal and nurture, her blonde innocence, and all the reasons she is too <i>needed</i> at home to be allowed into the big wide world. He cuts off her hair so she can go rule a country instead. How cool is that?<br />
<br />
<br />
<center style="color: #888"><i>(For the purposes of this post, Meredydd is pretending that the tooth-grinding final line of the film does not exist. Don't break his illusions.)</i></center>Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-6589318304106374342011-09-01T17:16:00.014+01:002013-01-16T17:45:15.829+00:00Startups, China, and my increasing ambivalence about capitalism<div class="c0">I used to be all for entrepreneurship. I long took it for granted that I’d found a software startup as soon as possible after graduating. But I’ve started to worry that prolonged direct contact with the incentives of a free marketplace would either demand that I be - or worse, turn me into - someone more morally compromised than I really want to be.<br />
<br />
The genius of a free market is that it measures the entire complexity of the world in one dimension - price. But this one dimension along which the world is measured does not precisely correspond to "good", in any human sense. It's not completely unrelated; it correlates well enough to have produced immense advances in human well-being over the last few centuries. But the invisible hand teaches to the test<sup></sup>: it optimises ruthlessly for the one thing it measures. The market is like evolution: not evil, but an extremely powerful force not <span class="c5">quite</span> aligned with your or my interests.<br />
<br />
<a name='more'></a><br />
This ruthlessness is why I'm uncomfortable with hard libertarianism, which essentially tells us that markets are good: the more of our lives we run through them, the better the world will be.<br />
<br />
I also think it's the big reason that people are uncomfortable with China's commercial culture. The economic cultures of "the West" have co-evolved with the development of commerce, and in doing so have built a sort of <span class="c4"><a class="c2" href="http://lesswrong.com/lw/18b/reason_as_memetic_immune_disorder/">cultural and institutional immunity</a></span> which blunts the less pleasant consequences of a free market. Lacking this immunity, China's sudden adoption of capitalism in the 1970s has led to a ruthlessly profit-seeking environment which I can only describe as <i><span class="c5">nastier</span></i> than the developed-economy bubble I live in.<sup><a href="#ftnt1" name="ftnt_ref1">[1]</a></sup><br />
<br />
I'm not talking about truly evil things such as melamine-doped milk, although you can bet the milk suppliers were under strong market pressure to do that too. I'm talking about the pervasive stories of sharp practice, of bending the rules, of seeing what you can get away with. I'm talking about the outsourced factories that progressively increase error tolerances until the commissioning company kicks up enough of a fuss - then wait a bit, and start increasing them again a couple of months later. "Third shift" knockoffs. Fake Apple stores. The Foxconn suicides.<br />
<br />
And yet. For several years now, I have been immersing myself in the startup literature, with its emphasis on "hustle" and "scrappiness".<sup><a href="http://www.blogger.com/post-edit.g?blogID=4522189764185139314&postID=658931830410637434#cmnt3" name="cmnt_ref3"></a></sup> Spend long enough in this world, and it seems that relatively few of the sharp practices that would make me reluctant to work in China are actually considered <i><span class="c5">wrong</span></i> - and definitely not beyond the pale. Paul Graham once said something to the effect that most successful startups have at some point done questionable things to get themselves to the next paycheck. AirBnB got its start by spamming Craigslist posters, Plaxo spammed its users' contacts, and Zynga (of Farmville fame) gained a substantial chunk of its revenue from incredibly deceptive "lead-gen" offers.<br />
<br />
Startups do seem most prone to shady behaviour early in their lives. This makes sense - that's when they are most desperate, don't have a reputation to uphold, and are least beholden to the norms of larger businesses. Perhaps it's just that in China, with most private industry arising from nothing within the last three decades, all commercial culture descends from startup culture.<br />
<br />
<br />
Be that as it may, why does this affect the aspiring entrepreneur? Sharp elbows may be part of the game, but why wring one's hands about the rules of a game?<br />
<br />
Ways of thinking are habit-forming. Hackers almost universally acknowledge that learning to program changed the way they view and interact with the whole world. Why should intensive study of another way of thinking be any different?<br />
<br />
If you have friends who have gone into investment banking, you probably already know what I mean. Direct engagement with the market makes you learn to think like a market; you have to. At that point, I suspect that internalising its values is all too easy. And those values are so superficially similar to human principles that it's easy to <a href="http://www.paulgraham.com/good.html">convince yourself</a> they're the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Objectivism_%28Ayn_Rand%29">same thing</a>.<br />
<br />
<br />
And so we end up with a three-time startup CEO <span class="c4"><a class="c2" href="http://sam.odio.com/2011/08/12/i-took-625-jonathans-card/">skimming off $625 from an experiment in altruism</a></span>, bragging about it, and then <span class="c4"><a class="c2" href="http://sam.odio.com/2011/08/13/jonathans-card-experiments-and-outcomes/">acting hurt and confused</a></span> when people react negatively. After all, it was allowed by the rules, right? And if I didn't, someone else might. And in any case, it was an experiment, and all I was doing was providing results.<br />
<br />
As a very perceptive <a class="c2" href="http://news.ycombinator.com/item?id=2883376">comment on HN</a> put it, this is an almost autistic response. The fact is, humans are really bad at explicitly drawing up rules<sup><a href="#ftnt2" name="ftnt_ref2">[2]</a></sup>. Instead, we use social conventions - morality - to establish and enforce a consensus that's usually more restrictive than the rules themselves. <sup><a href="#ftnt3" name="ftnt_ref3">[3]</a></sup><br />
<br />
But adherence to convention is actively cautioned against in startup circles. Naughtiness, subversion and a refusal to play by the rules are prized. "If you're running a startup, you had better be doing something odd. If not, you're in trouble."<br />
<br />
<br />
I linked earlier to an excellent post at Less Wrong, about the idea that cultures develop a memetic immunity to ideas and beliefs with dangerous consequences. I believe that market capitalism is one of these sharp-edged ideas, against whose consequences we have developed both cultural and institutional protection.<sup><a href="#ftnt4" name="ftnt_ref4">[4]</a></sup><br />
<br />
Founding a startup involves discarding this suffocating, inefficient insulation against the market, accepting its demands head-on, and (hopefully) reaping the benefits. But discarding one's immunity can be dangerous. As that article concludes:<br />
<br />
<blockquote>Another heuristic is to listen to your feelings. If your conclusions seem repulsive to you, you may have stripped yourself of cognitive immunity to something dangerous.</blockquote><br />
<br />
I can't say for sure whether these habits of thinking are induced by prolonged operation in an amoral market, or whether they just make you better at it. Either way, I am becoming unsure that these are the waters in which I want to spend my life swimming.</div><br />
<br />
<div class="c0"><br />
</div><div class="c0"><br />
</div><hr class="c6" /><div><div class="c0 c3"><a href="#ftnt_ref1" name="ftnt1">[1]</a> This isn’t to say that China won’t develop its own immunity. Indeed, there are signs that it already is, and much faster than the developed nations did at the equivalent points in their own industrial history. But right now, it’s the Wild West, with all that implies.</div></div><div style='margin-top: 1em'><div class="c0 c3"><a href="#ftnt_ref2" name="ftnt2">[2]</a> Aside: Actually <span class="c4"><a class="c2" href="http://lesswrong.com/lw/ld/the_hidden_complexity_of_wishes/">give us a genie</a></span> that obeys us literally, and wishing for anything at all would become almost indescribably dangerous. There is a <a href="http://lesswrong.com/">whole group</a> of people who think that technology might provide such a genie in the foreseeable future, and are understandably eager to get good at explicitly encoding human morals first.</div></div><div style='margin-top: 1em'><div class="c0 c3"><a href="#ftnt_ref3" name="ftnt3">[3]</a> The aforementioned entrepreneur apparently didn't understand this himself. As the outrage mounted, he emailed Jonathan Stark, the originator of this experiment in altruism, asking for his reaction. Stark responded by directing him to the project's Facebook page, where the community's moral consensus on his actions was readily visible, and described them as the ones whose opinions mattered. This was interpreted as "stomping on [his] olive branch" and "refus[ing] to address [his] question", without any understanding that the message was one of moral convention and the social construction of acceptable behaviour.</div></div><div style='margin-top: 1em'><div class="c0 c3"><a href="#ftnt_ref4" name="ftnt4">[4]</a> It's not that I think that I know something better. The alternatives tried so far are horrific, or don't scale, or both. But the best that I can say about free markets is that they are, like democracy, "the worst system, apart from all the others". I support them on that basis, but they are dangerous machines, and should be operated, where possible, with suitable protective clothing.</div></div>Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-82304517872319137902011-09-01T15:09:00.001+01:002011-09-01T17:30:25.677+01:00The Green Counter-RevolutionI now have <a href="http://www.rusi.org/analysis/commentary/ref:C4E5F66F731EAB/">a piece up</a> at the Royal United Services Institute, a think tank, about Iran's eavesdropping on GMail, how it happened, and some international context. I even have a go at some policy implications (internet censorship: a bad thing, apparently).<br />
<br />
It sort of grew out of <a href="/2011/08/iran-intercepting-access-to-gmail.html">Monday's post</a> on the topic.<br />
Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-81368368784848089122011-08-29T22:30:00.014+01:002011-09-01T21:45:36.322+01:00Iran Intercepting Access to GMail<b>Technical summary:</b> A user in Iran is reporting on <a href="http://www.google.co.uk/support/forum/p/gmail/thread?tid=2da6158b094b225a&hl=en">Google's support forums</a> that users attempting to access GMail from Iran are periodically being given a false SSL certificate. <i>Update:</i> Google have now <a href="http://googleonlinesecurity.blogspot.com/2011/08/update-on-attempted-man-in-middle.html">confirmed this</a> on their blog.<br />
<br />
<b>Non-technical summary:</b> The Iranian government appears to be getting increasingly sophisticated in their war on Internet dissidents. Notably, this is one of the first "in the wild" applications, by an authoritarian state, of an attack that has been widely forseen by security experts.<br />
<br />
<i>(Updated some links Tuesday)</i><br />
<br />
<i>(Updated "advice if you're in Iran" on Thursday. I have now written an <a href="http://www.rusi.org/analysis/commentary/ref:C4E5F66F731EAB/">article</a> on this attack for the Royal United Services Institute, including a bit more international context)</i><br />
<br />
<a name='more'></a><br />
<h2>What does a fake certificate mean?</h2><br />
This is evidence that somebody is engaging in a "man in the middle" attack against Iranians using GMail. This would allow the attackers to eavesdrop on users' email.<br />
<br />
<h2>How could this happen?</h2><br />
The way that secure browsing works, when you connect to a website (say, <code>gmail.com</code>), it proves its identity with a digital certificate saying who it is. This certificate is "signed" by some authority, saying the holder of that certificate is indeed the owner of the <code>gmail.com</code> domain. Your browser verifies this before connecting, and puts up scary warning messages if the certificate doesn't check out.<br />
<br />
The "signing" is mathematically pretty watertight, but there are a large number of certificate authorities out there, and the average web browser trusts several dozen of them. Gain control of one of them, and you can sign any certificate you like.<br />
<br />
This user is apparently being presented with a fake certificate for <code>gmail.com</code> signed by DigiNotar, a Dutch certificate authority. This would enable the owner of that certificate to pretend to be <code>gmail.com</code> - without any scary warning messages, or any indication at all to the users that anything is amiss.<br />
<br />
If an attacker with this certificate can get users to contact their servers instead of Google's, and forward all data to the real <code>gmail.com</code>, the users would see no difference, but the attacker could then eavesdrop on the contents of the "secure" connection. (This includes harvesting their GMail username and password for future use - so it only has to be done once.)<br />
<br />
The Electronic Frontier Foundation explains this vulnerability in more detail <a href="https://www.eff.org/deeplinks/2011/08/iranian-man-middle-attack-against-google">here</a>. <br />
<br />
<h2>Who is responsible?</h2><br />
This attack is relatively sophisticated - to pull this off, you need to either coerce or break into a certificate authority. (In this case, it was probably the latter, as DigiNotar is a Dutch company. Depending on how good the security at the certificate authority is, this probably doesn't need to be a physical break-in. The most responsible CAs will keep their private keys on an "air-gapped" network not connected to the Internet, but with dozens to choose from, you can probably find someone who doesn't.)<br />
<br />
In addition, you need to change something such that when your victim enters <code>gmail.com</code> into their address bar, they connect to your malicious server rather than Google's real one. The easiest way to do this is to <i>be</i> the person that the user is asking, "Where is <code>gmail.com</code>?" - that is, the ISP.<br />
<br />
The fact that this attack is apparently localised to Iranian ISPs, and reportedly didn't appear when the user used a VPN to "tunnel out" (as is often done in China to avoid the censors there), support the hypothesis that this is an attack by the Iranian authorities.<br />
<br />
In addition, an Iranian commenter on <a href="http://news.ycombinator.com/item?id=2938516">Hacker News</a> reports that less sophisticated SSL man-in-the-middle attacks are commonplace, and that dissidents have been arrested based on private information probably gleaned from such intercepts. The emergence of more sophisticated attacks would therefore be a natural progression.<br />
<br />
<br />
<h2>Why is this surprising?</h2><br />
Security experts have been <a href="http://www.schneier.com/blog/archives/2010/09/uae_man-in-the-.html">warning about the possibility of these attacks</a> for years, but it is surprising to see a relatively unsophisticated country like Iran taking the lead in actually deploying this stuff.<br />
<br />
Part of the reason is actually <i>because</i> Iran's digital footprint is so small. This sort of interception, while not mathematically hard, takes nearly as many resources as serving the website you're intercepting. For a well-wired country like China, such interception is impractical on a drag-net scale. But Iran is small enough that these relatively expensive surveillance techniques are feasible.<br />
<br />
Even the Iranian infrastructure is apparently struggling - the original report on the Google forums indicated that the fake certificate was only being offered for about half an hour to an hour each day, suggesting that they are spreading their interception resources hour-by-hour across segments of the population. But as I explained above, you only need to hit someone once. <br />
<br />
100% coverage would have made the attack a bit more robust. But the indications are that the Iranian authorities are making progressive improvements in repressive technology, and are now actively exploiting a structural problem with encrypted communications on the Internet which will be very difficult to fix.<br />
<br />
<h2>If you're in Iran...</h2>Just in case anyone's reading this from there:<br />
<ul><li><i>Update (Thursday 1st Sep):</i> Update your browser - a new version of Firefox has been released, which does not trust the compromised DigiNotar certificate. This won't solve the problem in the long term, but immunises you against this particular attack.<br />
</li>
<li>If you get warnings about "certificates" or SSL, <b>believe them</b>, and don't browse that site (or use a VPN or Tor). Current indications are that you'll be okay again in about an hour, so don't just click through.<br />
</li>
<li>Get an encrypted VPN (Google for it).<br />
</li>
<li>Enable <a href="https://www.google.com/support/accounts/bin/static.py?page=guide.cs&guide=1056283&topic=1056284&hl=en">two-step verification</a> on your Google account. (That way, even someone who's swiped your password can't log into your account - they'd have to snoop you directly)<br />
</li>
<li>Use <a href="http://www.google.com/chrome">Google Chrome</a>, whose certificate-pinning feature alerted us to this attack in the first place<br />
</li>
<li>If you want to be really careful, use <a href="http://www.torproject.org/">Tor</a> - it's slow, but pretty secure. <i>Update:</i> We now know that the Tor website was also targeted by this attack, so if you downloaded Tor in the last few days, you might have got a "poisoned" version. Update your browser (see above), and then download it again.<br />
</li>
<li>Change your DNS settings <a href="https://code.google.com/speed/public-dns/docs/using.html">as shown here</a> (not foolproof, but makes it a bit harder to do the DNS hijacking part of the attack)<br />
</li>
</ul>Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0tag:blogger.com,1999:blog-4522189764185139314.post-87965067866982504472011-08-28T18:50:00.003+01:002011-10-16T01:34:59.283+01:00Nokia's Downfall: A Self-Inflicted Wound<i>Update Sep/Oct 2011 - The N9 Meego phone has finally launched. TechCrunch has labelled it <a href="http://techcrunch.com/2011/10/15/nokia-n9-the-most-amazing-phone-youll-never-buy/">"the most amazing phone you'll never buy"</a>.</i><br />
<br />
Nokia's fall has been sudden and swift. They have lost the smartphone wars decisively: Unable to mount a competitive response to the iPhone and Android, their last-generation platforms have been spectacularly outclassed, and their efforts to produce something new were too little, too late. They bowed to this reality earlier this year, in a deal which makes them little more than a hardware manufacturer for the struggling Windows Mobile operating system. Plenty expect the rump of the once-proud phonemaker to be on the auction block within the next couple of years.<br />
<br />
This is all true, as far as it goes. But what these accounts miss is that Nokia shouldn't have been reacting to this revolution in the first place. They were years ahead of it, until they squandered their industry leadership in a strategic blunder driven by internal politics.<br />
<br />
<a name='more'></a><br />
<br />
<h2>The Promise</h2>In November of 2005, <i>three years</i> before Google's first Android phone hit the shelves, and two years before the first iPhone, Nokia launched the 770 Internet Tablet. It was a small touch-screen computer, as thin but a little larger than my current-generation phone. Connecting via WiFi, or over Bluetooth to a phone in your pocket, it could browse the internet, watch videos, or check your email. It even supported Flash (this is in <i><u>2005</u></i>, remember). Streaming video required RealPlayer, though, as Youtube hadn't even launched when it was released. Two years after its release, my 770 was still eliciting "ooh"s and "aah"s from my friends whenever I got it out and showed what it could do.<br />
<br />
Even better, the 770 was built on existing, open technologies, making it a developer's dream. Like Android, its "Maemo" software was built on the Linux operating system, but unlike Android, it used X11 and GTK - the same user interface technology I'm using on my laptop right now. Linux developers were on familiar ground, and many applications required only minimal modifications. I ported TCL/Tk, a simple language for whipping up apps, to the 770 in an afternoon.<br />
<br />
The device was so hotly anticipated that the pre-orders exceeded Nokia's manufacturing capacity. Launch-day orders were still being shipped in January 2006. Third-party applications exploded, with a mixture of existing Linux apps and new ones written from scratch by the growing community.<br />
<br />
June 2006 brought a software update, including built-in SIP internet calling and instant messaging with Google Talk. Developers reacted with renewed enthusiasm. This was the future, and Nokia was making the running. The community was waiting for the inevitable next step: a "Maemo phone", a 770 with a SIM card.<br />
<br />
That step never came.<br />
<br />
Nokia released an upgraded tablet with more memory and a faster processor in 2007, and added a slide-out keyboard a few months later, but it quickly became apparent that Maemo was an orphaned platform. Despite the game-changing arrival of the iPhone that year, Nokia were inexplicably doubling down on the already-ageing Symbian OS.<br />
<br />
<h2>A Bag of Wet Sand</h2>Nokia's Symbian phones had led the smartphone market for years, giving the Symbian division great weight within the company. But Symbian was old software, and showing its age. Developing apps for Symbian was a painful experience, and Nokia seemed in no hurry to make it easier. The same year the 770 was launched, Nokia introduced "mandatory code signing" for Symbian, forcing developers to pay thousands of dollars to even try writing an application for their newest devices. This was done not for strategic reasons, but to mitigate the inherent insecurity of the Symbian OS, which allowed any installed application to essentially take over the phone. By 2008, this inflexibility and poverty of apps meant that the ComScore tracking organisation wasn't even counting Symbian as a smartphone platform.<br />
<br />
The 770 was a fresh start, outside the existing feature-phone- and Symbian-centric structure of Nokia. From the outside, it often seemed as though the Internet Tablet team were a start-up within a company. They turned out revolutionary products at a rapid clip, but obviously lacked internal support in the face of a status-quo monolith that dominated the company's bureaucracy.<br />
<br />
<h2>The Fall</h2>The rest of the story is well-trodden. Despite attempts to update Symbian for touchscreens, it was clearly outmatched by the iPhone. Nokia panicked, and struck out incoherently in several directions at once. They continued to repeatedly kill their most promising platforms, then take years to ship a replacement.<br />
<br />
Weeks before the first Android phone was released, in late 2008, they finally announced a Maemo phone. But it was over a year before the N900 was released, still plagued with hardware issues. By then, multiple manufacturers were offering Android devices, with a tiny but accelerating market share.<br />
<br />
Within two months of the N900's release, Nokia had announced that they were jettisoning Maemo for a merger with Intel's unproven mobile Linux platform. With no follow-on hardware updates to iron out the N900's flaws, and a platform that had publicly been labelled a dead end, it sank like a stone.<br />
<br />
Two years later, Nokia has yet to release a handset running the new "Meego" system. The window for new smartphone platforms has mostly closed, yielding a two-horse race between Android and the iPhone. By this point, Nokia would have faced a hard, uphill fight for third place.<br />
<br />
The Microsoft tie-up has now effectively killed the Meego platform. The first - and presumably last - Meego handset will still be released this September. It has received excellent pre-release reviews.<br />
<br />
Six months after the Microsoft deal that killed Meego, Nokia has yet to announce a single Windows 7 phone.<br />
<br />
Throughout the company's thrashing decline, as more promising platforms were alternately strangled in their cribs and left languishing in under-resourced development hell, Nokia continued to release several new Symbian handsets per quarter. Somewhere in Finland, I am certain that there is still a Symbian division manager who is <i>proud</i> of this - who does not realise the cost at which this continuity was achieved.<br />
<br />
<h2>What We Lost</h2>Like all true tragedies, Nokia's death is ultimately self-inflicted, but my disappointment lies elsewhere. Their bureaucratic blindness not only cost them their command of the mobile market, but the vision of the smartphone future they almost represented. Android is pretty developer-friendly, but the idea that my phone should be a full computer is deeply appealing, and in many ways more powerful than the explicitly device-like model we now have instead.<br />
<br />
The iPad's ambition is to replace the laptop, to "device-ify" the computer, at the expense of flexibility, openness and control. The 770 offered us instead the computer-ification of the device: occasionally messy, but open to boundless possibilities.<br />
<br />
Attend any academic conference, or other gathering of geeks, and you will meet a few people still jealously guarding their N900s. They nurse the faulty hardware because warranty support has long since disappeared, and tolerate the abysmal battery life because they so value having a Real Damn Computer in their pockets. It is a good rule of thumb that what geeks are passionate about is a leading indicator - because where geeks are happy, they build things that will bring the users with them. Even after the first round or two of slaughtering their best platforms at birth, Nokia could still have drawn on these reserves of passion. Even then, they still had a chance.<br />
<br />
I got my 770 out of the cupboard earlier today, and turned it on. The clasped hands on the startup screen felt out of place; once upon a time they would herald each new round of mobile innovation, and now I was faintly surprised to see them on anything good at all. In this elegant time capsule from 2005, I caught a glimpse of the mobile future we might have had. I rather wish I had seen it come to pass.Meredyddhttp://www.blogger.com/profile/17520193400049712019noreply@blogger.com0