31 January 2008

The Nouns of Names on NEXUS

Programming is a mystery to most folks. They see a bunch of overpunctuated gobbledygook with words strewn about here and there and it's completely opaque. They know that it somehow translates into the functionality of the applications, games, websites, etc. that they use. But they have no inroads to understanding how on Earth that works.

I will now attempt a (very) partial explanation for the phylogenetics-literate crowd.

One thing people don't understand is that object-oriented computer languages (which is what I primarily use) are actually designed to be compatible with how humans think. Or at least, they're a sort of compromise between how computers think and how humans think. Natural languages, of course, are totally biased toward how humans think, while machine codes (and their slightly dressed-up cousins, assembly languages) are totally biased toward how computers think. (There are also functional languages which are slightly more computer-biased than object-oriented languages.)

Like natural languages, object-oriented languages have nouns, except they're called objects. They also have verbs, except they're called methods. Methods are usually (but not always) attached to objects. Objects can have attributes which are themselves other objects—these are called fields, and they can work a bit like adjectives (although that's not a perfect analogy).

One of the first tasks I do as a programmer when approaching a new project is to figure out what the nouns of the project are. These will be used as the basis for classes, which are the templates which objects (and their methods and fields) are created from.

So let's use Names on NEXUS as an example. This is my project, hinted at in my paper, to relate the data in NEXUS files (Maddison et al. 1997) to definitions of names as governed by the PhyloCode. So my first step is to come up with lists of nouns (i.e., class candidates) for each side of the equation:

PhyloCode (nomenclature)scientific name (or nomen), uninomen, binomen, prenomen, genus name, clade name, phylonym, definition
PhyloCode (specification)specifier, species, specimen, specimen collection, specimen accession, apomorphy, definition
NEXUSNEXUS file, tree, tree element, tree node, tree terminus, character state
sharedphylogeny, citation, piece of literature, calendar date, URI

The goal of this project is to translate a PhyloCode definition (associated with a phylonym) into a list of NEXUS taxa (i.e., operational taxonomic units) using a NEXUS tree. For that to happen, there need to be some additional nouns that help relate NEXUS entities to PhyloCode entities:

Names on NEXUScharacter state specifier, taxon specifier, character state link, taxon link

The next step is to figure out how these nouns—these classes—relate to each other. Typically, this involves statements of the form "X is a Y" (which has to do with class hierarchy) and the forms "X has a Z", "X has one or more Zs", "X has zero or more Zs", etc. (which have to do with fields). I'll also translate these nouns into capitalized "camel-humped" format, the standard format for class names in the languages I use. Lower-case "camel-humped" nouns are of primitive types (numbers, strings, Booleans) which I don't need to make a class for.

  • A LiteraturePiece has a CalendarDate, one or more authorNames, and zero or more URIs.
  • A Citation has a LiteraturePiece and zero or more authorNames.

PhyloCode: Nomenclature
  • A Nomen has a Citation, an orthography, and zero or more URIs.
  • A Uninomen is a Nomen.
  • A Binomen is a Nomen and a Phylonym, and has a Prenomen and a Uninomen.
  • A GenusName is a Uninomen and a Prenomen.
  • A CladeName is a Uninomen, a Phylonym, and a Prenomen.
  • A PhyloDefinition has a Citation, a Phylonym, one or more Specifiers, a prose statement, and a mathML statement(see my paper for details on the last one).

PhyloCode: Specification
  • A Specifier has zero or more URIs.
  • An Apomorphy is a CharStateSpecifier, and has a description and a Citation.
  • A Specimen is a TaxonSpecifier, and has one or more SpecimenAccessions.
  • A SpecimenAccession has a code and a SpecimenCollection.
  • A SpecimenCollection has a code, a name, and zero or more URIs.
  • A Species is a TaxonSpecifier, and has one or more Binomens (binomina) and one or more Specimens (name-bearing types).

  • A NexusFile has textData, zero or one Citations, zero or more URIs, a numTaxa amount, a numChars amount, two or more CharStates, zero or more Trees, zero or more CharStateLinks, and zero or more TaxonLinks.
  • A CharState has a character index and a character scoring.
  • A Tree has a TreeNode.
  • A TreeNode is a TreeElement and has two or more TreeElements.
  • A TreeTerminus is a TreeElement and has a taxonIndex.

Names on NEXUS
  • A CharStateSpecifier is a Specifier.
  • A TaxonSpecifier is a Specifier.
  • A CharStateLink has a CharState and a CharStateSpecifier.
  • A TaxonLink has a taxonIndex and a TaxonSpecifier.

Now I can describe the core functionality of Names on NEXUS. Taking a NexusFile, the user selects one of its Trees. Next, the application finds all PhyloDefinitions whose Specifiers are each referred to by one of the NexusFile's CharStateLinks or TaxonLinks. Using the Tree and each PhyloDefinition's mathML statement, it correlates the PhyloDefinition's Phylonym to a set of taxon indices in the NexusFile.

Of course, this is not all the application will do. (In fact, I've been done with that part of the programming for a while now.) There will also need to be a lot of programming for saving these data permanently in a database, presenting the data to the user, and making it easier for the user to enter data (for example, by creating methods for coming up with specifier suggestions based on definition statements). This may take a while....

24 January 2008

The Mystery of the Platypus

No, I'm not talking about the usual mysteries of platypuses* (Ornithorhynchus anatinus). Not the electrosensitive bill, not the egg-laying, not the beaver-like tail, not the poisonous ankle spurs on males, and not the fact that females have no nipples but simply sweat milk out onto their bellies. (In fact, most of those aren't terribly mysterious at all—except for the bills and the tails, they're just ancestral traits for mammals.) Instead, today's mystery is: How long have platypuses been around, anyway?

Skeleton of a platypus, Ornithorhynchus anatinus, at the Melbourne Museum. Photo by Peter Halasz.

And the reason I bring it up is because there is a new paper on the subject:

Rowe, T., T. H. Rich, P. Vickers-Rich, M. Springer and M. O. Woodburne (2008 January 29). The oldest platypus and its bearing on divergence timing of the platypus and echidna clades. PNAS 105(4):1238–1242. doi:10.1073/pnas.0706385105

It's not in print yet (hence the futuristic date), but it's been posted online. (Free access! Yes!)

The answer turns out to be rather bewildering. Well, first, let me clarify that I am actually asking how long stem-platypuses have been around. Platypuses proper (i.e., the crown group) have presumably not been around that long, but their ancestors go back to some time when the platypus lineage joins the lineage of echidnas (Tachyglossidae, a.k.a. spiny anteaters), an equally bizarre type of living, egg-laying mammal. Their final common ancestor, the ancestral monotreme, turns out to be difficult to pin down.

Rowe et al. review several molecular clock studies which have suggested a wide variety of dates for the origin of Monotremata, the platypus-echidna clade, from 17 to 131 million years ago. They can't even agree on whether one or two pan-monotreme lineages survived the Cretaceous-Paleogene extinction event (about 65 million years ago). Some of the more reliable estimates are older, but Rowe et al. consider the oldest dates to be most likely.

Why? Teinolophos trusleri.

Volumetric reconstruction of NMV P216750, a Teinolophos trusleri rigth dentary. From Rowe et al. 2008.

This is a fossil species from 112.5 to 121 million years ago. It's usually regarded as a stem-monotreme, meaning that it would have no bearing on the platypus-echidna split. But Rowe et al. have done a morphology-based cladistic analysis that places it as a stem-platypus, the oldest one known. (They also find Steropodon galmani, a 110-million year old fossil based on an opalized jaw, to be a stem-platypus.) They also consider that it was ecologically platypus-like, i.e., that it was amphibious.

This would mean that things like platypuses were swimming around in the Early Cretaceous, under the snouts of gigantic dinosaurs. It would also mean that the echidna and platypus lineages had diverged well before the Cretaceous-Paleogene extinction, perhaps sometime around the Jurassic-Cretaceous boundary. So any theory as to the cause of the extinction would have to allow for both stem-echidnas and stem-platypuses to survive, instead of a single stem-monotreme lineage.

It also means that many of the molecular analyses would be quite wrong. And even the more correct ones would be just barely right. This means one of two things:
  1. Monotreme evolution is much slower than that of other mammals, and molecular clock studies are based on presumed rates that are too fast.
  2. Rowe et al. are wrong, and Teinolophos is a stem-monotreme, not a stem-platypus.

As for #2, Teinolophos is only known from jaw material, and echidnas do have highly modified, toothless jaws. If #2 is true, then echidnas would have evolved from a somewhat platypus-like ancestor, an intriguing possibility. (In fact, that could be the case even if #2 is not true.)

But #1 is perfectly possible as well. As the authors note, it might help explain why there are a thousand times more therian mammals than monotreme mammals alive today. (Theria is the crown group that includes marsupials and placentals, i.e., all living mammals apart from monotremes.) Molecular clock estimates are notoriously sketchy. Only further evidence (e.g., Mesozoic monotreme fossils) will help clarify the situation.

* No, the plural is not "platypi". If you want to be fancy and use the proper classical plural, it's "platypodes" (like "Antipodes"). But who wants to be that fancy?

21 January 2008

How to Extend "Event", Once and For All

I've seen this information spread out in a bunch of different places online, but not in one place. So here you go:

The event-dispatching functionality in ActionScript 3.0 is wonderful. It creates a new paradigm for programming, one focused less on branching flowcharts and more on organic interactivity.

I'm assuming anyone reading this is familiar with how to use native events (e.g., addEventListener(Event.ENTER_FRAME, update); and all that good stuff). But there are a few "gotchas" when it comes to making custom events. There are also some good practices that are a bit obscure.

Say you want to make a special type of event that indicates an index number, in addition to the normal information (type, target, etc.). You might think that all you had to do is this:

package tld.myproject.events {

import flash.events.Event;

public class IndexEvent extends Event {

public function IndexEvent(type:String, index:uint, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_index = index;

private var _index:uint;

public function get index():uint {
return _index;



Tip #1. You must override flash.events.Event.clone().

This is the big one. If you don't override clone, then there is no guarantee that listeners will receive the right kind of event. This method is used during dispatching to ensure that all listeners receive the same (i.e., unchanged) information. By default, Event.clone() simply returns a basic Event object, so if you don't override clone to return your custom event type, listeners may not be able to access your custom event data, and you will probably get type errors and null pointer exceptions.

Here's how to override clone for IndexEvent:

package tld.myproject.events {

import flash.events.Event;

public class IndexEvent extends Event {

public function IndexEvent(type:String, index:uint, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_index = index;

private var _index:uint;

public function get index():uint {
return _index;

override public function clone():Event {
return new IndexEvent(type, index, bubbles, cancelable);



Tip #2: You should override flash.events.Event.toString()

This one is not as important, since toString is only used for debugging. (Or should only be used for debugging, anyway.) But the default method will not report the type of the event, and will also not report custom data. It'll just show something like [Event type="select" bubbles=true cancelable=false eventPhase=2].

For this reason, it's a good idea to override the default method. Fortunately, there is a method called formatToString that makes it much easier to generate a standardized event string. Al arguments passed are strings. The first one should be the name of the custom event class, and the rest should be the names of all fields that you want reported in the string. Here's an example:

package tld.myproject.events {

import flash.events.Event;

public class IndexEvent extends Event {

public function IndexEvent(type:String, index:uint, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_index = index;

private var _index:uint;

public function get index():uint {
return _index;

override public function clone():Event {
return new IndexEvent(type, index, bubbles, cancelable);

override public function toString():String {
return formatToString("IndexEvent", "type", "index", "bubbles", "cancelable", "eventPhase");



This will produce a much more informative string, something like [IndexEvent type="select" index=12 bubbles=true cancelable=false eventPhase=2]. (Sometimes I even omit some of the base Event fields. For example, if my custom event's constructor doesn't allow for cancelable events, I might leave "cancelable" out of the formatToString call.)

Tip #3. You should include static constants for event types.

The base Event class and all of Adobe's Event subclasses do this, e.g., Event.ENTER_FRAME, TextEvent.LINK, etc. The main reason for this is so that programmers can catch typos at compile-time rather than run-time. Typing addEventListener("enerFrame", update) won't generate a compile-time error, or even a run-time error -- your code will just fail silently. But addEventListener(Event.ENER_FRAME, update) will flag a compile-time error. For this reason, it's a good idea to follow in Adobe's footsteps and make your own constants:

package tld.myproject.events {

import flash.events.Event;

public class IndexEvent extends Event {

public function IndexEvent(type:String, index:uint, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_index = index;

public static const SELECT:String = "select";

public static const UNSELECT:String = "unselect";

private var _index:uint;

public function get index():uint {
return _index;

override public function clone():Event {
return new IndexEvent(type, index, bubbles, cancelable);

override public function toString():String {
return formatToString("IndexEvent", "type", "index", "bubbles", "cancelable", "eventPhase");



Ideally, these should be commented with ASDoc like so:

* The <code>IndexEvent.SELECT</code> constant defines the value of the <code>type</code> property of the event object for a <code>select</code> event.
* <p>
* The properties of the event object have the following values:
* </p>
* <table class="innertable">
* <tr><th>Property</th> <th>Value</th></tr>
* <tr><td><code>type</code></td> <td><code>"select"</code></td></tr>
* <tr><td><code>bubbles</code></td> <td>A Boolean value.</td></tr>
* <tr><td><code>cancelable</code></td> <td>A Boolean value.</td></tr>
* <tr><td><code>index</code></td> <td>An unsigned integer.</td></tr>
* </table>
* @eventType select

public static const SELECT:String = "select";

(Admittedly, I usually don't bother to do this, but....)

Tip #4. You should add metadata to your dispatchers.

Although metadata is not, strictly speaking, necessary, it's good practice for the following reasons:
  1. It allows other programmers (or you yourself, for that matter) to see at a glance which event types the dispatcher class is supposed to dispatch.
  2. It allows events to be documented with ASDoc, so that documentation can be automatically generated.
  3. In some code editors (Flex and [I think] FlashDevelop), it enables autocomplete, which is pretty nice.
  4. In Flex, it can allow binding.

Here's an example of a class that dispatches IndexEvent objects:

package tld.myproject.control {

import flash.events.EventDispatcher;
import tld.myproject.events.IndexEvent;

[Event(name="select", type="tld.myproject.events.IndexEvent")]

[Event(name="unselect", type="tld.myproject.events.IndexEvent")]

public class IndexController extends EventDispatcher {

public function IndexController() {

private var _index:uint;

public function get index():uint {
return _index;
public function set index(value:uint):void {
if (_index != value) {
var oldValue:uint = _index;
_index = value;
dispatchEvent(new IndexEvent(IndexEvent.UNSELECT, oldValue));
// This test ensures that the event is not dispatched if some listener to "unselect" has changed the value.
if (_index == value) {
dispatchEvent(new IndexEvent(IndexEvent.SELECT, value));



(Incidentally, if you were programming this class in MXML, the {Event(...)] metadata would go inside an <mx:Metadata/> section.)

With this metadata in place, we can now document the events:

* Dispatched when the <code>index</code> field changes.
* <p>
* The <code>index</code> field of the event object indicates the new value.
* </p>
* @eventType tld.myproject.events.IndexEvent.SELECT
* @see #index

[Event(name="select", type="tld.myproject.events.IndexEvent")]
* Dispatched when the <code>index</code> field changes.
* <p>
* The <code>index</code> field of the event object indicates the old value.
* </p>
* @eventType tld.myproject.events.IndexEvent.UNSELECT
* @see #index

[Event(name="unselect", type="tld.myproject.events.IndexEvent")]

Note that the @eventType ASDoc attribute indicates the constant that specifies the event type. (It can also indicate a plain string, but, per Tip #3, you should use constants anyway.)

We can also use autocomplete in Flex. if ctrl is an instance of IndexController, then typing ctrl.a will bring up a list of options including:
  • ctrl.addEventListener(IndexEvent.SELECT,
  • ctrl.addEventListener(IndexEvent.UNSELECT,
... keeping you from having to laboriously type out either one.

And we can bind to the value of index in MXML:
<control:IndexController id="ctrl"/>
<mx:ViewStack selectedIndex="{ctrl.index}">
<!-- child objects -->

The ViewStack object's selectedIndex field will now auto-update whenever ctrl dispatches a select event (per the Bindable metadata element -- note that multiple such elements may precede a property, if there are different trypes of event that signal the value changing).

Tip #5. You don't always have to extend flash.events.Event.

Sometimes it's fine to use a plain old Event instance! There are plenty of generic event types (e.g., Event.CANCEL) associated with it, and often that's all you really need. Even if you want a type that doesn't have a constant, you don't have to create a custom event type for it. The constant can be housed elsewhere. For example:

package tld.myproject.control {

import flash.events.Event;
import flash.events.EventDispatcher;

* Dispatched when the process this object controls begins.
* @eventType tld.myproject.control.ProcessController.EVENT_START


public class ProcessController extends EventDispatcher {

* The <code>ProcessController.EVENT_START</code> constant defines the value of the <code>type</code> property of the event object for a <code>start</code> event.
* <p>
* The properties of the event object have the following values:
* </p>
* <table class="innertable">
* <tr><th>Property</th> <th>Value</th></tr>
* <tr><td><code>type</code></td> <td><code>"start"</code></td></tr>
* <tr><td><code>bubbles</code></td> <td><code>false</code></td></tr>
* <tr><td><code>cancelable</code></td> <td><code>false</code></td></tr>
* </table>
* @eventType start

public static const EVENT_START:String = "start";

public function startProcess():void {
dispatchEvent(new Event(EVENT_START));



As long as the ASDoc comment with the @eventType attribute is included, Flex will autocomplete for the start event as well.

As a general rule of thumb, if you don't need the event object to carry extra data, you don't need to create a custom event class. Even if you do, there may be another subclass already in existence that suits your needs (e.g., TextEvent, ErrorEvent, etc.). On the other hand, though, if you do create a custom class with no added fields, it may come in handy down the road if you realize that you do need added fields after all. And it might also be handy if you want to restrict how default fields like type, bubbles, and cancelable are set.

Well, I think that's about it.
dispatchEvent(new Event(Event.COMPLETE));

20 January 2008

Third Meeting of the International Society for Phylogenetic Nomenclature

The ISPN's third biennial meeting has just been officially announced.

Third Meeting of the International Society for Phylogenetic Nomenclature
Halifax, Nova Scotia, July 21 – July 23, 2008

We are pleased to announce that the 3rd Meeting of the International Society for Phylogenetic Nomenclature (ISPN) will be held in conjunction with a joint meeting of the International Society of Protistologists and the International Society for Evolutionary Protistology (https://protist2008.dal.ca/). In addition to featuring communications on the theory and practice of phylogenetic nomenclature, this meeting will be an opportunity to discuss the forthcoming release of the PhyloCode and publication of the Companion Volume, as well as development of the on-line registration database (RegNum). All systematists interested in the development of phylogenetic nomenclature are welcome. Discussions and presentations at this meeting may influence the future development of the PhyloCode.

The meeting and associated social gatherings will be held on the campus of Dalhousie University, in the centre of Halifax. In order to make the meeting accessible to all scientists, on-campus dormitory-style accommodation will be available, in addition to nearby hotels. Note that U.S. Citizens traveling to Canada will be required to carry passports.

Conference Language:

ISPN Organizing Committee:
Harold Bryant, Chair, Royal Saskatchewan Museum, Canada
Nico Cellinese, University of Florida, U.S.A.
Walter Joyce, Yale University, U.S.A.
Michel Laurin, CNRS, Paris, France

Registration and Abstract Submission:
Instructions on how to register and submit abstracts will be provided in the second circular, which will be distributed in the very near future.

For More Information:
Download the First Circular (PDF)

I'd better brush up on my protistology. Oh, and hurry up with Names on NEXUS....

16 January 2008

Vermin the Size of Cars

I have to say, I've never understood why certain animals are kept as pets. Dogs and cats I like. You can play with them. They're your buddies. But my girlfriend has four chinchillas (Andean rodents that look like grey Pikachus), and, while I suppose they're kind of cute, sometimes I fail to see the point. Sometimes I feel like we're intentionally harboring vermin.

Anyway, Bernard, Lily, Hyzenthlay, and Half-Pint might be interested (if they had larger intellects) to know that an extinct cousin of theirs was recently discovered which outweighed some of the dinkier automobiles on the road. To be more precise, Josephoartigasia monesi weighed about a metric tonne. (Well, based on allometric inferences, anyway -- only the skull is known.)

Wonderfully, the paper is freely available.

How close was it to my messy housemates? Reasonably close -- since they're both caviomorphs (a group named after the guinea pig genus), their shared ancestry goes back at furthest to the middle Oligocene, roughly 28 million years ago. (J. monesi itself is from the Pleistocene, roughly a million years ago.) But J. monesi is much closer another living South American rodent called the pacarana, Dinomys branickii. Basically, it's a stem-pacarana.

Illustrations of a) Josephoartigasia monesi and b) its close living relative, the pacarana (Dinomys branickii), to scale, by G. Lecuona. A larger version is available in the paper, linked above.

And it's not the only giant South American rodent. The type species of Josephoartigasia, J. magna, was a smaller giant, as were some other stem-pacaranas less close to pacaranas, like Phoberomys pattersoni (about 700kg) and Phoberomys insolita (even bigger, but poorly known). Even today, the largest rodent in the world is the South American capybara*, Hydrochoerus hydrochaeris, weighing up to 65 kg. And the pacarana itself is no slouch, at 15 kg.

South America was until recently host to a number of large-to-gigantic animals we'd find strange today. There were ground sloths; tank-like stem-armadillos called glyptodonts; ground-dwelling killer birds called phorusrhacids; the aforementioned huge caviomorphs; and two groups of hoofed mammals unrelated to any of the modern groups: notoungulates, including the hippo-like Toxodon, and litopterns, including the bizarre Macrauchenia, which looked something like a llama with the head of a tapir.

On the subject of tapirs, clearly not all of the weird South American fauna has died out. While much of it seems to have been done in by invaders from North America, some of it has continued to flourish. A couple of groups, including the opossums, Didelphis, and certain armadillos, Dasypus, have even "swum against the tide" and colonized North America from South America.

And, of course, there are the four little furballs sitting in my downstairs. Oh, maybe I'll go give them some raisins -- they are kind of cute when they hold them.

Susan's cat, Caspian, at left, with one of her chinchillas, Bernard, at right. Photo by Susan Havens. (Not one of her best, but....)

* Apparently also known as the carpincho, according to the paper. Sounds kind of rude, somehow.

14 January 2008

March of Man: Information Upgrade

The information in the "Field Guide" at March of Man is fairly vague, unsubstantiated, and really just a first pass. I started to collect more complete, referenced entries in a Google Docs document:

March of Man Taxa

This is publicly viewable. If anyone wishes to help out with this (and receive credit on the March of Man website, of course), leave a comment and I'll share the document with you.

Here's a sample of one of the more complete entries so far:

Orrorin tugenensis

Time Range: 6.1 to 5.8 Mya

Author: Senut et al. 2001

Definition: The species typified by BAR 1000'00.

Synonyms: Praeanthropus tugenensis Cela-Conde and Ayala 2003

Hypodigm: at least 5 individuals -- BAR 1000a'00 (fragment of left mandible with molars 2 and 3; holotype); BAR 1000b'00 (fragment of right mandible with molar 3; holotype); BAR 349'00 (manual phalanx; paratype);
BAR 1001'00 (upper central incisor; paratype); BAR 1002'00 (left femur; paratype); BAR 1003'00 (proximal left femur; paratype); BAR 1004'00 (right humeral shaft; paratype); BAR 1215'00 (proximal right femur; paratype); BAR 1390'00 (lower 4th premolar; paratype); BAR 1425'00 (upper right canine; paratype); BAR 1426'00 (upper left 3rd molar; paratype); BAR 1900'00 (upper right 3rd molar; paratype); KNM LU 335 (lower molar; paratype)

Systematics: Originally proposed as the earliest species closer to Homo than to Australopithecus (Senut et al. 2001). However, this poses temporal difficulties, since it dates from a time when, according to genetic evidence, the human and chimpanzee lineages had only just begun to diverge, or perhaps had not diverged at all (Patterson et al. 2006). Instead it may be a very early species in the human lineage (Cela-Conde et al. 2003) or, given the timing, something close to the human-chimpanzee concestor. See: Hominini (concestor), stem-Hominini

Cranial Capacity: unknown, but probably about 350 cc

Description: Probably somewhat chimp- or bonobo-like, but with a more habitually upright posture.

Adult Female Height: 0.7 to 1m

Adult Male Height: 0.9 to 1.2m

  • Cela-Conde, C. J. and F. J. Ayala (2003). Genera of the human lineage. Proceedings of the National Academy of Sciences 100(13):7684-7689. doi:10.1073/pnas.0832372100
  • Patterson, N., D. J. Richter, S. Gnerre, E. S. Lander and D. Reich (2006 June 29). Genetic evidence for complex speciation of humans and chimpanzees. Nature 441:1103-1108. doi:10.1038/nature04789
  • Senut, B., M. Pickford, D. Gommery, P. Mein, K. Cheboi and Y. Coppens (2001). First hominid from the Miocene (Lukeino Formation, Kenya). Comptes Rendus de l'Académie de Sciences 332:137-144.

06 January 2008

My Reading List: Or, Why I Should Not Buy Any Books for the Next Two Years At Least

Yuletide has ended, and now I have even more books that I'm "currently reading" (translation: currently keeping bookmarks in). I compiled a list of the the books I've started but have not yet finished. I left out reference books, as well as my best Christmas present: Susan got me a freakishly gigantic compilation of Little Nemo in Slumberland comic strips (by Winsor McKay). The book is so large that you don't read the strips so much as enter into them, in all their meticulous detail.

I also omitted any books that are best browsed rather than read cover-to-cover, for example, The Onion's new atlas, Our Dumb World (which is pretty hilarious).

Anyway, here's the list:
  • The Amber Spyglass by Philip Pullman. I read though the first two His Dark Materials books pretty quickly last month, but I seem stuck halfway through this one. One of the key things these books have going for them is a great main character, Lyra, and she hasn't been present much in this volume so far.
  • Cocktail Time by P. G. Wodehouse. I barely started it when Susan absconded with it.
  • Collapse: How Societies Choose to Fail or Succeed by Jared Diamond. I keep reading this in spurts and am currently a little over halfway through. Very interesting, although I prefer the author's Guns, Germs, and Steel so far.
  • The Complete Gospels ed. by Robert J. Miller. I'm not sure if I should include this or not. I did read The Gospel According to Mark in its entirety (and it turns out to be written in a much more colloquial style than more "orthodox" translations indicate) and skimmed the rest, but it seems better as a reference than something to read cover-to-cover. (And for that reason I should probably return it to the friend who loaned it and buy my own durn copy.)
  • Darwin's Dangerous Idea: Evolution and the Meanings of Life by Daniel C. Dennett. Almost done with chapter two — excellent read so far.
  • Did God Have a Wife? by William G. Dever. I started reading this while visiting Scott in Wyoming. Now I have my own copy so I can finish it.
  • The Elegant Universe: Superstrings, Hidden Dimensions, and the Quest for the Ultimate Theory by Brian Greene. Got two-thirds through and then forgot about it.
  • From Lucy to Language by Donald Johanson and Blake Edgar, principal photography by David Brill. Haven't really started reading this cover-to-cover yet, but I should.
  • The Great Human Diasporas by Luigi Luca Cavalli-Sforza and Francesco Cavalli-Sforza. I've read a bit, but it seems so far to be stuff covered by other Cavalli-Sforza books I've read (although going into more detail on African pygmies).
  • How We Believe: Science, Skepticism, and the Search for God by Michael Shermer. I seem to have gotten halfway through this one and then forgot about it. I really enjoyed the author's Why People Believe Weird Things.
  • The Impact of Science on Society by Bertrand Russell. Really excellent stuff so far — has aged surprisingly well.
  • The Inflationary Universe: The Quest for a New Theory of Cosmic Origins by Alan H. Guth. Stalled two-fifths of the way through.
  • The Life and Adventures of Tristram Shandy, Gentleman by Laurence Sterne. Let's face it, I'm never going to finish this one.
  • Lucy's Child: The Discovery of a Human Ancestor by Donald Johanson and James Shreeve. Haven't gotten too far, but so far it's pretty interesting. More about how discoveries have been made than about what discoveries have been made.
  • The Orthodox Corruption of Scripture by Bart D. Ehrman. I'm about a quarter through. Very interesting stuff.
  • Sociobiology: The New Synthesis by Edward O. Wilson. I've been "reading" this classic tome for years. (To be fair, it's pretty large.)
  • Species: New Interdisciplinary Essays ed. by Robert A. Wilson. I've read a few of the essays and wonder if I'll ever read them all. I probably should.
  • The Stuff of Thought: Language as a Window into Human Nature by Steven Pinker. This book caps off not one but two trilogies by the author, one on language and the other on mind. Having read and throughly enjoyed the four preceding books (The Language Instinct, Words and Rules; How the Mind Works, The Blank Slate), I figured I owed it to myself to check this one out. So far pretty good.
  • The Text of the New Testament: Its Transmission, Corruption, and Restoration by Bruce M. Metzger and Bart D. Ehrman. Very detailed, somewhat laborious but fascinating, account of what, exactly, our sources for the New Testament are.
  • Under the Banner of Heaven: A Story of Violent Faith by Jon Krakauer. I finished the first two chapters, which are so distressing that it's taken me a while to work up to reading the rest.
  • Using Language by Herbert Clark. Not far.
  • Voyage of the Beagle by Charles Darwin. I sort of inherited this one and will make it through some day....

I'm sure I left some stuff off, and I'm really sure I left some stuff off the next list: a list of the the books I haven't even started yet!

  • Annals of the Former World by John McPhee
  • The Autobiography of Charles Darwin by (duh) Charles Darwin
  • The Chicken Qabbalah of Rabbi Lamed ben Clifford by Lon Milo Duquette.
  • The Coming Global Superstorm by Art Bell and Whitley Strieber
  • The Evolution of Living Things by H. Graham Cannon
  • The Lucifer Principle by Howard Bloom
  • Sanksrit Grammar by Willian Dwight Whitney. This one'll probably end up more of a reference book, but I should read the first few chapters at least.
  • Scenes From Deep Time: Early Pictorial Representations of the Prehistoric World by Martin J. S. Rudwick.
  • Speeches That Changed the World by various authors.
  • Spook: Science Tackles the Afterlife by Mary Roach. The author's Stiff, about various topics to do with corpses, was quite good.
  • The Structure of Scientific Revolutions by Thomas S. Kuhn
  • The Rough Guide to Climate Change: The Symptoms, the Science, the Solutions by Robert Henson
  • Write It in Arabic by Naglaa Ghali. It's a workbook, actually, and I should start it sometime.

I really need to take a month or two off and just read, read, read. (Or get caught in a bank vault while an atomic bomb destroys Los Angeles ... time enough at last!)

04 January 2008

Resolutions for 2008

I'm not going to bother you with personal resolutions (lose weight, save money, blah blah blah), but rather creative resolutions.

2007 was kind of a watershed year for me in many ways.
My girlfriend, Susan, also had a very productive year, since she started USC film school a year ago.

Of course, it wasn't entirely positive. I dropped the ball on Parry & Carney, and the Dinosauricon continues to languish. (Some day I plan to re-use code from March of Man and Names on NEXUS for a new version, but that day is still far off.)

Well, with 2007 in mind, here's what I'd like to get done in 2008:
  • Launch Names on NEXUS and give a talk on it at this year's ISPN meeting in Halifax, Nova Scotia (and also try for an SVP talk or poster). Perhaps start working on a related paper, if applicable.
  • Continue developing March of Man and add several dozen images to it. Continue promoting it and get at least another dozen artists to contribute. Perhaps do a poster or something at SVP.
  • Fix a few remaining issues with the PhyloCode website.
  • Help Susan on her filmic endeavors, and continue to develop a sci-fi concept we started.
  • Continue translating Genesis.
  • Release some ActionScript 3.0 source code into the public domain.

03 January 2008

Ape Taxonomy Is Confusing

Homininans, including us humans, are a type of hominin. Hominins are part of Homininae. Hominidae includes hominines. These are all subsets of Hominoidea.

Confused yet? You should be. Welcome to the not-so-wonderful world of typological, ranked taxonomy.

Traditionally, taxonomy had little to do with how organisms were actually related (Linnaeus having preceded Darwin by a good century). Taxonomy was just a way of sorting specimens: these ones go in this box (a species), and the little box goes in this bigger box (a genus), and the bigger box goes in this even bigger box (a family), and so on.

Eventually a typological system arose from this: one specimen (ideally) would be the standard, the archetype, the name-bearer for a given little box. One little box would be the "type" for a larger box, and so on. The box sizes were also strictly regulated: species, genus, family, order, class, phylum/division, kingdom. Eventually, new intermediate sizes, or ranks, were also added: subgenus, subfamily, superfamily, infraorder, suborder, etc.

Several taxonomic codes arose to govern this style of taxonomy, primarily the ICZN for fauna and the ICBN for flora. To simplify matters, they mandated that the name of a type genus should be used with the appropriate suffix for some of the taxa that include that genus. The codes don't agree on which suffixes to use for ranks (for example, the ICZN uses -idae for families while the ICBN uses it for subclasses), but they are standardized within each code.

Under the ICZN, our own taxonomy below the ordinal level looks like this:
RankTaxonEnglish vernacular form
SubgenusHomo (Homo)
SpeciesHomo sapiens
SubspeciesHomo sapiens sapiens

Anyone whose skin isn't crawling by now isn't paying attention.

Not only are these names comically and confusingly similar, but they're ambiguous. "Hominidae" means "the family that includes Homo", but what constitutes a "family" is entirely up to the whims of the taxonomist. As I've discussed on this blog earlier, some researchers restrict to to Homo and a few close, extinct relatives, while others have included all great apes as well, or even all apes.

Recently there has been a movement to coöpt these names into a phylogenetic framework. Something like this is emerging as a consensus (extinct taxa omitted):

|--Hylobatidae (gibbons)
| `--Pongo (orangutans)
| `--Gorilla (gorillas)
| `--Pan (chimpanzees, including bonobos)
`--Homo sapiens (humans)

In some ways this is a good scheme, but it has two big problems: 1) the Homo-typified names are still all horribly similar, and 2) many people still use those names in the more traditional way, where, for example, Gorilla, Pan, and Pongo are not in Hominidae.

So here's a brainwave: why not just think of new names for these clades? Seriously!

We already have some good vernacular names as a basis: "apes" for Hominoidea, "great apes" for Hominidae, and "African apes" for Homininae. Admittedly there's not a convenient term for the chimp-human crown group (besides "the chimp-human crown group", of course). Maybe something like "hunting apes" (humans and common chimps are the only apes to go on hunts, I think) or "sexy apes" (humans and bonobos are the only apes to engage in certain sexual positions and activities). Translate these into Latinized Greek and we get:

|--Hylobatidae (gibbons)
|--Pongo (orangutans)
|--Gorilla (gorillas)
`--[insert clever name here]
|--Homo (humans)
`--Pan (chimpanzees, including bonobos)

Isn't that much nicer? All of these could be defined as crown groups (except for Homo).

Well, just a little dream of mine, anyway....

01 January 2008

March of Man: Collage Backgrounds

Merry 2008, everyone!

In an attempt to beautify the collages on March of Man, I've added a more naturalistic background than the old grey tiles. Check it out.

I also added a few more figures. I sketched a bunch over my vacation, inspired by the chimpanzees at the Chicago Zoo (who, incidentally, love snow—or love eating it, anyway). Despite this, though, over half of the taxa are still not illustrated. Now would be a great time for other people to start making contributions. (Thanks again to Stephen O'Connor for his Homo erectus!)

Here are some sample collages—as always, figures are in chronological order from left to right:

Vertical distribution of figures based on phylogeny.

Vertical distribution of figures based on geography (Cape of Good Hope at top, Tierra del Fuego at bottom).

Vertical distribution of figures based on a combination of phylogeny and geography.

This won't be the final word on the background, but I think it's a bit of a step up (even if it does look a bit like barf). Unfortunately, it also drastically increases the size of the application. I need to do some file restructuring at some point. I've been neglecting my other projects, though, so I may have to push this off for a bit.

Update: Here is a much larger version (with phylogeny-based vertical arrangement).