Rothfuss and Le Guin

I recently went through why I don’t like Rothfuss’s style and noted a disconnect between what I saw as clumsy wording and pained metaphors, and the glowing reviews from bloggers and published fantasy authors alike.

Are these people on crack, or am I missing something?

Shortly after posting I discovered that Ursula Le Guin has written

It is a rare and great pleasure to find a fantasist writing not only with the kind of accuracy of language absolutely essential to fantasy-making, but with real music in the words as well. Wherever Pat Rothfuss goes with the big story that begins with The Name of the Wind, he’ll carry us with him as a good singer carries us through a song.

This really worries me. Le Guin is an amazing writer, of real stylistic skill and poetry, and if she finds something to like in his work, then I really have to consider that, perhaps, I actually am missing something. I could agree with her that he has “real music” in his words, but the comment on precision is exactly what the exerpts I posted about would seem to me to contradict.

I did, briefly, worry that, even if Le Guin isn’t “on crack”, as I put it, she might not be as sharp a writer and thinker as she used to be. Thankfully, the BBC’s interview podcast with her (28th Jan 2011, available till late Feb) has put paid to that unfair suspicion. Aged 81, she is sympathetic, sharp, a resolute defender of genre writing, and great fun. Long may she continue writing!

Some notes on style in Patrick Rothfuss’s The Name of the Wind

I’m attempting to read Patrick Rothfuss’s The Name of the Wind for the
Liverpool One Science Fiction and Fantasy Bookclub.

I’m finding it hardgoing. Perhaps some quotes from the text will help clarify why.

He pulled more beer for Jake, Shep, and Old Cob, moving with an air of bustling efficiency.

There’s a general overuse of “bustling” to describe a) any scene with a pub, and especially b) how good Kvothe is at running a pub. (The phrase reminds me, for some reason, of Dan Brown’s “moved briskly about” as dissected neatly by LanguageLog.)

Old Cob tucked away his bowl of stew with the predatory efficiency of a lifetime bachelor.

Here’s some more “efficiency” on the other hand. I quite like the idea of “predatory efficiency” though I’m not sure it applies so well to a lifetime bachelor’s attitude to stew. “Mercenary efficiency” might work better – presumably he normally pays for the stews, as opposed to hunting them down.

One at a time, Kote wiped their bottoms clean of the strawberry wine and set them on the bar between himself and Chronicler, as if they might defend him.

I’m really worried about “wiped their bottoms”: I just don’t understand if it’s deliberately jarring, or just careless, I’m assuming the latter. I don’t understand what the metaphor of defence means either: the Chronicler is unarmed, and not a threat.

For a moment fierce longing and regret warred across his face.

Then they were gone, replaced by the weary face of an innkeeper[...]

replaced” is very odd: it’s the same face, just without the emotions waging battle across his face. And why “an innkeeper”? It’s the same innkeeper whose face Kote was wearing before his emotions declared war on each other. On his face.

Kvothe had stopped speaking, and while he seemed to be staring down at his folded hands, in reality his eyes were far away.

In reality, they were still in his head.

There was a fleshy thump followed by a slightly pained chortle in my father’s baritone.

Is this a eupehemism for Kvothe’s mother having just kicked the father in the testicles?

She was a widow, fairly wealthy, fairly young, and to my inexperienced eyes, fairly attractive. The official story was that she needed someone to tutor her young son. However, anyone who saw the two of them walking together knew the truth behind that story.

“Official” is a weak, bureaucratic word. Worse, this paragraph makes no sense at all: what does “the two of them” mean? After some parsing, you realise that this is the widow plus the character mentioned in the previous paragraph.

“Semantics,” she shrugged.

People in pre-technological societies are always using Eng.Lit. terminology as putdowns.

Several oddly structured sentences make me wonder whether he had an editor…

My mother swatted him, then caught one of his hands in her own and unfolded it for Ben to see.

Her own hand? Or his?

He brought an earthenware jug up from underneath the bar, then set it on the bar with a hollow sound.

The hollow sound though comes from the jug, not from his action.

And there are continuous strange metaphors that could be poetic, in that they’re surprising and vivid. But good poetry has metaphors that are strange but somehow, viscerally, true despite (or even better) because of that strangeness. So consider:

His eyes were wild around the edges, like a skittish horse.

What did his eyes look like? Were they likely to rear up out of their sockets (perhaps in order to be far away in reality?) Or does it mean that he‘s metonymically skittish? Or that his eyes are like horse’s eyes? Are they only wild around the edges (i.e. red? Or fluttering with nerves/lack of sleep?)

a sword in its pure form. It was slender and graceful. It was deadly as a sharp stone beneath swift water.

This is a really interesting one. A sharp stone is deadly if you hit someone with it of course, but under swift water suggests instead slipping in a river and cracking your head on the stone. Accidental drowning is certainly deadly, but it is of course accidental, without agency, in exactly the way that a sword isn’t.

The man had true-red hair, red as flame. His eyes were dark and distant, and he moved with the subtle certainty that comes from knowing many things.

That’s a beautiful phrase. But does it mean anything? How many things do you need to know before you can move with a subtle certainty? Which things? Surely “how to move with subtle certainty” would be just one thing. Precision in movement could alternatively come from martial arts, or dance, or theatre. Possibly from many of those, but maybe not. And he could know arbitrarily many things of other types (accountancy, botany, the anthropology of chimpanzee troupes, …) without this affecting how he moved at all.

I suspect that the opening prologue is meant to be poetic, and has been worked on to that purpose. It doesn’t work for me though:

It was night again. The Waystone Inn lay in silence, and it was a silence of three parts.

Starting the novel with “It was night again” suggests that a major theme would be the cyclical nature of time, moving between day and night. If that’s the case, then this is nicely poetic. I haven’t yet seen any evidence for that, so I’ll reserve judgement.

The “silence of three parts” sounds like it’s meant to be clever, rather than actually being clever.

But never mind the prologue, what about the publisher’s blurb?

I have stolen princesses back from sleeping barrow kings. I burned down the town of Trebon. I have spent the night with Felurian and left with both my sanity and my life. I was expelled from the University at a younger age than most people are allowed in. I tread paths by moonlight that others fear to speak of during day. I have talked to Gods, loved women, and written songs that make the minstrels weep.

You may have heard of me.

The “I was expelled from University” slightly disrupts the portentous epic boasting, making it sound more like petulant student boasting. Then some precocious boasting about how clever he was to get in so young.

But what’s “You may have heard of me” doing? (Apart from breaking up the boasting with some false modesty, I mean.) In the context of the story, he’s telling this to an audience who already knows who he is. This might be explained by the fact that he’s not actually telling the story to the scribe. Though the scribe is himself a storyteller, (or the Chronicler) he’s not allowed to tell the story himself. Instead, Kvothe has the hubris to co-opt the poor scribe as a mere human dictaphone. Oh, and he’s going to check up on him too, to make sure he doesn’t dare edit the story, because he just taught himself shorthand in 20 minutes.

While we’re on the subject, you’d best not forget the stern reminder that he didn’t just grow up with a family of traveling minstrels! Oh no! He grew up with the Edema Ruh. Who are a family of traveling minstrels.

Apparently some people like the writing style:

prose is absurdly stunning, the type that makes me cry at its sheer beauty. (thebooksmugglers)

the sometimes ambiguous lines between poetry and prose begin to blur. (reviewstream)

Are these people on crack, or am I missing something? ;-)

I know what I did last summer: YAPC::EU::2010 Pisa

So, on the train down to LPW, I came across my notes from this summer about YAPC::EU::2010, my 6th YAPC, and the first that I’ve helped with as an orga ;-)

  • The general trend of YAPCs is to build on the successes of previous years, push the standard higher in some aspects, and to make a few new mistakes along the way, just to mix things up a little ;-) I don’t think we broke this trend.
  • Having a distributed orga-team isn’t impossible.
    • Last year, cog managed with nobody actually resident in Lisbon.
    • This year, we lost several key orgas, and much of the rest of the local contingent emigrated to UK, Spain, Holland, Austria, … distributed teams work very well for some things: getting sponsorship and drafting advertising copy can actively benefit from an international perspective, and bikeshedding^Wcollaboratively editing using git/googledocs/typewithme and IRC is fine.
    • But you do need some people in the same country (and ideally city) as the conference.  To do things like visit the venue and restaurant, chase up local suppliers, arrange deliveries etc.  Peppe++
  • Starting the conference at 10am may have been the best decision we made. (And dakkar++ for a great schedule all round).
  • Getting wifi for 300 geeks isn’t easy.
    • The option we provided worked pretty well, as soon as Devitalia (who we’d repeatedly told to expect 300 geeks) realised that we really meant it.
  • Catering is expensive. But it’s worthwhile, and I think we got good value for the money, as the lunches and coffees were excellent. If you want to save money on catering, then make sure you either
    • have a venue in town so that people can eat lunch wherever they want to (but then have a 2hr lunch) or
    • have a university or similar venue that will let you buy in crates of sandwiches.
  • Because we were out of town, we felt we should organize shuttle buses.
    • These worked really well. And at least 2 people understood peppe’s ravings about it.
  • The t-shirts were great! oha’s girlfriend Micaela designed the lovely Leonardo’s Onion logo, and ludan arranged printing and delivered them in his car (a big car, but rammed full of boxes even so).
  • Video recording is hard.
    • We tried (via news items on the site and mailing list) to suggest that
      • people should record screencasts, which a few people did (Reini Urban and Tim Bunce that I’m aware of) and
      • to ask for volunteers.
    • We did get some loans of video cameras (from mst@shadowcat, Ranguard@foxtons, Wendy@dijkmat, and Dirk@ModuleBuilder, which was fantastic. Dakkar mostly babysat the cameras, with Emiliano Bruni working as cameraman for the auditorium. But with one camera per room, mostly static, and mostly unmanned (e.g. for monitoring audio/video quality) the results are very much “best endeavours”. Peppe has worked heroically to upload all the footage that’s usable from this, but a lot of people (us included) have wondered how it could be improved. I think
    • what’s there is nice as a community artefact, to prove that there were interesting talks, and as a reminder of what happened. It may be that it’s worth doing it at this level just for those reasons.
    • if we wanted anything more slick, for example, to distribute outside the community, then we could do with
      • professional recording/editing. This costs a fortune. Sponsors who wish to facilitate this for future conferences would be welcomed gratefully, I suspect.
      • volunteers with experience of lighting/sound-recording/video-recording/editing.
    • I wonder if it would be better for a team of 2-3 people to record just one track every day, with multiple cameras, rather than attempt every talk?
    • I think that, without such sponsorship/volunteers, it would be entirely acceptable to not video YAPC at all.
    • As the orga-in-chief for ::EU::2011 is Andy Shitov, who masterminded yapc.tv, I’m sure he will have ideas/resources to make this one of the things that he raises the standard of ;-)
  • Running an auction is hard. This was the one thing that I attempted to run, and it was interesting, though not entirely successful. Many people had suggested that the auction was overlong usually, and we thought of doing it as “Lightning Auctions” with guest auctioneers. This was refined into a competition, which we thought would be fun, as the auctioneers competed, by any means possible, to raise the most money.
    • Not having an experienced auctioneer available is a disadvantage.
      • BUT… the auctioneers we did get though were fantastic! Dave Rolsky and brian d foy worked really well together. Matt Trout and Dave Cross were excellent, and we were really lucky to be able to team up the legendary Josette Garcia from O’Reilly with Michel Rodriguez to make the most bizarrely European team possible!
    • having a compere (dakkar), treasurer (arthas), and a gavel^Wgong banger (R Geoff Avery) was, I think, a good idea
      • BUT… I hadn’t had/made time to do a rehearsal, and I hadn’t made sure the roles were entirely clear. At one point Geoff asked me if he could time out an (overrunning) lot, and I realised I’d just assumed he’d do it because he was the “lightning talks guy”…
    • The runners didn’t know what they were supposed to do.  Oops.
    • I hadn’t stage managed how the paths (runners -> lots -> auctioneers -> purchasers; purchasers -> cash-desk; auctioneer switch-over) would work, so things got clogged up.
    • Organizing the lots, and having slides with photos etc. was a good idea. It also helped as we could run these through with the auctioneers, so they were familiar with the lots beforehand.
      • BUT… should have done this sooner, to be able to let bidders (attending, or remote) know what there was to bid for in advance.
    • Minimizing the number of lots was mostly a good idea.
      • AND… getting rid of most of the “low value” items via silent auction worked really well
      • BUT… having no low value items at all meant that many casual attendees (who weren’t going to spend £400 on a t-shirt) couldn’t bid at all, and perhaps didn’t feel involved
    • The element of competition was fun
      • BUT… had unintended consequences. Instead of deciding that a particular lot wasn’t selling and just calling it, auctioneers would drag things out to extract every last euro. (This was also partly due to the small number of high-ish value items).
      • (Of course, this made us more money in the end, at the expense of having a 2-hour auction, as per usual, instead of the short, sharp one we’d planned)
    • Team bids are fun
      • BUT… entirely confusing. It might be better to insist that team bids are made only by a single figurehead. Anyone else would have to go through them.
    • All in all, I think it was an interesting experiment, and I’ll be interested to see if any of the elements that worked get reused and built on for future conferences!
  • I hadn’t been going to give a talk, but at some point, chatting on irc we decided that someone should write a Renaissance sonnet in honour of peppe, for all his hard work.
    • This somehow metamorphosed into a lightning talk about, among other things, Renaissance love poetry and time travel.
    • Me and larsen++ developed the talk, he made the slides almost impossibly beautiful in Keynote and photoshop.  I presented. It worked really well.
    • We got some lovely comments in the evaluation, but I particularly loved that
      • I got high ratings for “Speaker’s knowledge of the subject” (not clear if that’s the poetry or the time travel)
      • this pair of answers:
        • Q: What worked well? A: It all made sense at the time
        • Q: What could be improved?  A: I need a time machine to go back then and make it make sense again
  • The trip to Florence was fun! But I’m not going to give up my day job to become a tour guide any time soon ;-) In general, the Friends and Family programme that arthas put on worked really well, and had great feedback.

The complexity of Italian tax law means that we’re not able to discuss the finances in any detail till year end but… with the information we do have, we can say that we more than broke even, yay!  We’ve already been able to contribute back to the grassroots Perl community by donating some of the surplus to YAPC::EU::2011 in Riga, and to YEF — there’ll be an official announcement of that soon, but I’m just delighted that we (by which I mean in particular our treasurer Michele, and the Budget-focused Peppe,) were able to make the conference economically viable in the middle of a global recession.  This in itself was, of course, only made possible by the generosity of our sponsors, and the commitment of the attendees who spent their (or their companies’) time and money to turn up and make the conference happen.

So, that’s the end of my tardy YAPC wrap-up except for the question: would I do it again? Well, in the immortal words of the comedy dance/”song” routine:

MOAR! MOAR! MOAR!

Oyster at the NWE.pm Hackday (pt2)

Continuing the writeup of the recent NorthWestEngland.pm hackday (Part 1):

Server

We’d originally assumed that the main backend would be EC2, purely because it seems to have more mindshare currently (for example, the opensource initiatives around Eucalyptus and OpenStack seem to be targeting the EC2 API as a de facto standard). However Marco Fontani (who has recently set up Glasgow perlmongers, and herded a group of 3 all the way down to Lancaster, yay!) has already published Net::RackSpace::CloudServers to CPAN and was keen on targeting this. He and Iain worked on the Rackspace backend for Oyster, while Carl (fade) and Ian Norton (idn) looked at the EC2 backend. The 2 backends work rather differently from each other: while in the case of EC2, we just have to inflate a stored image (AMI) that’s stored on Amazon’s S3 storage service, for Rackspace, it seems that we have a limited choice of prepared images, and then have to build a server from that.

The commonality of course is a routine that, from a fairly standard (Debian or similar) image, creates a base Oyster image. This will either:

  • be stored as an AMI for inflation into EC2
  • OR be run when a machine is provisioned into Rackspace.

The Rackspace backend is slightly more advanced, though both are now capable (sometimes with a bit of manual kicking required) of getting launched from the client. Next step is to get them exposing the hooks required by the Deployment team!

State, and configuration

One of the interesting things about splitting up into the 3 teams is how (at best) this could help us maintain encapsulation. We had a bit of discussion where the Server team would have liked us in the Client team to pass on the information from the command line to them, let them write information back to our config file, or require us to maintain state. Though they make some good and interesting points, I think it’s a good idea to at least be wary of confusing the concerns of these 2 areas, and I think we’ve made the right decision to defer any strong coupling between the areas at least for now. (For example, configuration files might be entirely irrelevant, in the case where the server is being launched by a script, or via the planned managed Oyster web-service.)

Deployment

Miles (pozorvlak, another of the Glesga boys), Graeme (grim), and Paul (bluefoo) worked on this, and specified that we will, for now, do deployment via push to git. This is also the technique that Heroku, a massive influence on Oyster, appear to do use. While this is great for an entirely managed service, there was some discussion about whether it was the right approach for us – for example, if someone chooses to plug in a managed git service, such as github, there may be limits on how we can incorporate git hooks. But as the team have real interest and experience with git, it makes loads of sense to do it like this for now, and we can always look at extracting the relevant code into (for example) Subversion hooks, or a standalone script at a later date! Matt also suggested that the deployment should honour the Perl de facto standard of a tarball as the “unit of deployment”.

I think we were all unclear about how deployment would work, which led to some frustration – discussion/post-mortems welcome!

Marketing, testing, documentation

Lateef, also from Glasgow, and Gabi (gabimuc) who had made it all the way from Germany, worked on testing and documentation. I didn’t pay nearly enough attention to what they were doing (bad osfameron!), and I do think I personally squandered them as a valuable resource for the day. (Possibly falling into the “but it’s too early to test/document things” trap) I’d love to get a writeup of experience from them to learn how better to incorporate their skillset into future hackdays.

That said, their help was already incredibly helpful!: several times, gabimuc tried to follow our documented API and pasted error traces, which helped us debug our assumptions and documentation. I think it might have been even more useful to have her and Lateef moving around the teams, testing and discussing assumptions and design throughout? Discussion welcome on how to improve this for next time!

Mark also did some nice work on thinking up an Oyster logo, currently work in progress. The marketing of the project will really kick in at some point, and I’m sure we’d appreciate new contributions for artwork/copywriting too.

Next steps

The next main step is to get, by hook or by crook, a “hello world” type app running on one of the backends (this could be a Catalyst app, or a simple Plack/Mojolicious one), the benefit of which would be in a) proving that the components work together, and b) to get the boost of “look, something worked!” which we just missed at the hackday itself ;-)

I’ll be presenting a talk summarising Oyster and its current status at London Perl Workshop 2010 this coming Saturday. Hope to see you there!

Oyster at the NWE.pm Hackday (pt1)

Mark Keating has already blogged in detail about the NorthWestEngland.pm Hackday 2010 from a social & logistic point of view, and I’ll just agree here that it was indeed awesome in the true sense of the world!

Instead, I’d like to wrap up some detail about Oyster itself, the project that about a dozen of us (the majority of the physical attendees) worked on.

Goal for the day

Our rough goal was to be able to provision a simple webapp (a “Hello World”) onto one of the Cloud backends. We didn’t quite make this, but we did create many of the pieces required.

Project resources

  • wikipage linking to pages on tasks, roadmap, APIs etc.
  • an IRC chat channel. #oyster on irc.perl.org
  • no mailing list yet. For now, use the NWE.pm one if required…
  • a git repo p5sagit@git.shadowcat.co.uk:Oyster.git. Nopaste your ssh public key on #oyster to get push access.
  • I’m also pushing to github

Client

Me, Rob (el_bandido), and Mark (n0b0dy) worked on this. Our user story is that we’d be able to:

$ oyster new My-App        # creates a new Oyster/Catalyst project
# edit code
$ git commit
$ oyster provision test      # creates a server called "test"
$ git push oyster-test       # deploy to the server provisioned above

Because one of our goals was to reuse the good work in specifying Modern Perl development tools in Task::Kensho, we started off trying to use Dist::Zilla as the interface for the above.

Advantages of Dist::Zilla

  • plugin oriented: already has plugins to do things like
    • check dependencies
    • commit to git
    • scp tarballs
    • create new commands
  • Actively developed
  • Moosey

Disadvantages of Dist::Zilla

  • Being a complex, highly factored Moose project, it’s hard to find where functionality, or datastructure declaration is actually implemented
  • … and therefore correspondingly difficult to implement, say, a new command, or way of gathering config
  • … the documentation is excellent for users wanting to use Dzil for its current purpose. But less so for people like us wanting to abuse it to do slightly different things. (I suspect that we would now be ready to hit IRC #moose to get support and perhaps contribute back to the docs as we do so).
  • As Matt pointed out, most Catalyst projects are not using Dzil, but rather Module::Install. Using Dzil might be a little niche?
  • For provisioning servers, we really need a multi-level configuration.
    {
       test => {
          username => ...
          password => ...
       },
       live => {
           ...
       }
    }

    But it really seems that Dzil expectes an ini file for everything. We kludged this by having a separate oyster config file using Config::General.

We’re currently considering whether to persevere with Dist::Zilla, or move to something simpler like App::Cmd, stealing modules, ideas, and code from Dzil as appropriate ;-)

Coming up in part 2

I’ll summarize the work on

  • the Backend cloud servers
  • the deployment phase
  • documentation, testing, and marketing

NorthWestEngland.pm hackday on Saturday! (20th November 2010, Lancaster)

So, we’re gearing up for the NWE.pm Hackday (wiki)! We’ll be mostly working on the following projects:

  • Oyster: “an incubator for perls in the cloud” (roadmap) (tasks). This is the project I proposed, and I’m very excited (and very very scared!) about it.
  • Ironman (Last year’s main Hackday project, ably herded by Ian Norton and co.)
  • Presenting Perl, a website for Perl video, slides, and much more. (roadmap) (tasks)

Look forward to seeing lots of old and new faces: as well as the usual NorthWest UK crowd, people are traveling from Germany, Edinburgh, Glasgow (and possibly other places!) We’ll also be open for business remotely, on IRC at irc.perl.org’s #northwestengland.pm channel. See you there!

Oyster Project – write an open-source tool for instant webapp provisioning/deployment to the cloud in one day… why aim so low?

Yesterday, I submitted Oyster as a possible project for the northwestengland.pm Hackday. Last year, the team built Planet Ironman, an aggregator for Perl bloggers. As well as the several man-days of work during the hackday itself, the group then ran with the project for the next year. NWE.pm are a really smart bunch of guys, so getting that kind of quality attention to a new opensource project would be a great prize! So I was really hoping that people would be as enthusiastic about Oyster as I was.

Oyster started out from a conversation with Guy Dickinson, who was suggesting that Ruby having an instant deployment (and zero sysadmin) platform in the form of Heroku made it a great target for web apps. Heroku is truly cool, but of course it’s a commercial application rather than a community project. Oyster, as a project, will start with building tools to Just Launch Your WebApp in the cloud, and will hopefully lead on to community hosting options, but (and I think this is a key point) without preventing somebody at a later date building a commercial platform on top of it. Oyster is quite ambitious, but even a single hackday would be able to get it nicely kick-started!

I’ll write about this in more detail soon, but in the meantime you can look at the Oyster presentation on slideshare. I was quite pleased with it, and though there were some excellent projects proposed, it won the bid, yay!

Or rather, it was one of the projects that won the bid ;-) Mark Keating suggested in his Why Aim So Low? presentation, we should continue to maintain Ironman over the next year too. We also agreed with Matt Trout that we could spend some time (in Hackday intervals, or short sprints over the year) triaging bugs for Perl 5 core. And finally, we’d all really liked Iain’s “Hackday in a Box” idea (a 1-page management console for hackday projects) but thought it was perhaps a small project for a hackday. And so we decided to incorporate it into the day by having Hackday in a Box be the sample application for Oyster!

All the voting and negotiations happened in a really nice consensus building way, and worked really well! We’re all set for the next steps which are:

Notes on new Macbook Pro

So, I got a Macbook Pro from $new_company (about which more later)
and, as I believe is traditional, here are some notes about the experience.

Setup

Very nice: no rebooting, things just work from more or less the moment you take
it out of the box. (Compare with recent Samsung N140 netbook, whose Windows 7
install wanted several reboots to install all the additional antivirus and
other crap it comes bundled with.)

Apps

My parents, brother, gf, and her mother all have macbooks. And you have to
admit that out of the box they come with a rather well thought out set of
applications for real people. But of course everyone has different needs, and
I immediately installed the following:

(Some are payware, eek! I’m trying them out for 30-day trials, and may get
some through work, others I might be persuaded to pay myself, but lets see)

  • Adobe Creative Suite 4 (Payware, but a friend works for Adobe, which made it seem very much worthwhile, if only for PhotoShop and InDesign)
  • Launchbar (App Launcher. Very nice, and apparently shinier than QuickSilver, but Payware)
  • Things (Task tracker, seems quite nice. Payware)
  • The Hit List (ditto, trying now after finishing the Things trial)
  • Omnigraffle (really nice design tool. Payware)
  • OmniOutliner (outlining tool. Payware)
  • Miro (torrent client and video player, Free)
  • VLC (Video player. Free)
  • VirtualBox (Virtual machine host. Free)
  • VMWare Fusion (Virtual machine. Payware)
  • Skype (VOIP client – yes, proprietary but family and work use it. Free)
  • Telephone (VOIP client without a stupid phone-like UI, yay! Free)
  • Google Chrome (Because Safari still sucks. Free)
  • Firefox (ditto)
  • OpenOffice (Office applications. Now native, so starts quickly unlike the old NeoOffice, yay! Free)
  • TextMate (Text editor. Though why would I want anything other than Vim. Payware)
  • MacVim (Text editor. Free)
  • Cha-Ching (Money manager. Crashed, not impressed. Payware)
  • Moneywell (ditto. Seemed more stable at least. Payware)
  • GitX (Git client. Shiny. Free)
  • The Haskell Platform (Much easier to install than last time I tried on ubuntu… Free)
  • Picasa (Photo manager, though I guess iPhoto is OK. Free)
  • Songbird (Music player. Free)
  • Tweetie (Twitter client. Free I think, I’m certainly not paying for one anyway)

Then some file storage apps:

  • DropBox (Remote file storage. Free)
  • BackBlaze (constant remote backup. Without any options. Yay. Bought immediately after free trial, as I really like the idea of not losing all my data, even though I’m too stupid to manage my own backup).

And some toys for the menu bar:

  • SlimBatteryMonitor
  • MenuMeters
  • MacFuse + fuse-ext2 (to copy my data from external ext3 disk)
  • Growl (Grrr!)
  • Candelair (to attempt to fix apple remote breakage in snow leopard)

And miscellaneous bits and bobs:

  • X-code and brew
  • Xiph-qt, to allow iTunes to play .ogg files

I’ve not had time to play with all of these, but the overall quality is pretty
good. Installation isn’t too bad, though I don’t think it’s intuitive to “just
drag the icon to the applications folder”. You can tell it’s not intuitive by
the fact that every .dmg has a different background image with a large arrow
graphic trying to point it. Or by the fact that my parents launch the one or
two applications they’ve downloaded by opening them from a .dmg that they have
permanently mounted… sigh…

Ah, there’s even an article about this.

But OK, once you know how to do it, it’s easy enough. Though I’d like
apt, and should look at MacPorts. I did install brew which
is nice for command-line apps.

Hardware

Hardware is nice. Mostly. It doesn’t run too hot. I like the lighting on the
keyboard. Actually the keyboard is much nicer than I’d expected (One of the
few really excellent things about the thinkpad was its keyboard, so I wasn’t
really expecting all that much from these odd scrabble-keys, but I’ll talk
about that in more depth shortly).

The new Mac trackpad is OK. I think I’d rather have a button – it’s not as if
you can click anywhere on the trackpad to click, it has to be near the
bottom, so why not just have a button? On the other hand, tap-to-click works
fine. Not having physical buttons means that there isn’t a middle-mouse
button. Which is inconvenient in an ubuntu VM, as it means there’s no obvious
way to do copy-paste in an xterm… I worried about this for a while, then came
up with the obvious workaround instead — use gnome-terminal… (who needs
unicode, colours, or stability anyway?)

The trackpad seems insensitive too for “click; move; click” sequences. OK,
this is mainly a problem for FreeCell and DiceWars, but annoying in any case.

The screen is nice too. Oh, the screen: this was largely why I had a sudden
wild shift from a 12″ supposedly “ultraportable” thinkpad to a 17″ MBP… I
decided that I couldn’t see enough on a small screen. OK, so the 17″ is
massive… embarrassingly so when you take it out on a train for example, but
it does make for a great machine to work on.

There are a couple of things I’m not so pleased with though: though the machine
doesn’t run hot (like my thinkpad) it does tingle in a semi-electric-shock way
when the power adapter is plugged in (a quick google suggests this is a fairly
common problem). Also the headphones, while loud and crisp, seem quite noisy.
When you have the phones plugged in, every time a noise occurs, the headphone
socket then hisses for half a minute, then switches itself off again.

Keyboard

The most annoying thing about the keyboard is the odd positioning of the keys.
The # key is hidden away in Alt-3 (but without anything written on the keyboard
to hint that). Oddly under my ubuntu VM (with keyboard set to Apple MBP) it
insists on RightAlt-3. PgUp/PgDn are Fn-Up/Fn-Dn, which is reasonable but
unexpected. Also, there’s only one delete key, which behaves badly in
Terminal.app until you set the appropriate options correctly (why isn’t that
the default?). Yet, there are some oddities taking up precious keyboard real
estate:

  • WTF is the “±§” key for?
  • Why haven’t they moved the Caps Lock key? OK, it’s not entirely useless, but it has very few use-cases: shouting on IM, or writing COBOL. It should be somewhere towards the top-right of the keyboard, and not in a place that’s easy to mistakenly press it. OK, so no other manufacturer moved CapsLock anywhere else, but Apple have supposedly “thought” different about the rest of the layout, so why not this?

Also, instead of Ctrl being at the very bottom-left (a lovely position, which
means you can press Ctrl without using a finger — I use the pad of my left
hand) the “Fn” key is there instead. The Thinkpad shares this idiocy. I’ve
recently been using a 5-year-old HP laptop as a backup, and despite it being
underpowered and falling apart, the 2 things I really liked, after using a
thinkpad, were a) the Ctrl key being in the right place, and b) that it had a
trackpad. (The Thinkpad just had a clitmouse. After 2 years I learnt how to
use it, but still found it hateful. Never again. But I digress.)

Media keys

Another oddity is the media keys. (Where by “oddity”, I’m struggling for a
politer word than “batshit crazy clusterfuck”).

I never really got media keys working satisfactorily under Linux, where they
mainly just spoke to the foreground application. So I was hoping that a bit of
Apple shiny would go a long way. Now I’m not a usability expert, but I’m
hoping that my expectation for what a Play/Pause button should do might not be
entirely insane or impractical:

  • if any running app that knows about play/pause declares it is “playing” then it should pause
  • else if the currently focused app knows about play/pause, then it should start playing
  • else launch the “default media app” and start playing (or, even better: don’t do anything)

What actually happens is this:

  • The Play/Pause event is sent to every open app. So any app that cares about it will:
    • start playing if paused
    • pause if playing
  • also, if iTunes is closed, then it will open

So, if you have VLC open playing a video, and somebody calls you, you press the Pause button. Then:

  • VLC stops playing
  • Oops, looks like you had Miro open, so it now starts playing
  • Looks like you didn’t have iTunes open, you must have wanted that, right? So iTunes launches and then starts playing too…

But that’s OK. You can press the Pause button to stop the chaos right?

  • Now Miro stops playing
  • iTunes stops playing
  • VLC starts playing again

Apparently this is breakage from 10.6 Snow Leopard, having been sane till 10.5.
There is speculation that Apple are trying to make 3rd party apps look bad by
not responding “properly” to the media buttons, while Apple’s own apps do. If
that’s true, then it’s not working. I don’t blame VLC. I don’t blame Miro.
Dear Apple, you fucked up, please sort it out.

(This isn’t just me: various threads including
http://discussions.apple.com/thread.jspa?threadID=2122639 are whining about
this idiocy. The thread mentions a cunning back: if you have QuickTime open,
it acts as a prophylactic against iTunes opening. This is apparently because
the ‘loginwindow’ process has an exception hardcoded into it not to launch
iTunes if it detects QT running. So not in the slightest bit insane then.)

I had the same issue with the remote. Yet it’s shiny, but if it only wants to
play with iTunes and the useless Front Row (where by useless, I mean doesn’t
play my videos, which is what I expected it to) then it’s basically a shiny
paperweight. Thanks Apple. I’ve installed Candelair, which may possibly help
improve this but I’ve been disinclined to test properly.

Power Management

When the machine resumes from sleep, the external monitor shows static “snow”
for half a minute or so. That’s not particularly impressive. A quick google
suggests that older models had similar problems, perhaps this resurfaces every
now and then? I should probably check to see if it’s going to be a
deteriorating hardware issue.

On the other hand, it actually resumes. From sleep-to-ram. And
hibernate-to-disk. Every time. Yes, every time!

(Can you tell I’ve been using Linux-on-laptop for the last 5 years?)

And though I don’t think I’m getting anywhere near the 8 hours advertised, I am
to be fair running with a bright screen, a couple of VMs and so on.

Windowing

This is a mixed bag. Mainly, the windows are less useful/pretty than Gnome:
you can’t set windows to Keep-on-top. You can only resize using the
bottom-right control, no Alt-to-drag option. No ability to maximize a window
(ok, so the need for this doesn’t come up as often as I’d expected, but when it
does, it’s annoying), and new windows don’t get tiled in pretty places as with
gnome. Also, more often than I remember happening under Linux, popup windows
get placed underneath the windows that created them. Meh.

I’m not sure whether I like Finder better than Nautilus. It seems to be
possible to use drag-to-copy into a folder of folders (rather than into one of
the subfolders). On the other hand “type-to-jump-to-filename” seems to not
work consistently (I haven’t quite figured which state is inhibiting this).

When you’re using 2 monitors, Mac’s single menu bar (on the top of the screen
instead of top of window) becomes a royal pain, as you have to move the pointer
from the external screen back to the laptop’s one to use it. I guess I should
learn the command keys to do this without mouse. Also, if you put the second
screen immediately above the first, you suddenly change the menu bar from being
“a mile high” to being a thin strip of stuff that you have to target. So don’t
do that (or learn those key combinations).

Spaces… wasn’t sure how to move apps between spaces. But the F8 view is
quite cute when you work out what it is (I was confused by it showing me what
looked like a 4×2 view instead of a 2×2 one… but of course I have external
monitor plugged in… d’oh.) Very cute is that Expose works while you’re in
the thumbnail view.

Date/Time applet in menubar is underpowered. Compare to the Gnome one that
has a month calendar view, world date-time and weather. This one can’t even be
configured to show the date in the menu bar. It’s a prime candidate for
replacement with something actually useful.

The only thing I can think of that might explain the weak Date/Time applet is
that they are trying to sell you on the Dashboard one? If so, it doesn’t work.
The Dashboard is a wonderful combination of ugly, confusing, and useless.
Every time I opened it (by accident, mostly) I would struggle to either get it
to do anything useful or, even better, close again. Luckily there is a
‘defaults’ setting that prevents it from opening again. Phew. Bizarre.

Virtual Machines

For dev work, I was planning to use VirtualBox, which has the nice feature of
being free. It has a few problems though:

  • networking seems to be hard to setup to work usefully.
  • Swallows some keys. Particularly Ctrl-Arrow to move between spaces, and Command-Space for launchbar.

VMWare solves these, though, oddly, it actually seemed slightly harder to
setup. Installing the “guest additions” had to download a large package, and
instead of running it itself expected me to read the system documentation to
know what to do with it (I just ran the perl script from terminal, which works
fine… Not sure why the README file couldn’t have just said that). Still,
minimizing friction between guest and host working is probably worth paying
for.

Conclusion

There are some niggles, and some outright baffling brokenness, but actually
I’m quite enjoying working on a Mac.

Spreadsheet imports: imperative vs. functional

I’ve been prototyping ways for customers to import data into our system.
While some kind of JSON/XML structured data would be easiest for us,
our customers like spreadsheets. That’s cool of course, and it’s easy to
mock up imports like this.

Product Price Category
Brie £ 2.00 Dairy
Chablis £ 5.00 Wine

Of course not all data fits nicely with this kind of very flat structure.
For example multiple values. We could do something like

Product Price Tags
Brie £ 2.00 Dairy,Cheese,Food
Chablis £ 5.00 Wine,Alcohol,Drink

but it might be nicer for the customer to organize like this instead:

Product Price Tags
Brie £ 2.00 Dairy
    Cheese
    Food
Chablis £ 5.00 Wine
    Alcohol
    Drink

The problem is that we can’t really parse the table row by row, simply.
We have to remember where the definition started, and finalise when the
item has been completely defined (which will happen when the next item
starts).
I started prototyping this in Perl, and ended up with some typical imperative
code like this:

    my (@products, $product);
    for my $r ( @rows ) {
        my $row = get_row_data($r);
        if ($row->has_product) {
            push @products, $product if $product;
            $product = Product->new( 
                product => $row->product, 
                price   => $row->price 
            );
        } else {
            die "No product" unless $product;
        }
        $product->add_tag($row->tag);
    }
    push @products, $product;

This is quite yucky. See how I’m repeating the push @products line:
first time when seeing a new product, and second when we’ve exited the loop.
Then we have the multiple assignments to $product and so on.

All of which seems to work OK, but I really dislike this logic, and am beginning
to think it’s a perfect example of an imperative antipattern. So, let’s see if
we can do it more elegantly. Thinking about how I’d do it functionally, in
Haskell, I’d use groupBy on each row, connecting the rows up until the
next row has a non-blank product.

So let’s try that in Perl! We’d want something like:

    my @items = groupBy sub { 
            my (undef, $next_row) = @_;
            ! $next_row->has_product
        },
        map get_row_data->($_),
            @rows;

    my @products = map {
        my $row_1 = $_->[0];
        Product->new(
            product => $row_1->product,
            price   => $row_1->price,
            tags    => [ map $_->tag, @$_ ],
        );
        } 
        @items;

That has less repetition, and less accidental complexity. First we group
the lines. Then we turn the groups of related rows into new objects. Job
done.

The groupBy function is interesting: notice how the callback to it
takes 2 arguments ($this_item, $next_item), though as we don’t care
about the current row, only the next one, we’re just doing (undef,
$next_row)
.

groupBy is also problematic though, in that it doesn’t exist in any of
the normal places I’d have expected (List::Util, List::MoreUtils etc.). So
let’s create it. The ideal way might be to translate Haskell’s definition from
the Prelude, but given that Perlish lists don’t have lazy semantics, and we
then have to implement span etc., let’s just write a noddy imperative
version for now:

    sub groupBy {
        my ($fn, @elems) = @_;
        my @groups;
        my $a = shift @elems;
        my $b;
        my @group = ($a);
        while ($b = shift @elems) {
            if ($fn->($a, $b)) {
                push @group, $b;
            } else {
                push @groups, [@group];
                @group = ($b);
            }
            $a = $b;
        }
        push @groups, [@group];
        return @groups;
    }

This of course has much of the unpleasantness I was complaining about before,
but at least it’s encapsulated, and allows us to use groupBy neatly.
(And we can always come back and clean up the internals later).

(And yes, I know I could define groupBy (&@) so that I could omit the
sub‘ around the block like with map/grep. But this is more annoying
than useful, as I can’t then simply call: groupBy \&function.)

How would you tackle this task? Is there even an elegant way to do it
imperatively?

Github language statistics

I enjoyed Aldo Cortesi’s rather interesting post about language statistics on github. He’s done some good analysis, and there are some interesting nuggets of information to be had about Perl, Haskell (though fewer, as there are only 18 projects that made his criteria) as well as other languages.

Of course, there is some silliness there too: you can bash Perl for many reasons (and if you’ve read my blog before, you might know that I do too), but there are some gems of forced interpretation:

C and Perl projects show a marked decline in activity over their first year. I suspect that the Perl result is due to the fact that it becomes harder and harder to contribute to a Perl codebase, the bigger it gets. The C result is more of a mystery.

I’m not sure that the premise is true — perhaps Perl projects are more limited in scope, for example. And Modern Perl is a quite different beast from the Matt’s PERL script archive of yesteryear. But the punchline is priceless ;-)

Here’s what I read with my biased interpretation of his results ;-)

  • Far fewer Perl projects than Ruby/Python so far. Github is a Ruby community effort, so it’s unsurprising that it would dominate here.
  • Median contributors for Perl is above average. This is substantiated by the total contributors for long running projects being comparable with Ruby/Python.
  • Perl projects seem to have many, small commits. This would seem to be a good thing, and rather in keeping with the Git Way. (/me shuffles embarrassedly at the sight of his own, rather monolithic git commits…)
  • While Aldo suggests Perl projects are “significantly more “top-heavy” than those in other languages, with a smaller core of contributors doing more of the work,” one could also hypothethize that Perl projects are good at attracting and retaining a strong core team. This certainly seems to be the case with long running, active projects such as Catalyst and Moose.

So, thanks Aldo for taking the time to do this fascinating analysis (though I’m sure you won’t mind if I draw some slightly different conclusions than you ;-P)