Sunday, December 30, 2012

Adventures in Multilingualism

Writing only in one language is so passé.

There's an idea in programming circles that one should be continuously learning new languages, say, one new one a year. I agree, but not so much with programming languages as spoken ones. Despite extending my programming language repertoire with some Typescript recently (if you’d even call that a full-blown language) spoken languages are more interesting to me right now. European ones. If language be food then these days I'm enjoying a main course of Spanish, picking at some Greek mezes, and reheating French leftovers.

As a kid I learned Irish, Latin and French at school. Because my parents took in Mexican students during the 70's and 80's I picked up a little Spanish as a teenager. Studying photography in Dublin in the 90's, we had a German language module for some reason. And when I married a feisty Zantean, I found myself absorbing (ab-Zorba-ing?) Greek passively at the family dinner table. All these languages in my head, some resentfully imposed on me, some enthusiastically embraced by me, had nowhere to go and no-one to speak them. Until recently I wasn't interested in learning any new language or keeping up the ones I knew, being of the mind as I was that it was a waste of time learning how to say the same thing in different ways. New ideas in science and programming were what mattered, not asking someone the time in French.

Multilingual
'Multilingual', by Shaun Chapman

At the same time I've exercised my language muscles intermittently over the years simply by dint of being such a fan of foreign language cinema. When Luis Buñuel died in 1983 a retrospective of his movies was shown on BBC which as a sponge for foreign esoterica I watched on an old black and white TV in awe. Truffaut died the following year; the years passed, all while I clocked up an impressive list of movies watched from all corners of the world without ever parlaying this cineaste activity into any meaningful progress vis-à-vis learning or improving a language.

For some reason, in the last couple of years I've slowly come around to the virtues of finally doing Spanish properly, doing Greek for the first time, and while I'm at it brushing up on my rusty, half-forgotten French. I don't know why this is; why the language bug has bitten. It may well be because since becoming a programmer in Brisbane I've found myself immersed in a cacophonous parliament of foreign-born colleagues, especially at Dialog, and when on a team with Readifarians of +Readify. I’ve grown accustomed to hearing workmates speak a confusion of languages all around me, and that has had a sort of liberating effect on me from the suffocating monopoly of English one finds here in Australia.

I’m foreign-born too by the way: foreign-born twice over in fact. Irish but born in England. I’m obviously not comparing my situation directly to that of many of the people I've worked with who speak English as a second language, but at the same time I believe that if you weren't born here (and I’m going to generalise this observation in a ridiculous sweep to apply to every country in the world) then you’re different, your language is different, and you are always somewhere on the 'different' scale. "We really have everything in common with America nowadays", said Oscar Wilde sometime in the late 19th century, "except, of course, language." It's the same for a Dubliner who comes to Australia: there are plenty of phrases you have to learn that are unheard of in Ireland, and vice versa, of course. Plenty of friendly enquiries about your accent, plenty of mystified looks when you say that a developer meeting was 'good craic, with decent heads.' Sensibly, you learn to stop talking like that if you want to get on with Australians, never mind kiwis and Indians.

One of the effects of studying languages like I've been doing is to have new-found respect for people I've worked with - people like +Adrian Budiman from Indonesia, +Sandra Palacio from Columbia, +Mehdi Khalili from Iran, +Paulo Alexandre Ogliani from Brazil, +Dmitry Kryuchkov from Russia, +John Wilson from South Africa - who are doing what I do, usually much better, through the fog of a second language. How do they do it?

Only joking about John, by the way: South Africans of course speak English and he actually has a euphonious, 'nice' South African accent. Some of the other South Africans I've met on the other hand sound like 'District 9'. "To this day the accents of Australian, New Zealand and South African English have a distinct family resemblance, derived from the shared experience of class emigration." writes Robert McCrum in Globish. It took me a while to distinguish the Aussie and kiwi accents, but the South African one is quite distinct from either of those to my ears.

Phrases and words that have a different meaning in Australia to the one I’m used to include 'ordinary' (poor quality), 'yeah no' (normally employed separately since they are mutually exclusive responses), of course ‘root’, and just for good measure 'three fifths of a poofteenth' (a trifling amount). My friend Paulo told me he found the hardest part of the language to be phrasal verbs, like 'pay out' (criticise), or ‘stand down’ (sack/fire). While it might look to someone struggling with English that English speakers have it easy, some phrases are what the French call faux amis, false friends, because they look like one thing and act like another.

So for all my joi de parler, my polyglotism (such an ugly word for a nice thing), how does multilingualism affect your writing if you’re a blogger like me? Maybe not at all. After all, anyone can translate anything you write into just about any tongue under the sun using Google Translate or some similar type of app or browser plug-in in an instant. Speaking of Google Translate, I use it all the time and I find it to be one of the marvels of the computing age. As far as I’m concerned, cloud machine translation, in more or less real time, on your phone, Chavooon!, is mankind harvesting the fruit of its ingenuity in spectacular form - one of those boons you get for just sticking around long enough and buying enough devices and computers over the years, the stuff of our parents' imagination, but for us just another app.

Back to the point: why write in anything other than English? After all, a majority of the web’s content is written in English. But the foreign language internet is rapidly expanding, particularly Chinese, Spanish, Russian and Arabic. Apparently it mightn’t be a bad thing to prime your content with some foreign language version to optimise for all the non-English people who search for your goodness. But I’m not really interested in any practical reason for any of this, or at least, not in any obvious, immediate sense. The most compelling reason I can offer for learning Spanish, French, Mandarin or Greek is this: you have a life of the mind, we all have. It has boundaries, they all have. When you start to think in foreign languages you expand those boundaries. Can you think of a better reason to do something? That’s it. Cést tout. And writing in those languages just takes it to the next level, and moreover is easy to break into using Google+ in particular.

If you’re worried about alienating what small audience you have on Twitter, Blogger, Google Plus, etc. by your experimental ramblings then like I say I recommend Google+. It’s the only big network where you can filter on your side, by sharing only to people you choose to: sympa friends, the language Meetup group you’ve joined, connections you know who aren't going to uncircle you because you've turned into Anthony Burgess. Twitter and Blogger don’t have any such 'supply-side' filtering. Everything you tweet or blog goes out there, to all your followers/subscribers. So, set up a G+ circle for your, say, French bons mots, write something à propos in French then share it without making it public: share just to that particular circle to keep it low-key.

Something else to consider is following a newspaper like El País or Le Monde on Google+ and comment on a post just to be part of the conversation. There are spirited and (generally) well-informed and polite conversations on most posts, and let's face it, no-one is ever going to judge you too harshly for a badly-phrased comment. The day you get your first +1 for a foreign-language comment is a red-letter day for a would-be multilinguist.

Wednesday, December 19, 2012

Science books of the year 2012

These 7 lucky books are my best science books of 2012. I know what you're thinking: that these are the only ones I read. Hey! That's not fair. Well it's true that I didn't read too many more than this. But I picked them carefully in the first place, as you have to if you have a full-time job, two kids, and not nearly as much free time to read as you'd like. And as it turned out, how right I was! So, having dealt with that objection, let us now turn to important matters. Let us talk of books, like men.

Apart from the winner, I've decided to leave it as a flat list, just like the Royal Society Winton Prize. Obviously, I could pick some from the runners-up that are bigger in scope, more enjoyable, better written, anything, than others, but to start trying to sort all six places like that is meaningless, so they're all in second place.

Best science book of 2012: "The Better Angels of our Nature" by Steven Pinker

You know that phrase that you hear about some books? About how it will change the way you look at the world? This one probably will. That's because it'll persuade you to moderate the feeling that you probably have that the world is getting worse, nastier, and more violent all the time. I blame videogames. It turns out this pessimism largely stems from two things: we overestimate the amount of violence in the world simply because we see it frequently on the news or on YouTube (a bias called the "availablity heuristic", explained in my no.2 book in this list), and we know far too little about the past.

This is a huge book, as in your hand will get tired holding it, and that's relevant to any assessment of it. Not because manual fatigue is interesting per se, but rather because the ambitious scope of this oeuvre has to be acknowledged in any discussion about it. From an unforgettable opening couple of chapters reminding us of the sheer savagery in the bible, and an eye-popping exploration of medieval torture devices, things become slowly more civilized as time passes, leading ultimately to the society we enjoy nowadays, where groups that were hitherto oppressed - animals, children, women, and homosexuals - gradually acquire the same rights as white guys like me over time. Well, alright - nearly. The scope of this book is so wide that you could enjoy it as history, or as science. Either way, it'll change the way you look at the world.

"Thinking, Fast and Slow", by Daniel Kahneman


Daniel Kahneman looks like my father-in-law, but that's where the similarity ends I'm afraid. Wise and worldly as Papou is, Kahneman has a lifetime of sociological work behind him at this stage and his book, which is rather like a recap of his life's work to explain how people think, is a depressing litany of foibles and idiosyncrasies from which we all apparently suffer. The data prove it. I say depressing, because much as I love Tim Harford's hardline rationalism in 'The Undercover Economist' and 'The Logic of Life', if the concept of anchoring is true, well, it makes me weep for humanity.

Just so you know, anchoring is the business of influencing people subconsciously to choose a value you mention, even if just innocently, for example in a discussion on how long a piece of work might take to complete, by simply saying that value. That's it. No more than that. You might have just rolled a dice in front of everyone to come up with the value; it matters not. We are all prey to arbitrary suggestions, and that's simply depressing.

"A Universe from Nothing", 2012, Lawrence Krauss

Lawrence Krauss was one of the stars of the 2012 Global Atheist Convention. There were plenty of big names there, but even among them he cut a rock-star dash, pacing up and down on the stage running though his cosmological shtick once more. Cosmology is just mind-blowing, one of the few disciplines where you can talk about the really big questions and receive meaningful explanations. Mind you, you have to pay attention, really pay attention: this was the hardest book to follow in this list. The historical run though the decades leading up to Einstein, relativity, and quantum mechanics are enjoyable, but from then on things get plain weird. A lot of the concepts in this book, like dark energy, the cosmological constant, and whether the universe is open, closed, or flat (turns out it's open) are so abstract as to be something I need to read repeatedly to sink in. It both makes me feel stupid and exhilarates me.

I should have just queued up for a copy of this book, signed in person by LK, at #AtheistCon when I had the chance. The queue was long, but it was obvious then by the love it was getting that this was going to be one of those event books you're going to end up reading one way or another. So you may as well meet the author. Kicking myself.

"Everything is Obvious", 2011, Duncan J Watts

Quite similar to the Kahneman book insofar as it's mainly about sociology and the counterintuitive (or 'unobvious') and fundamentally unpredictable nature of social interactions. This emphasis on the unknowability of the future makes it a bedfellow of the famous "The Black Swan" by Nassim Nicholas Taleb. Speaking of Taleb, he's got a new book out called "Antifragile", which I'm predicting will be on my list for next year. Whoops - a prediction!

There are many subtle points in this book that you might miss if you read it in a hurry. I found myself rereading pages to make sure that I hadn't just wasted my time reading something blindingly obvious. That's the whole point of the book: that plenty of things that you hardly think about are in fact not what they seem. Narrative sentences are one example. These are cases that seem to be more-or-less neutral descriptions of some event , e.g. "Such and such a border skirmish took place on such and such a date, effectively starting the Iran-Iraq war" but often, strangely, end up being descriptions that would have made no sense to people living through the events because, in this case, the war hadn't happened when that event took place so the sentence is peering into the future, placing the event within some larger narrative. It's obvious, now. But not then. And it leads to some profound conclusions: history cannot be told while it is happening.

"Massive", 2010, Ian Sample

2012 was a big year for the the Large Hadron Collider in general and the Higgs boson in particular. To get a bit of historical perspective on the LHC, the biggest machine ever built by humans, I sought out this book by the Guardian Science Podcast's own Ian Sample. Although it now looks like there might be two Higgs bosons, back before the announcement in July this year, we didn't even have one. It's not nearly as difficult a read as the Lawrence Krauss book - in fact the overwhelming memory I have of it is of a genuinely affecting story of international cooperation in the name of science.

To read this book in the heady days of autumn (northern hemisphere) as I did, when it seemed the great European project was in trouble, when every day saw Europe enter "a dangerous new phase of the [Greek credit] crisis" as the journalists loved to say, was a powerful restorative against such hysterical pessimism. If you look at projects like CERN, ESO and ESA then you'd have to agree that Europe is more than capable of getting on with it. It's just those bloody Greeks*.

"The Rational Optimist", 2010, Matt Ridley

Between reading this and "The Better Angels..." I've never felt more positive about things. Don't believe everything you read (in the newspapers) - things are actually getting better all the time. Human ingenuity, industry and above all compulsion to trade have lifted us out of the subsistence that was the our station until a very short time ago, according to Ridley. This is an impatient, opinionated read, as befits someone who is taking the rather sensible position of saying enough with the usual platitudes about history, and its great figures and sacred cows.
"My education was utterly dominated by two stories: the Bible's and Rome's. Both were disappointing examples of history. One told the story of an obscure, violent, and somewhat bigoted tribe and one of its later cults, who sat around gazing at their theological navels for a few thousand years ... the other, the story of a barbarically violent people who founded one of the empires that institutionalised the plundering of its commercially minded neighbours, then went on to invent practically nothing in half a millenium ... nearly extinguishing literacy as it died. I exaggerate, but there are more interesting figures in history than Jesus Christ or Julius Caesar."
And that's just a footnote at the back of the book! I must say that for all the Latin I learnt as a kid, the overwhelming memory I have is declining the verbs to 'wage war', and 'set up camp'. Never 'to come up with an idea', or 'to achieve gains in trade'. Merchants and traders of any stripe are the heroes of this book, from the ancient Phoenicians to the modern Walmarts. Priests, chiefs, thieves and scaremongering greenies get served.

There it is - what the world has been waiting for: my inaugural science book list. In light of such a never-ending stream of mind-expanding popular science books, year after year, I just don't read too many novels any more. It feels like short-changing myself. But now that "Bring up the Bodies" has won the Booker, I do feel like tackling that and "Wolf Hall". And I did enjoy Umberto Eco's "The Prague Cemetery", and Jonathan Franzen's "Freedom". But I love my science books: next year's list starts here.
* And Irish, Portuguese, Italians and Spanish.

Saturday, December 15, 2012

The Android Blogger app will drive you insane

In this short tale I will attempt to convince you that you should not use the Blogger mobile app under any circumstances except to finally publish an article to your blog, written elsewhere.

I'm on a 3-day break with my family at the moment, doing the usual sightseeing and relaxing by the beach. We rented an apartment at Noosaville, right on the river. While hanging out with Tina and the kids I usually do a bit of fiddling around on Twitter and Google+ on the phone, a HTC One X. This trip I thought I'd work on a blog post while I had a spare moment or two. Keep writing; if I can just keep writing!

There's something really wonderful about writing on the move. Mobile Phone technology allows you to live your own Kerouacian road fantasy, unshackled to the desk, typing out ideas pretty much as they occur to you. (I've no idea if Kerouacian is the correct adjective but if you say it out loud you'll realise it's a keeper.) As I type this, in fact, I'm sitting in a park in the kindly shade of a giant fig in the small market town of Eumundi in the Sunshine Coast hinterland of Queensland.

Flickr photo
FlickrJack Kerouac-Florida-1958, by pitoucat. Should have just used a typewriter, like Jack here

I noticed the Blogger Android app had been updated (to 2.0.41 - it must have been v1 previously). It looked newer, but whether it had any new features I couldn't say. There didn't seem to be any. Still lean as a whippet. Anyway, I fired it up and worked on a post I'd been writing for a few days. Penning a blog post in the Blogger mobile app isn't easy - making a link involves switching to Chrome, copying the URL, switching back and handwriting the 'a' tag, copying and pasting, which is fiddly to say the least.

I soon found out it was a bit worse than that. Pasting in a URL at one stage I realised I'd accidentally either pasted over much more of the post than I'd intended, or else cut instead of copied, or something or other - I can't be sure what I did exactly. Text editing on a phone is tricky, full stop. When you're composing a blog post which is supposed to have links, using software like Blogger which has no intrinsic way of making links, it's even trickier.

But here's the thing: Blogger has no 'undo'. Think about that. Let it sink in there for a minute. You could have spent a month writing an article, poured your heart into it, but one slip of the index finger and it's toast. In my case I lost my entire first paragraph, and could see no way to retrieve it. I knew the intact version of my article was only one level down on the history stack, but there was no way to get to it.

Switching to Chrome again, I Googled in vain for 'how do I undo in blogger Android app'. I couldn't find any way to. I did find plenty of links lamenting the lack of undo functionality in Android. But time was running out, or so I thought. Desktop Blogger auto-saves every minute or so, so fearing something similar I thought it best to quit back to the main menu at which stage I might get a save warning which I could cancel, possibly restoring my work. No such luck. With a diligence at once impressive and infuriating Blogger saved on close of the document. I had lost work in a harsh, unforgiving environment, much as I imagine the surface of Mars to be.

After some trial and error I realised that the way you have to use the app is to save as often as possible and use the Android back button to rollback your pending changes. That's because of two things: auto-save isn't enabled, and back button is effectively the undo button. Which is harsh, since it obviously undoes everything since your last save. Remember, this is a mobile app, one you might use waiting for take away fish'n'chips, waiting for someone to return from the toilet, waiting for the kids to get ready. I'm usually not 'in the zone' when I use it, so it's tough to keep to a sentence, save, sentence, save rhythm.

Google Drive can do undo and redo, so why the Dickens can't they do it for Blogger? I have since used Drive (ex-Google Docs, of course) to work on the article, happily undoing as the need arose, and will paste my finished piece into Blogger for the sole purpose of clicking the publish button. Because if there's one thing worse than using Blogger on Android, it's trying to use the Blogger website on a phone or tablet.

I'm not even going to talk about the way the app will HTML-encode the tags it itself places in your post if you dare to preview your piece more than once. Ok then, I will. Paste in something you've written in Drive and Blogger will turn any paragraphs into blocks surrounded by 'p'  tags. Ok, it's hard to see the structure of your article anymore, but that's valid HTML so that's ok. But on subsequent previews it will encode that 'p' tag again as well as whacking in a new, pristine one. It's around that time that your will to live starts fading.

And that's why the Blogger Android app is more than useless - it's a potentially dangerous waste of your words and your time. Writing on the road should be liberating and exhilarating, one of those things we can be so grateful to mother technology about. I love it. It's a real shame that Blogger makes such a mess of it.

Thursday, November 22, 2012

Welcome to the Republic of Letters

"There's nothing new under the sun." Oh yeah? What on Earth has ever come before that could possibly be like the internet? The Republic of Letters, that's what.

In my spare time I like to read books about science, history, technology, astronomy - in fact, one of the ways I measure my success in life is by the amount of time I free up to read about how the world works, and - just as important - how we came to know how the world works. The greatest story ever told. And reading these books, there are recurring dramatis personae, and recurring themes.

There's no getting away from Newton, for instance, or Richard Feynman, or Alan Turing, to pick just three. Turing comes up in relation to the history of cryptography, which in turn overlaps with the history of the computer. If computers are your bag you'll frequently encounter Charles Babbage, who gets a good run in James Gleick's "The Information", along with Ada Lovelace. He's a node, a narrative gravity well that a lot of paths pass through when talking about the history of modern technology: he also has a minor, passing role in "The Age of Wonder" by Richard Holmes, for instance, as an iconoclastic intriguer against the Royal Society.

Flickr photo
FlickrAshton Kutcher .', by Un poco locA !. following in the footsteps of giants of science .

So if you're reading similar sorts of books about the great scientists of the last couple of hundred years like Darwin, Davy, Herschel, Einstein, etc. it's hardly surprising that the same figures crop up again and again. But you wouldn't normally expect there to be too much in any treatment of their lives that has much bearing on how we use computers today, how we network, how we use social media, how we blog, tweet and update our status. Of course not. Why would there be? Back in the day they had to write letters and telegrams to each other and wait days and weeks for a reply. What's that got to do with mother social media, you say?

But reading Steven Pinker's "The Better Angels of our Nature" recently, I came across another node, a historical network that I never knew had a name. And what a name!
"The technologies of the day - the sailing ship, the printed word, and the postal service - had already made information and people portable. A global campus, a public sphere, or as it was called in the 17th and 18th centuries, the Republic of Letters."
We all know that in the old days people wrote each other letters. A lot of letters. But did you know that in the 17th and 18th centuries among scientists and philosophers, the network of correspondence was so complex and extensive that it was effectively what we'd nowadays call a blogosphere, a social network? I began to notice it everywhere. I recently read (and watched on TV) Niall Ferguson's "Civilization":
"The printing press and increasingly reliable postal services combined to create an extraordinary network, small by modern standards, but more powerful than anything previously achieved by a community of scholars."
By the way, my wife has a crush on Niall Ferguson, which has to be embarrassing for her if you know her and you're reading this. Please mention it. Back to Steve (I hope I can call him that) Pinker:
"Any 21st-century reader who dips into intellectual history can't help but be impressed by the blogosphere of the 18th. No sooner did a book appear than it would sell out, get reprinted, get translated into half a dozen languages, and spawn a flurry of commentary in pamphlets , correspondence, and additional books. Thinkers like Locke and Newton exchanged tens of thousands of letters; Voltaire alone wrote more than eighteen thousand...unfolded on a scale that by today's standard was glacial - weeks, sometimes even months - but it was rapid enough that ideas could be broached, criticized, amalgamated, refined, and brought to the attention of people in power."
In "Too Big to Know" ("but not too big to blog about") by David Weinberger, we're reminded that "knowledge has always been social", although "it really helped to be a leisured white man."
"In the 18th century, the great Western thinkers constituted what they called a "Republic of Letters", in which they shared their ideas in correspondence, arguing back and forth at the speed of ponies and sailing ships."
You'd have to say that at that pace, trolling can't have been too much of a problem. Only the most dedicated flamer would dash off a baiting letter or two only to spend a couple of weeks waiting by the postbox to read some outraged responses.

But the Daddy, the Ashton Kutcher (who, you will remember, was the first to reach 1,000,000 followers on Twitter) of the Republic of Letters, has to be Charles Darwin. According to the Darwin Correspondence Project website, "Darwin exchanged letters with nearly 2000 people during his lifetime. These range from well known naturalists, thinkers, and public figures, to men and women who would be unknown today were it not for the letters they exchanged with Darwin." On the front page of the site, they have a 'this day in Darwin's postbox'! To use a modern metaphor, they give you access to the Darwin firehose.

Because of the mysterious illness that set in after his Beagle voyage and plagued him for the rest of his life, Darwin more or less exiled himself to Down House, Kent, and became a prominent citizen in the Republic. In fact, you can trace his citizenship in the Republic of Letters back to his round-the-world Beagle voyage, during which he amassed evidence for his theory of natural selection and established a network of scientific and establishment correspondents.

It would be easy, and fun I suppose, to make a trite and unfair comparison between a typical twitter conversation, and some beautifully-crafted exchange between, for example, Darwin and Alfred Russell Wallace, or any two Victorian gentlemen amateur natural philosophers (or "scientists" as they later became known as). Hold them both up to the light and laugh at the quality of what passes for contemporary correspondence compared to the literary standard of luminaries of bygone days. But the quality, whatever you judge it to be, is irrelevant. Not all twitter activity is low quality any more than everyone who wrote to each other using pen and paper was Isaac Newton. Although, in fairness, one thing the old times had going for them was that you didn't get Republic of Letters bots writing badly-phrased epistles to random addresses wanting to share photographs with the bemused recipients.

I find it inspiring to think that, far from being a brand new phenomenon, the urge to join in correspondence with a network of peers is part of an honourable, valued tradition, following in the footsteps of giants like William Herschel, Robert Hooke, Ashton Kutcher, Lady Gaga, and of course Charles Darwin.

Sunday, October 28, 2012

Read Later on Google+

In a nutshell: I use Google+ to solve the 'read later' problem.

Reading things later has become a problem for me. Someone at work emails me a link, following up on a hallway chat about something I'm genuinely interested in and would actually like to read about, but just not now. So I close the email, and the link - unvisited, and now representing unread content - haunts me like a tiny ghost.

Or where my wife, God bless her cotton socks, sends me a link about the place we're thinking about staying in up in Noosaville before Christmas, but right now all I want to do is smash out some JavaScript, and I'll get to that other thing on Saturday morning when I'll be in the mood. Promise.

Or if I'm on the bus, 500 metres before my stop, and I follow a link from a tweet and the article just about loads before I have to alight (love that word) from the bus. The aricle looked interesting, but will languish in a mobile Chrome tab holding pattern unless I do something with it.

Flickr photo
FlickrPiles of books, by NettyA. My Read Later list is building up like the piles at this second hand book shop in Seoul.

Recently, Scott Hanselman wrote an interesting (as ever) piece about pushing what he calls "long-form reading" onto a Kindle for his deferred reading pleasure. The Kindle part is just incidental here: as long as the articles are saved "in a way that will encourage you TO READ THEM!" (his shouting) then that's all that matters. Well, maybe not incidental. I mean, Kindles are obviously designed for reading things, but not particularly for web pages that you're not interested in reading straight away. Instapaper is, though. Same with the "social bookmarking" site Delicious, in a way. So you can cook up an If This Then That recipe to combine your bookmarks with your Kindle automatically, achieving hitherto undreamed-of productivity. As long as at some stage you actually read the articles of course. They have to end up somewhere you're likely to see them. For some people like Scott H, the Kindle is something that they reliably pick up on the weekend, or take with them to the park, on a plane, into the toilet, the bus, anywhere they catch up on their reading. Somewhere away from the desk, where they're relaxed, and ready to absorb content that's longer than a tweet or an email.

But it seems to me there are too many moving parts here. Recipes scare me. They can go wrong. IFTTT no longer works with Twitter, for example, so any recipes cooked up with twitter as an ingredient just got burnt in that particular oven.

There's also something else that stops me from using a Kindle, but that may not affect you. I'm a web developer: I'm actually interested in seeing web pages as they appear in the wild. For that reason I've never been interested in Instapaper, Readability, or any of those things. I don't consider RSS to be like those though - it makes entire sites machine-readable, so RSS gets a pass.

It takes a lot to deter me from a web page: video that plays automatically, without prior warning, is one of those things, by the way.

Google+ Read Later circle

Read Later solved as a Google+ circle

So I see a simpler solution. Use Google+. Almost all content pages have the +1 button by now. The dialog that appears usually allows you to choose which circles you share with, so I just share it with a "Read Later" circle (see the green circle above) which I created to be my private repository of links. It's not really a circle in the conventional sense, since I'm the only one in there. The point is it quietly stashes the links, and I can dial down (red circle) the degree to which these links show in my Home Stream.

Google+ is ultimately just a website, so your saved web content stays on the web. Up where it belongs. When you finally, finally, read the damn article you put aside, you can just delete the post, or more usefully, share it at that stage with the Google+ world. You can even share your whole Read Later circle (blue circle), although that would probably be interpreted as "Hey, here's stuff I haven't read yet, and I'd like to add it to your pile of unread material too :)".

You can also add the official Google +1 Button Chrome extension which shows the full +1 sharing dialog just to be sure. Notice I didn't say "to be sure" twice there. Some sites, like The Guardian, despite having Google+ buttons on their articles, disable the usual dialog, and just show links to their G+ content. And some only allow you to +1 something, that's it, without any of the circling or commenting. But in those cases you can just browse to G+ (I usually have it open in some tab anyway) and slap it in manually.



C'mon Guardian, don't wreck the Google+ pop-up. Let me selectively circle stuff.

And the main reason this all works, the reason this is simple, and I actually remember to read these put-away articles, is because the Google+ client is on both of my Android devices, even on my old iPhone. It's on my main desktop computer, and my work one, in the form of the Google+ website. No extra software required. I don't need the Evernote client, or the Delicious one, or the Instapaper or IFTT one.

Smug? Undoubtedly. Keeping it nice and simple? Yes. Total Google+ fanboy? Oh yes.

Saturday, October 20, 2012

The 21st century belongs to JavaScript

This century is going to belong to the Chinese and to JavaScript. You should learn one or the other. In this post, I look at a good way to get started with JavaScript.

Let's face it, you probably need to give the chaos called your app's JavaScript code some order. If your app is in an entropic state, in a state of high disorder, you need to stabilise it. How can you possibly do that if you don't know any decent JavaScript patterns? You probably want to start using namespacing and modules, for a start. But how can you can do that if you don't know the basics of JavaScript functions?

Reading 'JavaScript Patterns' by Stoyan Stefanov, I realised there's too much stuff in here to remember. Too much. You have to write it down, blog it, or otherwise come up with some way of memorizing the information so that the book is actually useful to you. Obviously, using the patterns themselves in your code is the best way to learn something like this, but unless you have some functions that badly need currying and so on, it can be impractical to just start baking ideas from a book like this into your working code. So where do you start then?

Flickr photo
"DMP-FF005 CHINESE ARMY", by damopabe. The Chinese are going to rock the party hard in the 21st century, everyone knows this.

Functions

The chapter on functions is a good place. Javascript is object-oriented, but without classes, which seems a paradox if you mainly work in C# like I do. So, forget classes, and learn your functions if you want to learn Javascript.
In general, when you think of a function in JavaScript, think of an object, with the only special feature that this object is invokable, meaning it can be executed.
Reading this chapter, I was struck by how many different, but only slightly different, ways there were of doing the same thing: making a function. So how well do you know your Javascript terminology? What's this?
function(){
    alert("Who am I?");
}
That's right, it's a plain ol' function declaration. Specifically, an anonymous function declaration. If you had named it (because, let's face it, it's going to be difficult to use that declaration as it stands) by making the first line function MyFunction(){ then it would be a named function declaration. If you assign the function to a variable,
var myFunction = function(){
    alert("Who am I?");
};
then the whole thing forms a function expression, complete with semi-colon at the end. Since it's still unnamed, you probably know it better as an anonymous function. Now, going back to the first example, the "Who am I?" anonymous function declaration (see how I'm cunningly using repetition to drill the names of these functions, both function declarations and function expressions, into our memories?) seems to be inert and useless, except if you wrap it in () and put a () after it, in which case it stops being useless. In fact, in that case it takes immediate effect because - it should come as no surprise to find out - it becomes an immediate function.
(function(){
    alert("I happen immediately");
})();
What prompted me to pick up 'JavaScript Patterns' (it's actually an ebook but I feel in my heart that you can pick them up just the same) in the first place was the befuddlement I felt on my current project at the absolute effin' proliferation of JavaScript files: 3rd-party behemoths like jQuery and Modernizr, minnows like jQuery File Upload, and our own proprietary code. Cracking open some of the JS that the other guys in my team had written, I realised I had little idea what I was looking at much of the time. Like dark matter and dark energy, there's dark code. Bad neighbourhoods, I call them. Parts of the app you don't want to find yourself in. I mean I could see that there were a bunch of functions in a DateHelper file, for example, all doing sterling work like converting a day to a date and so on, but why they sometimes were created in an object literal, and sometimes using a constructor function I couldn't tell. What's that? Constructor function, you say?
var Thing = function(message){
    this.message = message;
    this.displayMessage = function(){
        alert(this.message);
    };
}
var myThing = new Thing("Note the *new* keyword");
Now, I'm not so artless as to believe that there's always great thought behind every piece of production code, especially - like I say - given that this is after all JavaScript we're talking about. But not knowing, at a high level (is this function part of another object? When does it run?) what you're dealing with puts you at a severe disadvantage. And so I decided on a top-down approach to start with - simply to learn what things looked like. Yes, you should learn everything, but you can't because you don't have enough time. So you have to start somewhere. I have any number of free ebooks available to me nowadays - I suppose most devs do too - but I'm realising that they're all useless unless I read them. And I can't read them all if I read them all.

In this post, I'm avoiding talking about how or why you'd use one type of function over another. Obviously, you can read 'JavaScript Patterns', or any number of books, sites, or posts to learn about that. That skill comes with experience, with recognising patterns, and knowing how and where to apply them. I'm talking about doing what you might do when learning astronomy, chess, or bird-watching. You start off by simply being able to identify the things you're looking at.

Now obviously, when it comes to programming, you're supposed to go deeper than crudely identifying objects based on a superficial recognition of coarse features. But this is Javascript we're talking about, people. No-one learns this stuff. Most "senior" developers I've met in the last few years, people who pride themselves on knowing arcane facts about C# and SQL Server, are just blue-arsed ignorance monkeys when it comes to the natural language of the browser, JavaScript. Why is that? No idea, it just is. They must think it's a "junior" language, beneath their dignity to learn. Who cares? And the usual disclaimer in these cases about including myself in that list applies here too, it should go without saying.

So, it might seem like there's not a lot to learn here - immediate functions, custom constructors vs object literals, a few other slight variations - and indeed there isn't. But without knowing those building blocks, the important patterns that you're going to need to learn soon like callback patterns or using Modules to structure your JS are going to expand away from you quicker than your ability to reign them in, until in the not-too-distant future their light will never be able to reach you, leaving you surrounded by an expanding sphere of obscurity. Much like the fate of this galaxy in fact.

Wednesday, October 3, 2012

You need a spare mobile phone

Don't rely on The Man to hook you up when your mobile phone breaks. The Man don't give a damn.

I had a scare a couple of weeks ago. Let me tell you about it. On Sunday I had to pick up the kids from MacDonald's in the afternoon, so I set off for a pleasant 15-minute jaunt through the bushland between where I live and Logan Rd. Naturally I took my phone with me, a 4-month old HTC One X. I thought I'd catch up on some podcast or other while I walked there. To my consternation however, as I strolled along the path that goes through the Roly Chapman Bushland Reserve I found I couldn't get the phone to turn on. Holding the top button down made it beep and vibrate, but there was no screen activity. By the time I'd crossed the creek and reached Logan Rd. I had to concede that the phone was as dead as a doornail.

Or was it?

Later that night when I had a bit of time to investigate, I discovered to my great excitement that the phone had actually been on and working all the time, but that the backlight/screen was the source of the problem. I could see the icons, etc, ever so faintly, far too weak to be able to actually use in any way. But however it might be possible to describe it as technically working, I was going to have to bring it back to the nearest Optus shop tomorrow.

Flickr photo
"The spare tire", by jmschrei

And so had begun my Period of Inconvenience. Over that weekend I had found out the One X was banjaxed I wouldn't really have used it much, except for a check-in or two in New Farm Park and the Powerhouse on the Sunday afternoon. Now however I was staring into the abyss of a working week without a phone, without a smartphone, and immediately suffered the absence of my usual podcasts on the cycle to and from work. No Guardian Science Weekly, no Skeptics' Guide to the Universe, no This Week in Google. You know, I don't want to sound helpless here but there's a difference between starting your day listening to Alok Jha talk to Craig Venter about artificial life and listening to utes on the freeway.

So, if your phone didn't work, and you got to work, what might you do? Well, you might log in to Gmail, seeing as how you can't access your personal email on your phone, right? But you wouldn't be able to. Know why? Hackers, that's why. Ever since I read Jeff Atwood's great post on email two-factor authentication, I've set Gmail up to send an SMS to my phone whenever I try and log in on an untrusted - read work - computer. Can you see this one coming? On Monday morning I went to log in to my Google account on my work computer only to be challenged by the 2-factor verification code screen. Simultaneously, sitting on my desk like a little blind puppy my HTC phone alerted me to an incoming SMS, one sent all the way from Mountain View, CA, with a 6-digit authentication token. But it just couldn't show it to me. Because it was fucked. Aw barnacles!

Fake it with 2-factor

That's when it hit me just how inconvenient this period of inconvenience could be. I knew I could log on to my Google account at home, but it might not be long before my home computer decided to recycle the 2-factor token it keeps for 30 days, being a trusted computer, and then I'd really be snookered. Nor did I think I could even switch the 2-factor off, since I would surely need to answer an SMS challenge before being able to change it. But actually, it turns out I needn't have worried. You can change it from SMS to a voice call with no interim challenge, after which a nice lady calls you and tells you the code without you having to try and read an SMS. As an aside, this is a handy way of faking an incoming phone call. Just set up voice call 2-factor authentication on your google account, and try to sign in on an untrusted computer. The robot lady will call you and you can proceed to impress listeners with a one-sided conversation (as long as you commit the actual 6-digit code to memory first) saying impressive things like "Two hundred grand? I hardly think so!"

I have to admit to walking in to the Optus store on the mall that lunchtime with an optimism I just hadn't earned. There was simply no reason to expect I'd walk out an hour later with any satisfaction. And sure enough, I didn't. Like an airhead, I thought they'd have a deep and dirty supply of smartphones to choose from while they ministered to my broken HTC. That's if they weren't able to execute some secret button combination and restore life to my moribund phone. Well, they didn't. In fact, the guy's suggestion was to buy an interim phone. That's right: at the same time as they acknowledge that the phone is broken through no fault of your own, they will tell you to buy one if you want a phone for the duration of the repair period. $190 was the cheapest he could offer (smartphone, that is, and they would discount $50 of that). Still, $140 was the going rate that lunchtime for a replacement phone. Did I mention that there was no suggestion that it was in any way my fault that the backlight was defunkt?

Entropy


Flickr photo
"Prof Brian Cox", by Joe Dunckley. I bet he has a spare mobile.

And that's the point of this post - don't throw away your old smartphone. Don't give it to your wife, kid, struggling brother-in-law, a mugger, or your Mum. And don't recycle it for Africans. Keep it - you'll need it. That night, steeped in humility, I rooted out my old iPhone, the one I had given up on because it had begun to slow down somewhat and the battery had begun to run down too quickly. That was the night I got hooked up with LastPass too, since there's nothing like trying to log back in to iTunes after a few months blissful absense to get you into self-harm. So, tip#2: use LastPass.

And that's a clue to the best analogy I can give to what happens if you're like me, someone who uses their phone a lot, and your phone goes out of action for a month. It's like Brian Cox talking about entropy in Namibia - everything goes to crap simply because that's the most likely course of events. Sure, everything could come out golden when something goes wrong with your phone, but entropy dictates that disorder is far more likely. For instance something entropic like, oh, that a day or two after I go to Bali on holiday the repair shop will leave my phone back to the shop, they will phone me, and the message will get buried in my unlistened-to message bank. There are just many more ways that chaos can happen than ways that things can go to plan. You can't change that, it's a law: the second law of thermodynamics, in fact. But you can plan for it, by having a disaster recovery plan in the shape of a spare mobile. Do it.

Saturday, September 8, 2012

Entity Framework Code First Web.config Initialization

Even though as a blogger you often blog code, blogs aren't working code, obviously. A blog post about a particular technology will slowly fade in relevance as time passes and the world moves on. But at the same time if a better way of doing something that you recently wrote about comes along, you'd want to update the post in question, so that's what I'm doing here about EF Code First Migrations, now that we're up to EF 5.0.

In Entity Framework Migrations strategies: the Semi-Automatic I talked about the DbMigrator class to run your migration scripts, invoked from the global.asax on Application_Start() for instance, but that was then: this is now. Or as they say in Perth "Yeah ... nah!". The way you specify the initializer for your DbContext has changed a lot in recent times, exhibiting all the stability of a game of jenga. But since the Jan 12 EF 4.3 Configuration File Settings post from the ADO.Net team, we can all consider ourselves schooled in the state-of-the-art in EF Code First initialization options, and should therefore move the whole show to the nearest config file.

Flickr photo
FlickrTransformers-Movie-Screen-Shots-04, by jalopnik. Web.config Transformer Man

Since EF 4.3 there has been an entityFramework section in the Web.config and as the EF team point out in that blog post you can use this to set a migration strategy. Much better than doing it through the code. Why? Because obviously you may not have the same strategy in your local dev, testing, and production environments. "...if you are using Code First Migrations, you can configure the database to be migrated automatically using the MigrateDatabaseToLatestVersion initializer." Did you get that? There's a new addition to the original 3 initializers included with EF:
  1. CreateDatabaseIfNotExists (default)
  2. DropCreateDatabaseWhenModelChanges
  3. DropCreateDatabaseAlways
  4. MigrateDatabaseToLatestVersion <- now that's what I'm talking about!
You can completely disable initialization too, by simply changing the disableDatabaseInitialization value to "true". You may be nervous about the unintended side-effects of EF Code First on your production database, so it's nice to have an off switch like this. Let's be perfectly honest here - running any sort of initialization option against a live database is not for the faint-hearted.

To get cracking with this new initializer, just associate it with your context in your app's Web.config:
<configuration>
  ...
  <entityFramework>
    <contexts>
      <context type="MyAssembly.MyContext, MyAssembly" disableDatabaseInitialization="false" >
        <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[MyContext, MyAssembly], [MyConfiguration, MyAssembly]], EntityFramework" />
        </context>
      </contexts>
   </entityFramework>
<configuration>
That databaseInitializer type attribute value is just confusing: at least I found myself confused the first time I had to whip one of these up in the web.config, so it might help to think of it as being the same as:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MyConfig>());
The MigrateDatabaseToLatestVersion generic initializer takes two type parameters - "When we create an instance of this initializer we need to specify the context type and the migrations configuration - the migrations configuration is the class that got added to our Migrations folder when we enabled Migrations.", from the Code First Migrations article in the MSDN Data Developer Center - so that's why there's the `2 in the config.

Remember that this new web.config option still requires that you explicitly run through the 'add-migration...' and 'update-database' steps I outlined in my last EF post. The purpose of this post is just to concentrate on moving the old code-based DbMigrator functionality into the web.config, since that sort of thing - your choice of initialization strategy - is perfectly suited to an environmentally configurable setting, much like a service endpoint or email address.

Flickr photo
FlickrTransformers DOTM Deluxe Bumblebee 05, by Gabo440. Transform that Web.config!

Transformers

Right, well, if you are going to use web.config Entity Framework initialization, then you definitely want to use Web.config transformations. They just go together so well. Let's say you have a particular initialization strategy for your local dev environment - DropCreateDatabaseWhenModelChanges, so you can just blow away your database every time it changes, whereupon it gets reseeded with some minimal data. That's what I do. And obviously you want the same thing in production. Only joking. That was a joke. You want MigrateDatabaseToLatestVersion, or maybe you want to switch initialization off completely. So how do you manage the change in the web.config. Manually?

Without going into too much detail, if you're using Visual Studio to deploy your solution then don't do it manually - it's a natural fit to use Web.config transforms. But even if you aren't, I still say it's beneficial to let Visual Studio perform a transform since you can easily create a transform file and preview that transform, and make your actual testing, staging, or production Web.config from that.
"...you can see a preview of the changes in Visual Studio. In Solution Explorer, right-click the transform file (for example, Web.Release.config) and select Preview Transform. Visual Studio shows the original Web.config file and the transformed Web.config file side by side."
So, the following section is part of a transform file I use at work which switches off initialization, both by setting the disableDatabaseInitialization attribute to true on the context, and then for good measure removing the databaseInitializer node itself. The attributes starting with "xdt" belong to the XML-Document-Transform namespace: they do the transforming magic here.
<entityFramework>
  <contexts>
    <context type="MyAssembly.MyContext, MyAssembly" disableDatabaseInitialization="true" xdt:Transform="SetAttributes">
      <databaseInitializer xdt:Transform="Remove"/>
    </context>
  </contexts>
</entityFramework>
I said I wouldn't go into that much detail about config transformations because you could write a whole blog post on the ins and outs of the different types of transformations that are possible. You have to admit, anything that varies by environment ultimately should end up in one or other of your config files, and your choice of EF initialization strategy will surely vary by environment. It's such a natural fit - web.config EF initializers and web.config transformations. They're like Fred Astaire and Ginger Rogers. I really should have used a picture of ol' Fred and Ginge dancing in "Swing Time" to illustrate this point, but I just got carried away with the whole Transformers thing.

Tuesday, August 28, 2012

How do you read a book?

This isn't a rhetorical question. I'm interested in knowing how people read books. I have a feeling that reading is more idiosyncratic that you'd expect.

The more I think about it the more I think that I'm not reading properly. The reason I say this is that for all that my life has changed I still read more or less the way I did when I was a kid or a teenager, picking up a book, reading a few pages, putting it down again, all this several times a day, until about 1 - 4 weeks later I reach the end. Is that the best way to do it? Shouldn't I have a few tricks up my sleeve at this stage, some sophisticated reading techniques?

It's such a fundamental activity, reading. Look, you're doing it now. Such a personal activity, one that surely should be constantly improving as time passes. You will have changed most of your other habits from when you first started reading for pleasure, indeed your life will be barely recognisable from that time. I don't watch TV the way I used to, strumming idly away on the guitar. I don't listen to music the same way I used to, one album from start to finish at a time. But I still go to a shop, buy a book, and sit down and read it more-or-less one page at a time, more-or-less one book at a time.

At least I'm reading

Working in IT you'd think that the vast majority of your colleagues would be bibliophiles, avid readers, bookworms. I used to think that. I don't anymore. I've been shocked over the last few years as I talk to people about books how few do any real reading. Why don't people read? And why do adults read childrens' books and crappy fantasy novels? I've met people older than me who go on like kids about Harry Potter, Lord of the Rings, and Terry Pratchett books. They don't seem embarrassed: it isn't their dirty little secret or anything.

See, I don't count that as reading. There's an argument that says that no matter how trashy or juvenile the material, when people read something "at least they're reading". Ok, once in a while you might want to read something light - I'm reading a cyber-espionage thriller right now that I'm confident isn't going to trouble the Booker prize panel - but not all the time. So, why is it deemed so important to be reading when what you're reading is crap? I don't understand this attitude. No, I call shenanigans on this. Read good stuff, or else go for a bike ride, visit your cousin, or put up some shelves.

Anyway, the upshot of all this is that when I find someone who's interesting in reading half-decent books, I latch on to them to see what I can learn.


Words with friends 1

One thing I like to do is get books off friends. For instance, this guy I used to work with, Dave, mentioned that he had 'Zen and the Art of Motorcycle Maintenance', a book I love and have read a few times. I think it was in the context of 'Hey Eurotrash, you're a reader, you'd like this one'. I couldn't help remarking that it didn't seem to be his sort of thing, and he agreed. He said he hadn't read it, didn't particularly want it, and I must say I thought it'd be nice to have a copy here in Australia so I badgered him to give me his unwanted copy. But when he gave it to me, I was surprised to see a personal dedication on the inside page:

[GoogleBooks]

"Dear David,
Thanks for being the ideal assistant. I hope you get some value out of this book. I look forward to working with you again, and I'm sure you will achieve all your basketball ambitions - with the obvious exception of winning 3pt shootouts against me!"
I began to change my mind about taking it. Dave didn't seem to mind too much and insisted I take it. Still, I felt a bit strange about the book, and pretty quickly passed it on to Karl who I knew was interested in it. Incidentally, the next Lifeline BookFest Karl returned the favour by picking me up a 2nd-hand copy of Shackleton's 'South'. I'm glad I passed 'Zen' on, and the ultimate reward is knowing that Karl enjoyed it - we chatted about it at Friday beers at least once. I borrowed it back briefly to copy that orphaned dedication and give it a home in this post.

Speed reading? Slow down.

"I took a speed reading course and read 'War and Peace' in twenty minutes. It involves Russia."
With all due respect to the sanity of supposed speedreaders, this is a deeply insane business. I'd go further, and say "batshit crazy". So why do I use such strong words? Well, if you're reading a technical, non-fiction, science, or history book you need to pay attention, absorb the details, and let things sink in. If you're reading a fiction book, then you're reading for pleasure so what's the hurry? There, I think I've kinda covered it. The only efficiency gained by "speed-reading" is that you at least get through this waste of time quickly. Science and Woody Allen are skeptical about speed-reading. For me, it falls squarely in the category of 'no free lunch'. Skepdic makes a good point: "Who would want to hire a physician or lawyer who skimmed rather than read his or her texts?"

Doing the slightest little bit of research on speedreading brings up a lot of spammy, testimonial-heavy, unscientific corners of the internet. That doesn't prove anything, it's true. But reading is a bit like talking insofar as it involves words. A person is talking to you, in written form, when you're reading. That's the most commonsense way I can put it.

The book I'm reading at the moment - "Thinking, Fast and Slow" (which is a terrible title for such an important book) is one which I put down all the time to try and make sense of what I've just read. It's a one-book refutation of speedreading. You try reading the chapter "Regression to the Mean" quickly. You have to slowread it.
"Whether undetected or wrongly explained, the phenomenon of regression is strange to the human mind. So strange, indeed, that it was first identified and understood two hundred years after the theory of gravitation and differential calcalus. Furthermore it took one of the best minds of nineteenth-century Britain to make sense of it, and that with great difficulty."
Same with 'The Better Angels of our Nature', 'The Quark and the Jaguar', or indeed 'Zen and the Art...', to pick just a couple of great books you want to read. For me, your approach to reading should be something like progressive resistance with weight training: you should be pumping heavier and heavier ideas as your strength increases, so your toil remains constant over time. Which means you are almost always encountering new ideas, always learning, always surprising yourself. It behoves a chap to stop fiddling and pay attention. You should be reading difficult stuff, whatever level you're at, in relation to the stuff you were reading last year - you know more now, you can take it. Get Wikipedia to 'spot' you.

The underlining question

I'm an underliner. In an attempt to improve my comprehension of sciencey, technical books, I frequently sit down with a pen to hand. You should see my copy of "The Blank Slate". I even went through a note-taking phase recently where I would write out, in the Blogger app on my Xoom tablet, the stuff I would normally underline. The idea was that I would generate the guts of a blog post for each book by default. For example, it helped me write a post about James Gleick. All I'd have to do would be to glue the relevant phrases together around the meaty quotes. The trouble, of course, is that it slows the reading process down too much. Gave it up with the tablet, though I still like to do it with real books, although: "Highlighting and rereading text is among the least effective ways for students to remember the content of what they have read", according to a grumpy scientist in this month's Scientific American.

Words with friends 2

I worked with another Dave, in Executive Building in the CBD. I knew Dave to be a reader because he would come in every day with a scrunched-up copy of The Australian. One day, ol' Dave said he had to buy a new 8-book set of Vintage Classics ('Crime and Punishment', 'The Trial', etc.) because he had lost one of the books in the collection. So, what happens to the old 7, I asked? BANG! Asked for 'em, got 'em. Dave was kind enough to give me his original, now-useless set of classics-minus-one ("To Kill a Mockingbird") which since that fine day sits proudly on my shelf at home. My advice is: take books where you can get them. They will make you a better person. I reread 'All Quiet on the Western Front' and it blew me away again.

The gorilla in the room, reading a Kindle

To wrap up, I haven't even talked here about probably the single biggest recent change in the way we read - ebooks - because I want to write about that separately. I have a very Gen Y friend, Sam, who is aghast that I still read paper books. The tipping of the point with ebooks versus regular books is nigh, certainly in some sections like IT books. Reminds me of 10-12 years ago with MP3s.

But fuck it I still love to sit down with a honking big science hardback, with pictures in the middle, a nice new-book smell - the kind of book that gives you a bookshelf that will impress neighbours and Coles delivery guys. And ah - the buzz of getting the Amazon cardboard box delivery. Not quite the same over Kindle.

So, have you got any interesting insights into the way we read, the way we should or shouldn't be reading? How do you read a book?

Monday, August 20, 2012

Whoops, that IS an error!

Hey come on Blogger, don't suggest to a user that they clear their cache and cookies because your site crashed! That's just rude.


So, because Blogger crashed, you should have to log in anew to Facebook, Amazon, this site, that site, just because Blogger crashed? Naaaah. "Try refreshing the page to see if things are back in order?" Sure, I can do that, that's probably what I would have done anyway. But is it just me or is there a slight whiff of blame emanating from the instruction to "clear" these stale, soiled cookies from your hard drive that you have somehow accumulated that are preventing little old Blogger from doing what it wants to do? Get the fuck outta here!

We're having some problems with users who can't login on the Mater Patient Portal - every site with real people using it will have problems like this - and one suggestion that was made was to suggest to people to clear their browser cache and remove their cookies. Even if this was successful, it's too disruptive to people to do this. It's like hiding their car keys.

I don't know about you, but nowadays I might have a couple of hundred cookies on my hard drive. So I thought I'd check.


That's a lot of cookies.

Look at this small section of the list of cookies I have accumulated in Chrome. This is just part of the google.com cache. Are the other Google teams going to thank the Blogger team for killing the cookies they create? As you can see from the size of the scrollbar in the screenshot, there is a whole jar full of cookies there.

There's nary a site nowadays that doesn't want to personalise your experience when you visit, or in some way track your behaviour. I don't mean track as in snoop or pry, I mean simply to log your visit for their, and possibly your, benefit. Like maybe serving you some half-decent ads. Or saving you from personalising over and over their front page. As you can tell, I have no problem with cookies. I can't stand all this knuckleheaded posturing about cookies abroad today. But that's another blog post.

As well as cookies, you can see there's a lot of "Local storage" items in there. That's HTML5 Web Storage, which can be up to 64Kb per domain, which it seems to me is a shame to just throw away, because ... something happened in Blogger, and ... this might fix it? And Web Storage tends to be treated the same as cookies by browsers, cleared when cookies are cleared. There's even a type of storage in that list called "Database storage", which I'm guessing is actually SQL Database stuff, even though that API is no longer being supported.

Blogger can do a small, discreet, non-intrusive error. I know it can, because here's a nice one I found when I tried to preview my post.


Now, that's what I'm talking about.

Saturday, August 4, 2012

The Page Object pattern for UI tests

Do you do web/UI functional tests in your team? You know, the ones where Selenium, for instance, fires up Firefox, IE, or Chrome, and navigates through the app for all the world like a player piano in an empty room. If so, you want to use the Page Object model.

From the Selenium wiki: "The Page Object pattern represents the screens of your web app as a series of objects." If you're not already conforming to it, you will eventually stumble upon this pattern. So you may as well stride purposefully towards it. Ultimately, the best way to see the benefits of using it is to do UI tests using the Stupid pattern first, which we did in my team. That's the pattern where you have hard-coded strings, button ids, and ad-hoc ways of getting from one screen to another right in your test methods. About as DRY as Sea World. Test code should be treated like regular code, and you wouldn't ordinarily write your app's code in such a procedural, slapdash way.

I can proudly stand up and say that all of the pages in my current project are represented as Page Objects. Every single one. All right then, they aren't - but they're in the process of being converted to being Page Objects as I write this.

So - what's a Page Object? In our case, it's an abstract class containing (among other things) a constructor:
protected PageObject(SeleniumBase browser)
{
    if (browser == null)
        throw new ArgumentNullException("browser");
    Browser = browser;
}
with some methods like this (using the actual model classes from our main app):
public DestinationPage SubmitTheForm(FormModel model)
{
    // boilerplate Selenium code to find form elements, fill them with model data, and submit the form
    return NavigateTo<DestinationPage>(By.Classname(".submitButton"));
}
made possible by this beautiful generic base class method:
protected TDestinationPage NavigateTo(By clickDestination)
where TDestinationPage : PageObject
{
    Navigate(clickDestination);
    return (TDestinationPage) Activator.CreateInstance(typeof (TDestinationPage), Browser);
}
[Photo of a water mill]

This method is the ball bearing, the engine, nay - the water mill of our functional tests suite. It keeps things moving. It does the important work of clicking a link or a button, or some sort of page navigation element (Navigate()), then dutifully completes the corresponding paperwork by newing up (Activator.CreateInstance()) an instance of the type passed in to it, so you can chain methods in a meaningful expression like:
HelpPage page =
Site.BrowseTo(HomePage).GoToLogonPage().LogOn().GoToHelpPage();

Chaining

As you can see, this NavigateTo method allows for method-chaining. This "fluent" approach reminds me of Linq expressions or jQuery methods which are the ways I became familiar with chaining. "Methods on the PageObject should return other Page Objects" says the Selenium docs. I also find it useful to have other properties on the Page Object simply returning strings that I expect to find on the page to prove the state of the page, for instance that there is a particular message showing. But generally speaking, Page Object methods return Page Objects.

I was speaking to Bradley@Readify about all this chaining, and he cautioned against violating the Law of Demeter (or as Martin Fowler calls it, "the Occasionally Useful Suggestion of Demeter") in situations like this. I think though as developers we're conditioned to see all those dots as Demeter territory, whereas in this case there's no actual composition denoted by the dots. Of course, Brad knew this. He was just sayin'.

A fork in the road

Sometimes a Page Object method may result in two different paths being taken, depending on an input parameter, for instance an answer which may be right or wrong. In the Selenium wiki they suggest explicitly creating methods to handle this approach, but I prefer to use generic methods. I'll show you what I mean. Starting with this test:
this.Given(_ => GivenMyPasswordIsReset())
    .When(_ => WhenIChangePassword(_resetPassword), "When I use my old password")
    .Then(_ => ThenIShouldBePromptedToChangeMyPassword())
    .And(_ => AndIShouldSeeAWarningAboutUsingTheSamePassword())
    .BDDfy();
I call this helper method within the test itself (because I have another test where I do more or less the same thing except that I use a new password):
void WhenIChangePasswordTo(string password) where TPage : Page
{
    HomePage.GoToLogonPage().LogonAndChangePassword(_user, password);
}
which in turn calls this, in the LogonPage Page Object:
public TPage LogonAndChangePassword(User user, string newPassword) where TPage : Page
{
    return LogonAndChangePassword(user).ChangePassword(user, newPassword);
}
This can result in the user being successfully directed to the home page, or the Change Password page, depending on whether they use the old or new password. I don't see that there's any difference in terms of the responsibilities of the cleint test class and the Page Object. Sure the test class dictates what page it expects to be returned to, by means of the type (e.g. ChangePasswordPage) that it passes the Page Object, but in the case sugested by the Selenium wiki, it has to explicitly call a method called LogonAndChangePasswordWithOldPassword(), or such like. Generics win, I think.

Chunking

When we invoke a method on the Page Object like Logon(), we're chunking - treating a bunch of things at one level as if they were one thing on a higher level. On one level you might have instructions like "fill in the username field, fill in the password field, and press submit". On a higher level you would have "log on". We can ignore the internal structure of the lower level operation. In the same way, you can have a chunked operation of chunked operations on the Page Object.

Say you have a path that's commonly taken through your app, for example one where a user goes to the home page, logs on, and checks their messages, then you might want to chunk those operations into one aggregate one for convenience. That chunking should obviously happen on the test class itself, because it doesn't make much sense to have a MessagesPage object have to concern itself with the details, however high-level they may be, of logging on.
_messagesPage = HomePage.GoToLogonPage().Logon(user).GoToMessagesPage();
can become
_messagesPage = CheckMessages();
as long as CheckMessages() returns a MessagesPage object. This is all rather obvious I'm sure, but it's interesting to think about the movement up and down the levels you have to do when composing a test with a Page Object.

Also, even though you can new up a new MessagesPage() in each of these cases instead of reusing _messagesPage in consecutive methods, it goes against the spirit of the test which is to simulate moving through the app by getting from one page to another. Unless you're saving state on the page as you go, I guess it doesn't really matter, but reusing the variable is a truer representation of what's happening in the browser: the user gets to a page, then clicks on a link in that page to go to another one - it's the same page they entered and exited.

The wrap-up

The Page Object pattern allows us to do two things mainly:

1) Encapsulate the low-level "internals" of the page - the ids of the buttons, classes of elements, etc. that we want to click on, find, assert are visible, do anything with. Page Objects "should seldom expose the underlying WebDriver instance."
2) And generally, make the client (of the Page Object) test methods more elegant by taking them to a higher level.

Thinking in higher levels is what distinguishes chess masters from chess chumps like me. I'm crap at chess, I should point out. Couldn't beat Ricey, couldn't beat Nagy. But it remains fascinating to me. Grandmasters don't analyze the game by thinking ahead more moves than you or I, but rather by seeing the game at a higher level than you or I would.
Intelligence depends crucially on the ability to create high-level descriptions of complex arrays, such as chess boards, television screens, printed pages, or paintings.
from "Gödel, Escher, Bach: an Eternal Golden Braid" by Douglas Hofstadter

Tuesday, July 24, 2012

Speeding things up with HTML5 Web Storage

Cache stuff in Javascript using Modernizr and the HTML5 API. And pronounce cache correctly.

On my brother Gavin's gallery website that I'm working on there's a sidebar which fetches a list of photo sets. Standard stuff. You choose a set and it loads a page with the querystring value of the set's id. It's an oldish WebForms site that I've been doing the jQuery and Web API business on.

I use a Web API project to fetch the list of sets from a Flickr account which Gav has set up, where each group of paintings ("available work", "small paintings in oil") is represented as a set of Flickr photos. It's a double hop: the website hits my Web API project, which hits the Flickr API. And as you can imagine, the list of sets doesn't change that often. So you can probably see this one coming from a looong way down the road. Anyway, in case you can't, here it is. Ready? I thought I'd cache the results.

But not in the .Net code. Because I'm asking for the data in the jQuery ajax() method, and pumping it to the screen on the .done() callback, I thought I'd test use the new (to me anyway) HTML5 Storage feature. It's seems like a good way to cache a small amount of data that is unlikely to change from page to page within the same session, and which is probably going to be pointless, or worse, fetching every single page load.


As a digression, it's weird the way here in Australia devs are wont to pronounce "cache" as "cay-che", not "cash". I grew up in Ireland where one of the stock phrases that you heard during the 80's was "arms cache", as in the British army found one in Northern Ireland, and said "cash", not "cayche". On podcasts and tech shows I only ever hear them say "cash". I spoke to Noel about this when I was back in Ireland a while ago. His wife's a Québécoise, a fluent French speaker, and la belle Catherine pointed out that the English word cache comes from the French word cacher: to hide away, store - and the root of that word is pronounced "cash". The French are losing enough words to internet English as it is - I think we should respect the words we owe to them by honouring the Gallic pronunciation appropriately where we can - just sayin'.

Framework à la carte

Anyway, I've become fascinated with Modernizr of late. I even like the pink fade on their website, the sort of styling that would normally be anathema to me. I can't work out what the logo means - the steps with a quarter circle - but to my great delight it animates when you mouse over it. And I love the way they make you choose what you need before downloading the library. It forces you to pay attention to what you're doing. These days, there are so many Javascript frameworks, plug-ins, and UI helpers, etc. that you can drown in different versions of slightly different libraries on your site. When stuff is free, you just take as much as you can get, I've found, so it's salutary for once to have to go through a list and pick what you need.

Since for the time being I'm only interested in that sessionStorage feature of HTML5, I can get a pretty pared-down version of Modernizr. My custom build amounts to a supermodel-skinny 9kb! This enforced customisation with Modernizr is because of the heterogeneity of HTML5. You are only likely to be interested in checking for the ability of your visitors' browsers to do a few particular things, so why download an exhaustive framework to cover every nook and cranny of the HTML5 features list?

It's code time. In GetSets() I check two things: first, does the user have a half-decent browser? In other words Internet Explorer 8+, Firefox, Opera, Chrome, or Safari? Those browsers all support HTML5 Web Storage. If they do, then see if they have already retrieved the data:
if (Modernizr.sessionstorage && sessionStorage['GLSets'])
If they don't have either, call out to the Web API url to get the sets from Flickr.
GetSets: function () {
        var self = this;

        // retrieve sets from local storage if already cached
        if (Modernizr.sessionstorage && sessionStorage['GLSets'])
            self.ShowSets(sessionStorage['GLSets']);
        else {
            var url = common.BaseUrl + "api/lavelleartgallery/sets?user=" + common.GLFlickrId;
            $.ajax({
                dataType: "jsonp",
                url: url
            })
            .done(function (data) {
                // cache sets in local storage
                if (Modernizr.sessionstorage)
                    sessionStorage['GLSets'] = JSON.stringify(data);

                self.ShowSets(sessionStorage['GLSets']);
            })
            .fail(function (jqXHR, textStatus, errorThrown) {
                // oops!;
            });
        }
    },

ShowSets: function (data) {
        var sets = JSON.parse(data);
        var listOfWorks = $('<ul></ul>');
        $.each(sets, function () {
            var set = {
                id: this.Id,
                name: this.Name,
                numberOfWorks: this.NumberOfPhotos
            };
            listOfWorks.append('<li><a href=\"Set.aspx?id=' + set.id + '\">' + set.name + ' (' + set.numberOfWorks + ')</a></li>');
        });
        $("#Sets").html(listOfWorks);
    }
And as soon as we get the data from Flickr (the .done() callback), stash it in the cache if we can. You'll notice that you have to serialize and deserialize the array of sets to set and get it from sessionStorage. That's because sessionStorage and localStorage only support strings.

Dive into HTML5 Web Storage

You might be thinking to yourself - I could have just saved this as a cookie if I wanted to avail of client side storage. In which case I refer you to the mysterious Mark Pilgrim's erudite "Dive into HTML5" book/website. If you read the chapter on Web Storage, you'll see a couple of ways in which the new Web Storage distinguishes itself from cookies: the data is not sent to and from the server on every request despite persisting beyond page refreshes.

This is all very handy, and browsing GavinLavelle.com, I can see a great improvement in the page load speed - the sets sidebar has no lag whatsoever, but - and it's a big one - the cache expires at the end of the session. I want to upgrade my HTML5 Web Storage to business class. I want to give it a bigger seat and more legroom. I want it to last as long as the data it's caching is current. That could end up being quite tricky. But there is no reliable way to expire localStorage - the counterpart to sessionStorage - as it just sits around for a long time apparently, so you have to come up with some expiration/refreshing strategy if you want to use it.