## Death to Syntax!

The Hodgkin-Huxley model of the action potential is a foundation stone of the modern understanding of neuronal behaviour and constitutes one of the (rare) undisputed classics of mathematical biology. It is also relatively simple — certainly in comparison to the models I have to work with, which are themselves mere lightweights next to some of the bullshit monstrosities people concoct in the name of Systems Biology.

The model consists of four differential equations, of which the following is an only marginally non-standard statement:

\begin{aligned} V’ &= \frac{I_{app} – g_K n^4 (V – V_K) – g_{Na} m^3 h (V – V_{Na}) – g_{L} (V – V_L)}{C_m} \\ m’ &= \alpha_m (1 – m) – \beta_m m \\ n’ &= \alpha_n (1 – n) – \beta_n n \\ h’ &= \alpha_h (1 – h) – \beta_h h \end{aligned}

Now, obviously, if you don’t understand the mathematical notation then this will be incomprehensible, and to describe the model completely we would need to define the terms and perhaps specify values for the parameters. Nevertheless, you can hopefully see that this is a natural way of representing a mathematical model, using a language that is both concise and expressive.

Because this is such a classic model, people often use it as an example in their modelling environments. Here it is encoded in the definition language of the system I am developing in the context of my current work:

# the four differential equations
v' = (Iapp
- gK * n^4 * (v-vK)
- gNa * m^3 * h * (v-vNa)
- gL * (v-vL)) / Cm
m' = am * (1-m) - bm * m
n' = an * (1-n) - bn * n
h' = ah * (1-h) - bh * h

# intermediate variables
am = 0.1 * (25-v) / (exp((25-v)/10)-1)
bm = 4 * exp(-v/18)
ah = 0.07 * exp(-v/20)
bh = 1/(1 + exp((30-v)/10))
an = 0.01 * (10-v)/(exp((10-v)/10)-1)
bn = 0.125 * exp(-v/80)

# default initial values
v := 0.804
m := 0.0582
n := 0.33
h := 0.568
gK := 36
vK := -12
gNa := 120
vNa := 115
gL := 0.3
vL := 10.6
Iapp := 1
Cm := 1


(The software, BCMD, is still at the alpha stage, but quite usable. At some point in the near future it’ll get a more public release — I’ll post a link when that happens.)

Note that the version above includes some additional equations and parameters, and even some sparse comments for visual clarity. It would be possible to omit these things, but they have to be defined somewhere and here’s as good a place as any. (The parameter values are, of course, not binding and can be overridden at runtime if desired.)

Here’s the same model as represented in the predecessor to my system, BRAINCIRC, which has been in (admittedly specialised) use in my department for the last decade or so:

MODULE: Hodgkin-Huxley
******
DIFFEQS
name: eq4_20
keyvar: v
lterm: 1.0, v
rterm: (-gK*pow(n, 4)*(v-vK)-gNa*pow(m, 3)*h*(v-vNa)-gL*(v-vL)+Iapp)/Cm
******
name: eq4_21
keyvar: m
lterm: 1.0, m
rterm: am*(1-m)-bm*m
******
name: eq4_22
keyvar: n
lterm: 1.0, n
rterm: an*(1-n)-bn*n
******
name: eq4_23
keyvar: h
lterm: 1.0, h
rterm: ah*(1-h)-bh*h
******
endDIFFEQS
******
VARS
v	v_init
m	m_init
n	n_init
h	h_init
endVARS
******
TEMPVS
am	0.1*(25.0-v)/(exp((25.0-v)/10.0)-1.0)
bm	4.0*exp(-v/18.0)
ah	0.07*exp(-v/20.0)
bh	1.0/(exp((30.0-v)/10.0)+1.0)
an	0.01*(10.0-v)/(exp((10.0-v)/10.0)-1.0)
bn	0.125*exp(-v/80.0)
endTEMPVS
******
PARAMS
v_init	0.0
m_init	0.0
n_init	0.0
h_init	0.0
gK	0.0
vK	0.0
gNa	0.0
vNa	0.0
gL	0.0
vL	0.0
Iapp	0.0
Cm	0.0
endPARAMS
******
endMODULE


BRAINCIRC is a horrible piece of software, as programs written by scientists sadly often are. It is opaque and brittle and borderline unusable, and reading the source code made me want to stab my own eyes out with a fork — a significant fraction of the despair attending my first few months in MedPhys resulted from floundering through this fucking quagmire. The parser is unspeakable garbage from bottom to top, and the definition language is much more verbose than it needs to be, and incredibly fragile, and in certain respects just facepalmingly stupid — for example, although the parameters have to be given values, they don’t actually get used, they just constitute a kind of type declaration — there’s a whole separate file, with a subtly different syntax, that you need to create to actually initialise the wretched things — but it is at least readable. The syntax gets in the way of seeing what’s going on, but doing so is not outright impossible.

If you have any familiarity with the field, you might be able to guess what’s coming. Either way, brace yourselves, because it’s not pretty.

Here is the Hodgkin-Huxley model implemented in SBML — the Systems Biology Markup Language, an attempt to create a lingua franca for models like this. I’ve taken out the optional notes and annotations — which are of course wrapped up in their own stupid syntactic legislation and add hundreds more lines of unfathomable bollocks to this deluge of textual diarrhœa — so while this is certainly not the most minimal representation possible, as these things go it’s actually sparse:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<sbml xmlns="http://www.sbml.org/sbml/level2/version3" level="2" metaid="metaid_000001" version="3">
<model id="hhsa_1952" name="hodgkin-huxley squid-axon 1952" metaid="metaid_0000002">
<listOfUnitDefinitions>
<unitDefinition id="time" name="millisecond" metaid="metaid_0000003">
<listOfUnits>
<unit scale="-3" metaid="_922669" kind="second" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="mV" name="mV" metaid="metaid_0000050">
<listOfUnits>
<unit scale="-3" metaid="_922681" kind="volt" />
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment id="unit_compartment" name="unit_compartment" metaid="metaid_0000032" size="1" />
</listOfCompartments>
<listOfParameters>
<parameter id="V" constant="false" name="V" metaid="metaid_0000010" value="0" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="V_neg" constant="false" name="V_neg" metaid="metaid_0001011" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="E" constant="false" name="E" metaid="metaid_0001010" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="I" name="I" metaid="metaid_0000011" value="0">
</parameter>
<parameter id="i_Na" constant="false" name="i_Na" metaid="metaid_0000012">
</parameter>
<parameter id="i_K" constant="false" name="i_K" metaid="metaid_0000013">
</parameter>
<parameter id="i_L" constant="false" name="i_L" metaid="metaid_0000014">
</parameter>
<parameter id="m" constant="false" name="m" metaid="metaid_0000015" value="0.052932">
</parameter>
<parameter id="h" constant="false" name="h" metaid="metaid_0000016" value="0.59612">
</parameter>
<parameter id="n" constant="false" name="n" metaid="metaid_0000017" value="0.31768">
</parameter>
<parameter id="E_R" name="E_R" metaid="metaid_0000018" value="-75" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="Cm" name="Cm" metaid="metaid_0000019" value="1" sboTerm="SBO:0000258">
</parameter>
<parameter id="g_Na" name="g_Na" metaid="metaid_0000020" value="120" sboTerm="SBO:0000257">
</parameter>
<parameter id="g_K" name="g_K" metaid="metaid_0000021" value="36" sboTerm="SBO:0000257">
</parameter>
<parameter id="g_L" name="g_L" metaid="metaid_0000022" value="0.3" sboTerm="SBO:0000257">
</parameter>
<parameter id="E_Na" name="E_Na" metaid="metaid_0000023" value="-190" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="E_K" name="E_K" metaid="metaid_0000024" value="-63" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="E_L" name="E_L" metaid="metaid_0000025" value="-85.613" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="V_Na" constant="false" name="V_Na" metaid="metaid_0001023" value="-115" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="V_K" constant="false" name="V_K" metaid="metaid_0001024" value="12" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="V_L" constant="false" name="V_L" metaid="metaid_0001025" value="-10.613" sboTerm="SBO:0000259" units="mV">
</parameter>
<parameter id="alpha_m" constant="false" name="alpha_m" metaid="metaid_0000026">
</parameter>
<parameter id="beta_m" constant="false" name="beta_m" metaid="metaid_0000027">
</parameter>
<parameter id="alpha_h" constant="false" name="auxiliary alpha_h" metaid="metaid_0000028">
</parameter>
<parameter id="beta_h" constant="false" name="beta_h" metaid="metaid_0000029">
</parameter>
<parameter id="alpha_n" constant="false" name="alpha_n" metaid="metaid_0000030">
</parameter>
<parameter id="beta_n" constant="false" name="beta_n" metaid="metaid_0000031">
</parameter>
</listOfParameters>
<listOfRules>
<assignmentRule metaid="metaid_0001135" variable="V_neg">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<ci>
V
</ci>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000135" variable="E">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<plus />
<ci>
V
</ci>
<ci>
E_R
</ci>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000035" variable="V_L">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<ci>
E_L
</ci>
<ci>
E_R
</ci>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000041" variable="beta_n">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<cn>
0.125
</cn>
<apply>
<exp />
<apply>
<divide />
<ci>
V
</ci>
<cn>
80
</cn>
</apply>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000038" variable="alpha_h">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<cn>
0.07
</cn>
<apply>
<exp />
<apply>
<divide />
<ci>
V
</ci>
<cn>
20
</cn>
</apply>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000033" variable="V_Na">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<ci>
E_Na
</ci>
<ci>
E_R
</ci>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000034" variable="V_K">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<ci>
E_K
</ci>
<ci>
E_R
</ci>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000043" variable="i_K">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<ci>
g_K
</ci>
<apply>
<power />
<ci>
n
</ci>
<cn>
4
</cn>
</apply>
<apply>
<minus />
<ci>
V
</ci>
<ci>
V_K
</ci>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000042" variable="i_Na">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<ci>
g_Na
</ci>
<apply>
<power />
<ci>
m
</ci>
<cn>
3
</cn>
</apply>
<ci>
h
</ci>
<apply>
<minus />
<ci>
V
</ci>
<ci>
V_Na
</ci>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000044" variable="i_L">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<ci>
g_L
</ci>
<apply>
<minus />
<ci>
V
</ci>
<ci>
V_L
</ci>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000037" variable="beta_m">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times />
<cn>
4
</cn>
<apply>
<exp />
<apply>
<divide />
<ci>
V
</ci>
<cn>
18
</cn>
</apply>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000040" variable="alpha_n">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide />
<apply>
<times />
<cn>
0.01
</cn>
<apply>
<plus />
<ci>
V
</ci>
<cn type="integer">
10
</cn>
</apply>
</apply>
<apply>
<minus />
<apply>
<exp />
<apply>
<divide />
<apply>
<plus />
<ci>
V
</ci>
<cn type="integer">
10
</cn>
</apply>
<cn type="integer">
10
</cn>
</apply>
</apply>
<cn type="integer">
1
</cn>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000036" variable="alpha_m">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide />
<apply>
<times />
<cn>
0.1
</cn>
<apply>
<plus />
<ci>
V
</ci>
<cn type="integer">
25
</cn>
</apply>
</apply>
<apply>
<minus />
<apply>
<exp />
<apply>
<divide />
<apply>
<plus />
<ci>
V
</ci>
<cn type="integer">
25
</cn>
</apply>
<cn type="integer">
10
</cn>
</apply>
</apply>
<cn type="integer">
1
</cn>
</apply>
</apply>
[/itex]
</assignmentRule>
<assignmentRule metaid="metaid_0000039" variable="beta_h">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide />
<cn type="integer">
1
</cn>
<apply>
<plus />
<apply>
<exp />
<apply>
<divide />
<apply>
<plus />
<ci>
V
</ci>
<cn type="integer">
30
</cn>
</apply>
<cn type="integer">
10
</cn>
</apply>
</apply>
<cn type="integer">
1
</cn>
</apply>
</apply>
[/itex]
</assignmentRule>
<rateRule metaid="metaid_0000048" variable="V">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide />
<apply>
<minus />
<ci>
I
</ci>
<apply>
<plus />
<ci>
i_Na
</ci>
<ci>
i_K
</ci>
<ci>
i_L
</ci>
</apply>
</apply>
<ci>
Cm
</ci>
</apply>
[/itex]
</rateRule>
<rateRule metaid="metaid_0000045" variable="m">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<apply>
<times />
<ci>
alpha_m
</ci>
<apply>
<minus />
<cn>
1
</cn>
<ci>
m
</ci>
</apply>
</apply>
<apply>
<times />
<ci>
beta_m
</ci>
<ci>
m
</ci>
</apply>
</apply>
[/itex]
</rateRule>
<rateRule metaid="metaid_0000046" variable="h">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<apply>
<times />
<ci>
alpha_h
</ci>
<apply>
<minus />
<cn>
1
</cn>
<ci>
h
</ci>
</apply>
</apply>
<apply>
<times />
<ci>
beta_h
</ci>
<ci>
h
</ci>
</apply>
</apply>
[/itex]
</rateRule>
<rateRule metaid="metaid_0000047" variable="n">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<minus />
<apply>
<times />
<ci>
alpha_n
</ci>
<apply>
<minus />
<cn>
1
</cn>
<ci>
n
</ci>
</apply>
</apply>
<apply>
<times />
<ci>
beta_n
</ci>
<ci>
n
</ci>
</apply>
</apply>
[/itex]
</rateRule>
</listOfRules>
</model>
</sbml>


Like many such projects, SBML is based on XML, the Extensible Markup Language. Like many such projects, it inherits from XML a catastrophic burden of irredeemable wrongness.

Here is a lightly-edited version of the Wikipedia XML introduction, with some emphasis added by me:

Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. It is defined in the XML 1.0 Specification produced by the W3C, and several other related specifications, all free open standards.

The design goals of XML emphasise simplicity, generality, and usability over the Internet. […] Although the design of XML focuses on documents, it is widely used for the representation of arbitrary data structures, for example in web services.

Many application programming interfaces (APIs) have been developed to aid software developers with processing XML data, and several schema systems exist to aid in the definition of XML-based languages.

As of 2009, hundreds of document formats using XML syntax have been developed, including RSS, Atom, SOAP, and XHTML. XML-based formats have become the default for many office-productivity tools, including Microsoft Office (Office Open XML), OpenOffice.org and LibreOffice (OpenDocument), and Apple’s iWork. XML has also been employed as the base language for communication protocols, such as XMPP.

The highlighted goals seem laudable and, on the face of it, the widespread adoption and plethora of applications would suggest an admirable success. Au contraire, mon frère: the goals are fundamentally misguided, the promises illusory and the laundry list of users and myriad implementations is a litany of despair.

I contend that this stuff is a cancerous blight on the information landscape, which is doing active harm to us all. While that statement is harsh, it is also so obviously and implacably true that I shouldn’t even have to justify it. Yet there are whole armies of otherwise seemingly intelligent people who buy into this bollocks, so let’s take it point by point. I’m sorry. I shall at least try — unlike the W3C in any situation ever — to be as brief as I can.

Most of the claims about readability, simplicity and Internet-suitability boil down to the format being based on plain text. But text is, as a glance at the above SBML should confirm, not readable per se. Finnegan’s Wake is in text. Messages encrypted by the Enigma machine were in text. The XML specification is in text, and about as readable as either of those others. Text may be readable, but if so it is readable because its content is readable, because it is written and constructed with clarity. This is a trivial point, but it demonstrates in miniature the metonymic fallacy that underlies the entire XML project: it misidentifies the problem at every turn, then makes that misidentified problem the focus of attention. In so doing, it actively obstructs the finding of a solution to the actual problem, which lies elsewhere.

It is important to point out that XML is, by intent — it’s even right there in the name — a markup language. It is designed to annotate documents where the majority of the information is conveyed in the text. This is a valid use case, and XML’s solution is also valid, if largely vacuous. It’s not a very interesting or difficult problem, and XML is not a very interesting or admirable solution, but you know, it’s okay.

Naturally, that is not what it’s used for. At least, it’s not the kind of use that seems to predominate, and against which I am fulminating here. Revisiting that Wikipedia intro:

Although the design of XML focuses on documents, it is widely used for the representation of arbitrary data structures, for example in web services.

This is the where the problem really arises, and it’s essentially an everything is a nail issue: people think XML = structured data, which is absolutely wrong, and use it for that, and then things go to hell in a handcart. It is possible to represent structured data with XML, but it isn’t what it’s for, it doesn’t do it well, and it’s bad for everyone when you do.

(The reasons XML has become the misshapen lump hammer with which everyone bangs in delicate screws are sociological rather than technical, and (ISTM) can mostly be found in the explosive success of the World Wide Web in the late 1990s. Unlike XML, HTML actually has some well-defined purpose and meaning, but they look kind of similar, use the same kind of tag structure, and when the whole dot com boom was at its boomiest, lo! There was XML, looking coyly fashionable and batting a beaded lash. (Needless to say, HTML too has suffered the curse of XML-ification, although at least in that case it wasn’t a huge stretch.) Soon there were web services, and SOAP and, well, there went the fucking neighbourhood.)

Now you could argue that this means it’s not XML’s fault it’s such a plague. If people would only use it for the purpose for which it was designed, we’d all be happy. And that would be a reasonable argument. But I think it would also be wrong.

The fundamental category mistake underlying the whole XML project is this: it treats syntax as the important problem.

From this simple error, all else proceeds. XML offers itself as a solution to that problem. And because XML is so ugly and complicated, everyone agrees that it must indeed be solving a very difficult problem. And that the solving of that problem must be important.

And then, catastrophically, XML’s approach to that problem — which is all about syntactical correctness and explicitly disavows any question of meaning — becomes primary. A zillion tools spring up to deal with the horrors of XML syntax, which we need, because XML is a bottomless well of nitpickery, but which are not actually doing anything useful, because all that syntax doesn’t serve any real purpose. It’s just bureaucratic pettifogging busywork, functioning, inevitably if not intentionally, to obscure the simple truth:

SYNTAX IS EASY, IT’S SEMANTICS THAT’S TOUGH.

Ultimately, my beef with XML is not just that it is ugly and verbose and inefficient and stupid and misused. It’s not just that the tools are horrible to work with and the parsing is no easier than with lex and yacc, and the claims of readability only not laugh-out-loud funny because they’re so tragic. It’s that after all that, if you invest the time and effort, and you’ve got a perfectly marked-up, syntactically flawless document that, say, obtusely expresses something as concise as a mathematical equation as a hundred nested, attribute-bedecked elements, you’re still no closer to a solution to your problem because none of that was ever the fucking problem in the first place.

In the end, your real problem remains exactly as it was. At best, all you’ve done is dressed things up in filthy rags. But more likely you’re actually further from a solution than you were at the start, because now the whole thing is more opaque. The wood is hidden by neatly-hierarchical tag trees.

Clarity of representation is, if not actually a prerequisite for clarity of thought, at the very least a significant aid to it. XML is the apotheosis of lack of clarity in both.

And it’s everywhere. Crawling over the entire infosphere like a plague of flesh-eating slugs, blighting the minds of generations of scientists and technologists and creators and of society at large. It is a conspiracy of fossilising idiocy that acts to replace the capacity to think with the technocratic equivalent of poring over holy scriptures, impossible to argue with not by virtue of its truth or value but just because of the sheer fucking overwhelming weight of it.

There is no excuse for this bullshit.

It is time to declare war on empty syntax. Way past time, in fact. It will be a long and ugly fight, but reason can prevail. You can do your bit. Refuse to be a part of the problem. Stand up for what is right.

JUST SAY NO to XML.

## MathJax Test

This should hopefully be rendered inline: $\frac{E}{mc^2} + e^{i \pi} = 0$. And this might conceivably be rendered as display:

$$P(\mathbf{\theta|x}) = \frac{P(\mathbf{x|\theta}) P(\mathbf{\theta)}}{P(\mathbf{x})}$$

Well whoop-de-doo.

(This does not mean I am necessarily going to blog some science.)

## Rubicon

So after all that angsting, things finally reached a head at work last week. (I say “finally”; it’s sometimes hard to remember that I only started a couple of months ago. It has certainly felt like a long time.) Anyway, the ensuing meetings and negotiations and weeping and rending of garments, over the course of several days, can be loosely summed up as:

M: The models are horrible and I can’t take it anymore!

PI: So make something better. It’s your research.

M: But I don’t know if I can!

PI: Pfft. Nobody does. Don’t be such a wuss.

I paraphrase, obviously. Everything was couched in politeness and hedged around with ifs and buts. But the upshot is I got called chicken, and, like Marty McFly, just couldn’t walk away.

This doesn’t seem to me like a conversation one can have more than once, so I guess I’m in it for the long term after all. And since I’ve effectively been authorised to do whatever is necessary to get things on a sounder footing, I now have no choice but to put my metaphorical money where my proverbial mouth is and sort it the fuck out.

In a future post, I may try to explain what that entails. In the meantime: Eek!

## Migration

Well stone me, here we go again.

Things are going to be in flux around here for awhile. I finally had enough of the unmitigated uselessness of my previous web hosts (CWI hosting — I mention them in the spirit of naming and shaming, please avoid them like the fucking plague) and decided it was time to up sticks. New hosts seem well-regarded — time will tell, but so far, so good.

And since it is wearisome indeed to set up and run one’s own installation of long-outdated and generally frowned-upon blogging software, I’ve decided to bite the bullet and move to an officially-sanctioned version of WordPress. Yeah, finally falling into line with the rest of the internet.

All previous WT incarnations will be kept online, at least when I get around to putting them up in a vaguely useable form — it’s broken links a-go-go at the moment. They’ll be read only, of course, but it’s not as if anyone was actually commenting anymore anyway.

Whether this move will be accompanied by a meaningful increase in posting remains to be seen — I wouldn’t bet on it — but at least it’s a change of scenery…