Older blog entries for crhodes (starting at number 137)

I released sbcl-1.0.33 last week; there's a good amount of new stuff in there, including support for NetBSD on the x86-64, some new introspection and tunable functionality, and also a whole chunk of Unicode and external-format work that I meant to do some months ago.

Today I got round to giving SBCL's website a little bit of an update; not only does it reflect the most recent release – something we've got a little bit lax on recently – but also I have updated my gpg key information. Since Launchpad seems to have taken for our bugtracking needs (at least I'm reasonably content with it), I've also taken the opportunity to link the bug numbers in the news page to the relevant bug entries in launchpad. This is still very Web 1.0, I recognize; I was at a networking event today where the highly eminent keynote speaker spent about 20 minutes essentially saying (and I paraphrase mercilessly) "social web, linked data, this is the FUTURE, it has reached a TIPPING POINT, we are on the road to DATA MASHUP WEB 3.0" and I feel relatively content to stick with my curmudgeonly Web 1.0 view of the world for now.

A while ago now, Nikodemus Siivola moved bug information for SBCL from a flat text file to Launchpad. Historically I have had almost nothing but displeasure working with the "standard" or "industrial" bug trackers; I have found Bugzilla horrible to work with, both as a bug reporter and as an administrator; lighter-weight solutions such as Trac are just about tolerable, but basically anything that requires me to have a Web Browser seems to end up confusing and distracting me. An honourable mention at this point goes to debbugs: being able to report, manipulate, update and close bugs by e-mail is close to my idea of Nirvana.

So, Launchpad. Initially, I was dismayed, because there doesn't seem to be a way of getting notifications of bug updates over RSS, which would be a second-best to getting updates by e-mail. I managed to ignore all SBCL bug reports for a while, but eventually I bit the bullet and signed up (having refused to do so a good long while ago, when shortly after I used Ubuntu's bugzilla to report a bug they closed the bugzilla in favour of launchpad without managing to transfer accounts across.)

A large motivation for signing up was the discovery that launchpad does, in fact, have an email interface to the bug tracker; as long as you can emit GPG-signed mail (which I can), it seems to have all the required functionality for doing things without needing to go near a web browser; I can now receive bug reports and reply to them, and in at least some cases the References: headers in the mail I receive allows my client to thread the discussion properly (I haven't really stress-tested this yet, but it works at least well enough for now.)

If that were all, this would not be news (and not even worthy of a blog post). But now I get to demonstrate my Emacs lisp “scripting” ability, in much the same way as Dan Barlow did for me many years ago: SBCL has a mailing list for reporting bugs, for people who are unsure as to whether their problem is a bug or not, or for people who don't want to go to the trouble to get a launchpad account just to report a bug. When such a report does describe a new bug that we should be tracking, that report needs to make its way to launchpad.

Without too much further ado, I present sbcl-bugs-mail-forward, which constructs a message (almost) ready to be sent:


(defun sbcl-bugs-mail-forward ()
  (interactive)
  (let ((message-forward-ignored-headers "")
        from subject)
    (gnus-summary-mail-forward 4)
    (message-goto-to)
    (insert "new@bugs.launchpad.net")
    (message-goto-subject)
    (message-beginning-of-line)
    (re-search-forward
     "\\[\\(.*\\)\\].*\\[\\(.*\\)\\] \\(.*\\)$")
    (setq from (match-string 1) subject (match-string 3))
    (message-beginning-of-line)
    (let ((kill-whole-line nil))
      (kill-line))
    (insert subject)
    (message-goto-body)
    (insert "Report from " from "\n\n")
    (insert " affects sbcl\n status confirmed\n importance ")
    (save-excursion
      (insert "\n tag \n done\n\n")
      (message-goto-body)
      (re-search-forward
       "^\\(-\\)+ Start of forwarded message \\(-\\)+$")
      (beginning-of-line)
      (let ((kill-whole-line t))
        (kill-line))
      (re-search-forward "^\\(-\\)+$")
      (beginning-of-line)
      (end-of-buffer)
      (kill-region (mark) (point)))
    (mml-secure-message-sign-pgpmime)))

You can tell it's scripting, really: it's an odd mixture of plausible and dubious ways of getting things done: regular expressions to extract the original sender of the report, and to remove the forwarded message information (and the dull advert inserted in the footer by SourceForge's mailing list system). On the other hand, that function, coupled with something along the lines of


(setq gnus-parameters
      '(("nnml\\+private:list.sbcl-bugs"
         (gnus-summary-prepared-hook
          '(lambda ()
             (local-set-key (kbd "C-c C-f")
                            'sbcl-bugs-mail-forward)
             (local-set-key (kbd "S o m")
                            'sbcl-bugs-mail-forward))))))

gives me exactly what I think I want: a simple way of creating, tagging and classifying an entry in the bug tracker from a mail report.

I couldn't find any convenient emacs/launchpad interfaces (or any at all, in fact); I'm not sure this counts as one either, but by all means use, adapt and improve on the above for your purposes – I'll happily take criticism of and improvements to this hack.

As mentioned earlier: the 2010 European Lisp Symposium invites your contributions. Unfortunately, the website for the 2010 event is not set up yet; you can get an impression of what the event is like by looking at last year's website, which in the fullness of time (soon, I hope) will be updated with ELS2010 information. In the meantime, here's the Call for Contributions: we would welcome both papers describing original work, not published elsewhere, and submissions for tutorial sessions. Submission will be through EasyChair's conference management system.

3rd European Lisp Symposium

May 6-7, 2010, Fundação Calouste Gulbenkian, Lisbon, Portugal

Important Dates

  • Submission Deadline: January 29, 2010
  • Author Notification: March 1, 2010
  • Final Paper Due: March 26, 2010
  • Symposium: May 6-7, 2010

Authors of accepted research contributions will be invited to submit an extended version of their papers to a special issue of the Journal of Universal Computer Science (J.UCS).

Scope

The purpose of the European Lisp Symposium is to provide a forum for the discussion and dissemination of all aspects of design, implementation and application of any of the Lisp dialects. We encourage everyone interested in Lisp to participate.

The European Lisp Symposium 2010 invites high quality papers about novel research results, insights and lessons learned from practical applications, and educational perspectives, all involving Lisp dialects, including Common Lisp, Scheme, Emacs Lisp, AutoLisp, ISLISP, Dylan, Clojure, and so on.

Topics include, but are not limited to:

  • Language design and implementation
  • Language integration, interoperation and deployment
  • Development methodologies, support and environments
  • Reflection, protocols and meta-level architectures
  • Lisp in Education
  • Parallel, distributed and scientific computing
  • Large and ultra-large-scale systems
  • Hardware, virtual machine and embedded applications
  • Domain-oriented programming
  • Lisp pearls
  • Experience reports and case studies

We invite submissions in two categories: original contributions and tutorials.

  • Original contributions should neither have been published previously nor be under review in any other refereed events or publication. Research papers should describe work that advances the current state of the art, or presents old results from a new perspective. Experience papers should be of broad interest and should describe insights gained from substantive practical applications. The programme committee will evaluate each contributed paper based on its relevance, significance, clarity, and originality.

  • Tutorial submissions should be extended abstracts of up to four pages for in-depth presentations about topics of special interest for at least 90 minutes and up to 180 minutes. The programme committee will evaluate tutorial proposals based on the likely interest in the topic matter, the clarity of the presentation in the extended abstract, and the scope for interactive participation.

The tutorials will run during the symposium on May 6, 2010.

Programme Chair

Christophe Rhodes, Goldsmiths, University of London, UK

Local Chair

António Leitão, Technical University of Lisbon, Portugal

Programme Committee

  • Marco Antoniotti, Università Milano Bicocca, Italy
  • Giuseppe Attardi, Università di Pisa, Italy
  • Pascal Costanza, Vrije Universiteit Brussel, Belgium
  • Irène Anne Durand, Université Bordeaux I, France
  • Marc Feeley, Université de Montréal, Canada
  • Ron Garret, Amalgamated Widgets Unlimited, USA
  • Gregor Kiczales, University of British Columbia, Canada
  • Nick Levine, Ravenbrook Ltd, UK
  • Scott McKay, ITA Software, Inc., USA
  • Peter Norvig, Google Inc., USA
  • Kent Pitman, PTC, USA
  • Christian Queinnec, Université Pierre et Marie Curie, France
  • Robert Strandh, Université Bordeaux I, France
  • Didier Verna, EPITA Research and Development Laboratory, France
  • Barry Wilkes, Citi, UK
  • Taiichi Yuasa, Kyoto University, Japan

A while ago, I attended the 2009 European Lisp Symposium. Antonio Leitão, the Programme Chair for that event, is now preparing a special issue of the Journal of Universal Computer Science on Lisp: Research and Experience, and while authors of ELS papers are invited to submit substantially extended versions of their conference papers, so too are new contributions being sought: the Call for Papers explicitly welcomes original contributions not submitted elsewhere.

The deadline for submissions is not far away: 19th October 2009, so get scribbling! (And should the worst happen, and inspiration not strike in time, don’t despair: the call for contributions to the 2010 European Lisp Symposium will be published shortly.)

In my previous diary entry, I was all gung-ho and optimistic about actually improving SBCL's support for Unicode; “not all of this is implemented yet”, I said. Shortly after beginning to implement the UTF-16 external format, I discovered that the compiler, on x86 only, was miscompiling memory accesses where the offset was of the form (+ variable constant). Because of the release cycle, I then felt that I had to address that (and certain other miscompilation issues that people noticed), with the result that the major achievement in SBCL's Unicode support in the hot-off-the-press 1.0.31 release is that

the EBCDIC-US external-format is now supported for octet operations (as well as for stream operations).
Lucky EBCDIC users.

I was going to blog about the fact that using org-mode, referred to in my previous diary entry, made the important but non-urgent tasks more visible. I was going to use sorting out backups for interesting data (say, my e-mail archives) as an example, and discuss the solution I came up with, but I have just realised that the trust model is exactly backwards (my server trusts root on the backup machine). This is annoying, because I thought I'd got it right, and because getting it right would have been equally easy.

Oh well. So, instead, I'll return sorting out backups to the TODO (or maybe STARTED) state, and (prompted by some recent discussion on #lisp IRC) I'll blog about SBCL's interpretation of Unicode characters, with the up-front caveat that I'm Not An Expert in this languages, glyphs, graphemes, characters and all that jazz.

Common Lisp's string type is defined to be a vector specialized to hold only characters or a subtype thereof. This definition is already hard to wrap your head around, and has amusing consequences documented here in the past, but I don't want to get into it too much; merely to say that already this definition restricts to a fairly large extent the possible implementation strategies for supporting Unicode.

Why so? Because in Unicode there are several notions of ‘character’, and we have to decide which of them we're going to use as our Lisp character type (and use as string constituents). The simple answer from the implementation point of view (and the route that SBCL currently takes) is to define a Lisp character as an entity corresponding directly to a Unicode code point. This is simple and straightforward to implement, but unfortunately has the side effect of making various Common Lisp string functions less useful to the user.

How so? Well, consider the string comparison functions, such as string=. As specified, string= compares two strings, character by character. In SBCL, then, this compares two sequences of Unicode code points, character by character, for equality. The problem is that this operation doesn't in general have the semantics of ‘string equality’, because in Unicode there is more than one way to encode the same abstract character: for example, the e-acute ‘abstract character’, or possibly ‘grapheme’, e-acute (which is usually displayed ‘é’) can be represented either as the single code point U+00E9, or as the combining character sequence U+0065 U+0301.

So, that's OK; the Unicode FAQ on Combining Marks says that characters and combining character sequences are different, and even implies that programmers should be dealing with Unicode code points (SBCL characters). Unfortunately, Lisp has been around for longer than Unicode, and code has been written essentially assuming that string= performs a language-string equality comparison rather than a codepoint-by-codepoint equality comparison, simply because (pre-Unicode) these two concepts were conflated.

What about the alternative? We could try defining Lisp characters to be abstract characters, represented as combining character sequences. One problem with this idea is that there's the char-code function to implement: for every Lisp character there must be a corresponding unique integer. That's not so much a problem – Lisp has bignums after all – but it will make char-code-limit surprisingly large (in principle, I think every combining mark could be applied to a given base character). This means that we'd lose the ability to represent an arbitrary character as an immediate object, meaning that accessing characters from strings would in general cause heap allocation, and lead to surprises elsewhere in the system.

So, given that we stay with a Lisp character corresponding to a Unicode code point, what other pitfalls and details are there to consider? The memory representation of strings of type (simple-array character (*)) is worth mentioning; because there's a fairly strong cultural expectation of O(1) access time in vectors, we don't do any compression, but simply store each Unicode codepoint in a 32-bit cell. SBCL has a separate base-string representation, where each ASCII codepoint is stored in an 8-bit cell; a long time ago I gave a talk about this.

Also, interpretation of the contents of strings has caused confusion recently. Granted that a string is a vector of (effectively) code points, what does that mean for strings containing surrogate characters (code points in the range U+D800–U+DFFF)? These code points do not correspond to any abstract characters directly; instead, pairs of surrogates are (in certain Unicode encodings, such as UTF-16) interpreted as characters beyond the Basic Multilingual Plane. Some Lisp implementations (such as OpenMCLClozure Common Lisp) go so far to resolve this ambiguity as to forbid the creation of a Lisp character with a surrogate codepoint. In SBCL, however, we take the view that those characters exist, but should not be interpreted in any way; a string containing surrogate pairs should be considered to have individual surrogate characters in it, and no attempt should be made to combine them. If there is data in an encoding which uses surrogate pairs (such as UTF-16), then that data should be read in using the :utf-16 external format, so that no surrogates are present at the Lisp level; an attempt to write out a surrogate Lisp character in a Unicode encoding should generate an error. (NB: not all of this is implemented yet).

All of this merely scratches the surface of Unicode support; I'm hoping to find time to implement better support for finding properties of the Unicode Character Database, and to implement Unicode algorithms for normalization, collation and so on; I'm also planning to tighten up support for the Unicode encodings (to address the potential security issues that exist from nonconforming decoders) and generally to improve support for doing useful things with non-ASCII. As usual, there's likely to be a significant lag between planning and doing...

Although I've used Emacs for well over 10 years, and I've been a pretty serious Common Lisp programmer, I don't consider myself an Emacs power user by a long shot: I don't think I'm at all skilled in its use; I don't customize it very much; and I know almost none of the interesting bits of Emacs Lisp. The only applications I really use within Emacs are Gnus, the News and Mail reader (which I adopted after one too many "please find attached" errors) and, more recently, SLIME (but since much of my Common Lisp work is at the implementation level, the luxury of using SLIME for development is often unavailable.

Recently, though, I'm beginning to suspect that I might get more practice. Firstly, the additional responsibilities of a permanent job in UK academia (essentially boiling down to administration, lots of it) meant that my old strategies for managing my TODO list (scraps of paper, followed by writing in different colours on my office wall, followed when I ran out of wall space by a plain-text TODO.txt file) were no longer sufficient to manage the complexity, and I discovered org-mode.

My use of org-mode has, roughly, removed the feeling that I'm drowning in a morass of multiple different things to do with no idea of what's important or urgent along with a feeling that I've forgotten the really important things, and replaced it by a vague feeling of guilt that I'm not doing all the TODO, STARTED, WAITING items that show up in bold red in my *Org Agenda* buffer (and probably won't, ever). I haven't yet found a good way of integrating notes that I take on my often-disconnected laptop with the master org files kept on my server, but vague guilt is noticeably preferable to drowning, so this is a net win.

Also a net win for me is the new daemon functionality in GNU Emacs 23. My setup for mail is perhaps a little eccentric; I read all my mail, including work mail (over imap), from a machine at home which I might call a "server"; I used to log in over ssh, start emacs -f gnus, and go on from there. With the new daemonized emacs, I only need to start emacs once, and can connect to it later, whether that's from my office workstation, or my laptop at some arbitrary location (assuming that I have Internet access, anyway), or even someone else's Mobile Internet Device.

I found one problem with this new modus operandi, though; once I'd logged out of the shell session that started the emacs daemon, accessing remote files with tramp (over ssh) became more painful, as the ssh credential forwarding provided by the ssh-agent responsible for that session was no longer available. The solution I found was to run an ssh-agent instance within the emacs daemon at startup; I have lightly adapted some code by Will Glozer; with my version, a simple


(when (daemonp)
  (ssh-agent "ssh-agent -d"))
in my ~/.emacs does the job very nicely.

I've just come back from the 2009 edition of the European Lisp Symposium, held in Milan. It was fun! (It was hot, too).

I agreed, at something like the tenth hour, that I would present a tutorial on using SBCL internals; perhaps inevitably, I left it until somewhat past the eleventh hour to actually prepare for the tutorial, with the result that I'm not sure how effective it was – it certainly wasn't the kind of tutorial where the audience follows along each on their laptop, and that meant that I didn't really get any audience feedback during the session. In partial mitigation, the tutorial materials should appear on the ELS website at some point; they're also available from my talks page at work.

My somewhat lax preparation regime meant that I didn't get maximum benefit from the social time, since on Wednesday evening I participated in the steering committee meeting, had a little bit of a drink at the reception, and then went off and worked on my tutorial. I did have a chance to speak to some people later, particularly at the final dinner, but not as much as I would have liked (this was also partly dictated by my travel arrangements, which were extremely tightly placed around the conference's official schedule). The other presentations were fun, though; the accepted papers showed a good range, from very specific aspects of particular lisp evaluation models (stand up, Tom Burdick and OMG1) to using a web browser as the interactive output pane of a Lisp debugging session. I enjoyed the keynotes as well, even those where I disagreed slightly or profoundly with the speaker on the technical or social issues discussed; the debate on the future of CL (the panel: Pascal Costanza, Nikodemus Siivola, Stelian Ionescu, Marco Antoniotti, and Scott McKay) was also a success, I think; there was at least a range of opinions on display.

I'm looking forward to the 2010 iteration (to be held in Lisbon), not least because I will be rather more involved in the organization of it than I was this year. I'll be watching for any other wrapups of this year's event, and if anyone has any ideas for what they'd like to have in the programme for ELS2010, please don't hesitate to get in touch!

I've recently been working on improving SBCL's build behaviour.

Well, perhaps that's not exactly a novel or surprising piece of information for this diary: but maybe this is the last major effort that has to be made. One of SBCL's raisons d'être is to be a Common Lisp compiler, written in Common Lisp, that does not have any dependencies on the host Lisp compiler used to build it (assuming that the host implementation is sufficiently conforming, but not making any unwarranted assumptions about any implementation-defined or undefined behaviour). This method for building a Lisp compiler is sufficiently tricky to wrap one's head around that I wrote and delivered a paper describing it, including diagrams, for the Workshop on Self-Sustaining Systems last year.

So what's new now? Well, given this aim, it would be reasonable for the output of the SBCL cross-compiler, running as an application in the host Lisp, to produce bitwise-identical output files independent of which host Lisp was being used. Reasonable, perhaps, but in practice the state of SBCL until a month or so ago was quite a long way away from this ideal: every output file had a header declaring when and from which compiler it had been generated, which was not going to help bitwise comparisons: and even after such straightforward issues had been dealt with, every single output file from the build process (of which there are of the order of 350) exhibited non-trivial differences when compiled with CLISP from the corresponding output files compiled with SBCL.

The differences between output files that I've observed and fixed in the last month or so – by lavish use of cmp(1), staring at emacs buffers consisting largely of control characters, and the time-old debugging method of Thinking Very Hard – can be broadly split into three categories:

  • outright leaks: information being taken from the host compiler and erroneously treated as though it was applicable to the target. Sometimes this was simple carelessness (the cross-compiler's constant-folding for symbols used symbol-value, even for things like most-positive-fixnum); sometimes it was nastier than that (CLISP and SBCL disagree on the value of (log 2d0 10d0) in the last binary digit). It's not nice to find these things still showing up, but at least this set of changes should make these bugs stick out like a sore thumb if they're ever reintroduced (or still present on other platforms...)

  • traversal order: some operations have a net effect that's deterministic, but the order in which sub-operations was different; collecting a bunch of definitions by iterating over a hash table with maphash, or a set of storage classes with union, is going to be correct no matter the order, but different between different implementations of those functions. Also in this class, though not strictly speaking an issue of traversal order, was the dependence on the host's interpretation strategy: whether forms were always compiled or not, which influences the number of times gensym is called and hence the value of *gensym-counter*.

  • idiosyncrasies: working towards eliminating the effect of differences of interpretation in the standard. Most of these differences of opinion are legitimate: CLISP macroexpands more than SBCL does because it has an interpreter on by default, for instance; similarly, CLISP's compiler doesn't aggressively coalesce constants, whereas SBCL's does. Some of them are less so; CLISP, for instance, prints 'foo as "'FOO" whereas SBCL prints "(QUOTE FOO)" when *print-pretty* is nil. I think the standard mandates SBCL's behaviour, but for these purposes we have to work around it anyway.

In the process, I also fixed a terribly embarrassing bug in genesis, the Lisp application responsible for taking these output files from the cross-compiler and constructing a Lisp memory image file ready to start up. As has been discussed here in the past, the standard-mandated requirement on arrays in Common Lisp is not sufficient for us to be able to construct the image file in memory as an array of bytes: conforming implementations are permitted to impose a maximum array size as low as 1024 elements. Fortunately it is straightforward to implement a suitable data structure without this constraint; unfortunately, the implementation did not take sufficient care to zero-fill newly-allocated memory, and while most of the time Lisp implementations perform that zeroing, there are circumstances in which they don't.

All of this has now been merged to SBCL's CVS, and is awaiting the 1.0.28 release due on Thursday 30th April. The practical upshot? Well, apart from a certain amount of increased confidence in the implementation strategy, and perhaps soothing the nerves of extremely paranoid distribution package maintainers, these changes should make compilation of SBCL on new platforms more straightforward, as there are now two implementations capable of building SBCL which are themselves buildable starting just from gcc and system libraries: CLISP and Peter Graves' XCL.

Long time no diary: a partial explanation. (Warning: contains largely self-indulgent content not related to Free Software.)

My daughter Marianne was born on a highly auspicious date: the 8th August 2008, the most eightish date for 20 years. All went reasonably well; the paediatrician who checked her over at Newham General Hospital detected a heart murmur, but we were given an outpatient appointment a month away and discharged. It took a lot of effort and perseverance to establish breast-feeding, and her weight gain was slow, but she seemed otherwise to be healthy and doing well.

However, at the outpatient appointment at the cardiology clinic at Great Ormond Street Hospital, we were told that Marianne had a heart defect: Tetralogy of Fallot. The cardiologist immediately reassured us that this was an operable condition with extremely good prognosis, but that the operation wouldn't take place for a while, as the bigger the child the better the recovery from the necessary open-heart surgery. In the meantime, the combination of the ventricular septal defect (the ‘hole in the heart’ which caused the audible murmur) and the pulmonary stenosis (a narrowing of the pulmonary artery, the vessel responsible for taking deoxygenated blood to the lungs to be refreshed with oxygen), together with her partially-overriding aorta (the opening to the aorta being over the VSD) meant that Marianne's heart would allow deoxygenated blood to go around the body again without being refreshed with oxygen, and consequently would have to work significantly harder (leading to right-ventricular hypertrophy and also explaining her slow weight gain).

Although we had been reassured by the cardiologist, and also the GOSH cardiac liaison nurse we spoke to, the diagnosis was still a shock to me: I think I spent about three or four days being completely unable to think straight. But the mind is resilient, and after a little bit it settled down, with the reassurance that many medical professionals: health visitors, dieticians, nurses, cardiologists and general practicioners were available to help. Other sources of support were great as well: family, colleagues, friends and neighbours, and even groups on mumsnet were extremely helpful and understanding.

And so life continued. Many of the normal stages of child development happened: first smile, sleeping through the night, not sleeping through the night any more, playing with toys, discovering wrapping paper, sitting up, and beginning to eat food; all this punctuated by visits to the health visitor, cardiology clinic and paediatrics unit. And then, eventually, came the letter giving us a date for her surgery: Thursday 5th March.

First there was the pre-admission hurdle to jump: various measurements to make, various blood samples to take, and the consent form to sign. Except that we couldn't: no surgeon was available, as they were all too busy. Fair enough; we arranged to come in the following week for that. It was at that point, signing the consent form for my daughter's heart surgery, that I experienced shock and panic again, this time for the best part of a week: while the full repair for Tetralogy of Fallot is a relatively well-understood procedure (it's been performed for longer than heart-lung bypass machines have existed) the mortality rates are still of the general order of 1-2%. Because Marianne was outwardly healthy, it was very hard to believe wholeheartedly that this scary procedure was utterly necessary, and so it felt like I was needlessly making her play Russian roulette.

The 4th March rolled around, and we were essentially ready: bags packed, all urgent items at work completed, contingency plans in place. And then the hospital phoned: a more urgent case had come up and so there was no surgical team available for us; we were rescheduled for the following week. To be fair, we had been warned that this might happen – even on the day itself, so having a day's notice was a bonus. Still, there was a lot to unwind: not just the various plans, but also our own emotional preparedness. Back to the normal routine, with an extra week of voluntary quarantine for Marianne (coughs and colds noticeably impede recovery from operations).

There was to be no second stay of execution on the 11th March: we were given ‘starvation times’ for Marianne: no food after 2:30am, no breast milk after 4:30am, and no water after 5:30am. The alarm was duly set for 4am so that she could get a last stomachful. Then we were all set; we set off in plenty of time to get to the cardiac ward at GOSH for 7:30am.

Once there, Marianne was weighed, and then dressed in a hospital gown. She then played with a set of coloured wooden stacking rings, while Jenni and I debated the merits of the various colour combinations that she was inadvertently modelling – well, we had to talk about something. A surgeon came down to assess her: determining whether she was well enough for the operation to take place, and checking that she'd had nothing to eat or drink since the small hours. With a certain amount of humour, she drew a purple arrow on Marianne's chest: it is NHS policy that all surgical patients should be marked up before the operation, because there have been a few too many embarassing errors in theatre (amputating the wrong leg, and similar). As the surgeon put it, though, “there is only one heart”.

Then we waited for the most difficult part: taking Marianne to the anaesthetists and leaving her there. We were allowed to hold her while the nitrous oxide was given; it took hold quickly – without the wriggling which we had been warned might be a possibility. And then we left the room, because it was what had to be done.

Waiting while your child is having surgery is not a pleasant experience. Fortunately, the hospital is aware of this, and enforces a certain amount of activity; they require parents to sort out their hostel accommodation during this period, which involves bureaucracy and therefore takes time. Also, we hadn't had breakfast by this stage, so that was a good thing to do, and we had been given (not by the hospital!) £10 to convert into a grey book. Even extending all of these things as much as possible, it was only about two hours since we'd left Marianne (where the operation was meant to take about four hours in total), so it was an immense relief that, when we returned to the cardiac ward and a nurse was able to telephone the operating theatre, we were told that Marianne had been weaned off the heart-lung bypass machine successfully: in other words, her heart was beating again.

In fact, we were lucky: throughout our stay in hospital, we never really needed to be given any bad news. By the evening of Thursday (the day of her operation), she was taken off the ventilator, able to breathe for herself. The following afternoon, she was removed from intensive care, with her breathing and temperature no longer needing to be continuously monitored. Even the one complication, a buildup of air in her chest cavity, was rapidly dealt with, and her chest drain (a tube attached to suction, drawing fluid away from the chest), pacing wires (to correct any irregularity in the heart rhythm) and intravenous lines (used for delivery of pain relief, mostly morphine) came out at lunchtime on Saturday, leaving her with a single stitch (not the only mark, of course, but the wound on her chest is held together subcutaneously). On Sunday morning she was able to breastfeed, and she did so with enthusiasm and vigour; the nurses then removed her nasogastric tube, and told us that we were likely to be discharged the following day.

And so it proved: after one last echocardiogram, we were given some medicines (paracetamol and diuretics), an outpatient appointment for mid-April, and a discharge letter, and told to go home. And, not without some trepidation, but also with a great deal of optimism, so we did.

All of which is one way to say that, if I have dropped patches on the floor, failed to fulfil administrative duties, or ignored requests for assistance in whatever context: I apologise, but I have had other things on my mind. It seems to be common knowledge amongst parents that worry never goes away, but with luck the worries that I experience will be less acute for a good little while.

128 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!