16 December 2008

My Yuletide Gift: Open Source ActionScript 3.0 Libraries!

I finally got around to setting up a Google Code site:

A Three-Pound Monkey Brain: ActionScript 3.0 Libraries

As you can see, there is still much to be done. But it's a start, and it's available to anyone.

Merry Solsticetime, everyone!

10 December 2008

Uncle Sam wants YOU!

In case you all were curious about what I actually do for a living, this just launched:


This is a project I worked on with several other developers. (Well, I still am working on it—there are a couple of revisions we'll be rolling out before too long.) I also did some work on the main Army Experience Center website.

I believe this is the first project I've worked on involving Papervision3D that has made its way online. Hoo-ah!

22 November 2008

One Mo'

Here's all 10 MPTs (most parsimonious trees) from Yates & Kitching (2003) combined into one network:


Hmm, just noticed how reminiscent these are of Charley Harper's work....

20 November 2008

Names on Nodes: Viewing Phylogenies

One of the primary uses for Names on Nodes will be as a viewer for phylogenetic hypotheses. The first incarnation will be able to digest hypotheses from NEXUS files; later versions will allow other file formats and ad hoc creation. I've been working on this aspect of the application lately and thought I'd post a few screen shots. (Warning: This is not the final look. I am definitely going to use a more legible font!)

Here's a very simple tree from a study on carnivoran phylogeny using supertrees (Bininda-Emonds et al. 1999):


(Note: the feliform side is a little outdated by now.)

This is a directed acyclic graph (and specifically a tree) rendered using the Flare ActionScript library, an extremely powerful (if sometimes frustrating) data visualization tool. It's based on the only tree in that particular NEXUS file. But what if a NEXUS file has more than one tree? This is where it gets kind of neat (I think)—Names on Nodes can show multiple hypotheses at once!

Here's a combination of two hypotheses from Novacek's (1989) study of mammalian phylogeny:


(Note: Much of this was changed by the subsequent molecular revolution in eutherian phylogeny.)

The NEXUS file has one tree based on extant organisms and another with some extinct taxonomic units. This network represents the phylogeny if both trees were true. Obviously, it shouldn't be taken too literally—there's no way carnivorans are descended from a hybridization of two disparate lineages, for example. But it shows a sort of consensus, and can be used for the application of phylogenetic definitions.

For the more botanically-inclined, here's a similar network for Rodman et al.'s (1984) analysis of Centrospermae:


(I have no idea how outdated this one is.)

Another thing that can be done in Names on Nodes is linking phylogenies together. For the aforementioned study by Bininda-Emonds et al. there is another NEXUS file focusing on Canidae. A user could open both files, drag the root node of the Canidae phylogeny to the terminal Canidae node in the Carnivora phylogeny, and equate the units with each other. This would produce something like this (cropped):


The root node in this phylogeny, then, could be equated with the Carnivora node in Novacek's phylogeny, and so on. In this way, gigantic networks can be compiled, representing the complete Tree of Life. Outdated hypotheses can be filtered to taste.

Next step: automated taxonomy.

Next next step: relating anything and everything to the Tree of Life.

10 November 2008

Names on Nodes: Entities

Here's a UML diagram of the latest class schema for the core Names on Nodes entities:

The white arrows indicate inheritance, i.e., "is-a" relationships. For example, a PhyloDefinition is a type of Definition. The black diamonds indicate composition, i.e., "has" relationships. For example, a Definition has any number of Anchor entities, each of which has exactly one Signifier entity.

Some comments on the major classes of entity:

Signifier.—This is what everything revolves around. A Signifier signifies a set of organisms, that is, a taxon. Signifier entities may be scientific names, specimens, character states, or taxonomic units in systematic studies.

Several Signifier entities may share the same SignifierIdentity, indicating that they are different ways of referring to the exact same thing. For example, Felis leo (ICZN) and Panthera leo (ICZN) are objective synonyms. (Subjective synonyms do not share the same identity.)

Authority.—Every Signifier is unique within an Authority. Authority entities may be publications, nomenclatural codes, personal opinions, specimen repositories, or bioinformatics files. Every Authority is associated with a unique URI (e.g., a web address, a DOI, an ISBN number, etc.).

Like Signifier entities, different Authority entities may share an identity (AuthorityIdentity). These Identity entities are hidden from other entities, so that Authority and Signifier entities can be equated or differentiated without affecting other entities in the database.

Relator.—A Relator is a set of Relation entities, each of which represent a statement about two Signifier entities, either Inclusion (i.e., a is a superset of b) or Parentage (i.e., a is immediately ancestral to b).

Definition.—A Definition defines a Signifier according to an Authority, and may have any number of Anchor entities, each of which tells whether a given Signifier is objectively a subset of the defined Signifier.

RankDefinition.—A RankDefinition consists of a rank and some number of internal Anchor entities. For example, under the ICZN (an Authority), Hominidae (a Signifier) is defined as the family (a rank) typified by Homo (a Signifier referenced by an internal Anchor).

PhyloDefinition.—A PhyloDefinition consists of a formula, expressed prosaically and mathematically. For example, according to Gauthier & de Queiroz 2001 (an Authority), Aves ( a Signifier) is defined as, "the crown clade stemming from the most recent common ancestor of Ratitae (Struthio camelus Linnaeus 1758), Tinamidae (Tetrao [Tinamus] major Gmelin 1789), and Neognathae (Vultur gryphus Linnaeus 1758)." This Definition is specified by three internal Anchor entities, respectively referencing the species Struthio camelus, Tetrao major, and Vultur gryphus (all of which are Signifier entities).

Dataset.—The relations in a Dataset are based on observation or hypothesis. A Dataset entity's Authority may be a bioinformatics file, a publication, or a personal opinion. As with Signifier entities, every Dataset can be uniquely identified by a qualified name, combining the URI of its Authority and a local name.

Context.—Applying phylogenetic definitions requires a Context, which is essentially a set of Dataset entities. All Definition and DefinitionApplication entities are implicitly included under every Context.

DefinitionApplication.—This is sort of the crux of the whole idea behind this project: that a PhyloDefinition can be automatically applied under a given Context.

21 October 2008

Six Ways to Say the Same Thing

Prose
"'Aves' refers to the crown clade stemming from the most recent common ancestor of Ratitae (Struthio camelus Linnaeus 1758), Tinamidae (Tetrao [Tinamus] major Gmelin 1789), and Neognathae (Vultur gryphus Linnaeus 1758)."
—Jacques Gauthier & Kevin de Queiroz 2001 December


Simple Mathematical Formula

Aves := Clade(Struthio camelus + Tetrao major + Vultur gryphus)


Complex Mathematical Formula

Aves Linnaeus 1758 [Gauthier & de Queiroz 2001] := (AD o max o CA)(Struthio camelusTetrao majorVultur gryphus)


Ridiculously Complex Mathematical Formula

C := {x : (∀y ∈ (Struthio camelusTetrao majorVultur gryphus))[xy]}
A := {xC : (∀yC)[xy]}
Aves := {x : (∃yA)[xy]}


Simple MathML-Content
<apply>
xmlns="http://www.w3.org/1998/Math/MathML"
<csymbol
definitionURL="http://namesonnodes.org/2008/phylo/math/nodeClade"/>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Struthio+camelus"/>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Tetrao+major"/>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Vultur+gryphus"/>
</apply>

Complex MathML within Custom Markup
<pn:definition
xmlns="http://www.w3.org/1998/Math/MathML"
xmlns:pn="http://namesonnodes.org/2008/phylo/names">
<apply>
<csymbol
definitionURL="http://namesonnodes.org/2008/phylo/math/clade">
<mi form="prefix">Clade</mi>
</csymbol>
<apply>
<csymbol
definitionURL="http://namesonnodes.org/2008/phylo/math/nodeAncestors">
<mo form="infix">+</mo>
</csymbol>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Struthio+camelus">
<![CDATA[<i>Ratitae</i> (<i>Struthio camelus</i> Linnaeus 1758)]]>
</csymbol>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Tetrao+major">
<![CDATA[<i>Tinamidae</i> (<i>Tetrao</i> [<i>Tinamus</i>] <i>major</i> Gmelin 1789)]]>
</csymbol>
<csymbol
definitionURL="urn:isbn:0-85301-006-4/Vultur+gryphus">
<![CDATA[<i>Neognathae</i> (<i>Vultur gryphus</i> Linnaeus 1758)]]>
</csymbol>
</apply>
</apply>
</pn:definition>



References

19 October 2008

This is why I never get anything done.

I was getting pretty close to presentable with Names on Nodes, when I had a revelation. Now I have to rewrite most of it.

The revelation was this: nomenclatural codes, bioinformatics files, publications, specimen collections, and people are all the same thing. They are authorities.

Scientific names, taxonomic units, character states, and specimens are all the same thing. They are signifiers. They each signify a taxon (a set of organisms).

Signifiers are authorized by an authority. For example, Homo sapiens is a species authorized by the International Code of Zoological Nomenclature. YPM-VP 1450 is a specimen authorized by the Yale Peabody Museum's Vertebrate Paleontology Collection. "Wings used for powered flight," is a character state authorized by Gauthier & de Queiroz (2001). "30. Number of stamens: ten or fewer," is authorized by the NEXUS file registered as M331 in TreeBASE, as are the taxonomic units Phytolaccaceae and Lardizabalaceae.

Signifiers may share the same identity. For example Tyrannosaurus bataar (ICZN) and Tarbosaurus bataar (ICZN) signify the same taxon, no matter what. The identity is only accessible to the signifiers themselves, which means that signifiers can be equated and differentiated without disrupting references to them. (A similar identity property holds for authorities.)

Every authority may be associated with an absolute URI (universal resource identifier). Publications (including nomenclatural codes) may be associated with DOIs, ISBNs, etc. People may be associated with OpenIDs. Anything may be associated with a web address. It's a bit trickier for NEXUS files, but I figure that they can be uniquely identified by an ad hoc schema plus a SHA-1 hash of their textual data.

Examples:
  • http://www.peabody.yale.edu/collections/vp Yale Peabody Museum: The Collections: Vertebrate Paleontology
  • http://uppsaladomkyrka.se Uppsala domkyrka (cathedral)
  • urn:isbn:0080-0694/146 The International Code of Botanical Nomenclature (Vienna Code)
  • http://openid-provider.appspot.com/keesey Timothy Michael Keesey
  • http://threelbmonkeybrain.blogspot.com Timothy Michael Keesey (also!)
  • urn:isbn:0-912532-57-2/chapter1 Gauthier & de Queiroz 2001
  • biofile:5b2f349967­c18006233f­c89b8643ff­6c57be2858 the NEXUS file of Rodman & al. 1984
Each signifier, then, can have a unique local name under its associated authority, which forms a unique qualified name when combined with the authority's URI. Examples:
  • http://www.peabody.yale.edu/collections/vp::1450 a specimen
  • http://uppsaladomkyrka.se::Carolus+Linnaeus a specimen
  • urn:isbn:0-85301-006-4::Homo+sapiens a species
  • urn:isbn:0-912532-57-2/chapter1::wings+used+for+powered+flight a character state
  • biofile:5b2f349967­c18006233f­c89b8643ff­6c57be2858::CHARACTERS/19._Crassulacean_acid_metabolis/present_in_at_least_some_specie a character state
  • biofile:5b2f349967­c18006233f­c89b8643ff­6c57be2858::TAXA/Menispermaceae a taxonomic unit
This basically means four things:
  1. I don't have to track that much information about each thing, since that information is held in other resources. I really just need to reference other resources (authorities and signifiers) and maybe provide a convenient name for each one (a canonical name in the Names on Nodes database).
  2. It is possible to create an extremely flexible data model capable of accomodating just about any data set, nomenclatural act, or taxonomic opinion.
  3. When using Names on Nodes, you'll be able to filter out authorities you don't want to use.
  4. I gotta redo a lot of stuff.
One thing I still have to completely figure out is the idea of relators. A relator is an entity which contains a set of relations, each of which relate a signifier to another. Two major types of relations are inclusion and precedence (i.e., ancestry). Examples:
  1. Precedence.—nexus:5b2f349967­c18006233f­c89b8643ff­6c57be2858::TREES/Fig._2/a (a hypothetical ancestor) is ancestral to nexus:5b2f349967­c18006233f­c89b8643ff­6c57be2858::TAXA/Caryophyllaceae according to nexus:5b2f349967­c18006233f­c89b8643ff­6c57be2858::TREES/Fig._2.
  2. Inclusion.—urn:isbn:0-85301-006-4::Homo includes urn:isbn:0-85301-006-4::Homo+sapiens according the rank-based definition authorized by urn:isbn:0-85301-006-4.
  3. Inclusion.—urn:isbn:0-85301-006-4::Homo+sapiens includes http://uppsaladomkyrka.se::Carolus+Linnaeus. according the rank-based definition authorized by urn:isbn:0-85301-006-4.
In case #1, the relator is a tree in a NEXUS file. In cases #2 and #3, the relators are rank-based definitions authorized by the International Code of Zoological Nomenclature.

So, once this is set up, the application will be able to automatically apply phylogenetic definitions, given a certain set of relators. This set will typically include a tree (or network) and a character matrix (optionally). But it could also include many trees, or a custom phylogeny. It gets a bit complex, though, since definitions themselves are relators (mandating the inclusion of types or internal specifiers), as are contextual applications of definitions (indicating other, non-essential inclusions).

Still some details to work out, but I think I'm on a good track here.

08 October 2008

Three-Pound Monkey Brain Subpackages

So I'm looking at fleshing out the threelbmonkeybrain package, and specifically at moving a lot of reuseable code from Names on Nodes into threelbmonkeybrain. It's looking like it could be a pretty gigantic package. So big that I started thinking of breaking it down into the Three-Pound Monkey Brain family of packages.

Then I thought of some cutesy names.

Brainstem
Basic classes: relations, assertions, utilities, data filtering, basic geometry, basic collections.
Dependencies: Flash, Flex (some utilities)

Synapse
Data transfer: Internet operations (email, streaming media), file operations (assets, load tracking)
Dependencies: Flash, Brainstem

Calculia
Mathematics: operations, advanced collections, MATHML translation, formula rendering, etc.
Dependencies: Flash, Flex (some displays), Brainstem

Hippocampus
Data modeling and persistence: value objects, form generation, metadata description, validation, CRUD services, uploads, etc.
Dependencies: Flash, Flex, Brainstem

Motor Cortex
Animation: motion blur, beacons, drawing, constraints, locators, controls, etc.
Dependencies: Flash, Brainstem, ?Calculia

Of course, I could use some more predictable, boring names: base, net, calc, persist, anim. I dunno, what do you guys think?

01 October 2008

Nomenclature vs. Science

Recently, due to an electronic submission SNAFU, an unreviewed paper naming a new species was accidentally published online. The new species is a very interesting one, of much interest to those of us who study the general group that it belongs to. But, we find ourselves morally obligated to avoid public discussion of it, because its publication was inadvertent. Now we must wait for the ponderous phases of review and publication to take place before we can discuss what we already know. In essence, the process of nomenclature is impeding the process of science.

Does this seem backward? Why shouldn't we be able to discuss new data as soon as they are available? Nomenclature is essential to proper communication, but should it be allowed to slow the march of science?

More to the point, why does nomenclature even have the opportunity to impede science? Why would we even set up a system that allowed that to happen? Why can't we publish data as soon as it's available (perhaps with an efficient review process)? Why do we place nomenclature on such a high pedestal?

Well, really, it's just one aspect of nomenclature that is placed on a pedestal: priority. Whoever publishes a name for a specimen first gets to be the NAMER OF THE TAXON, and any Johnnies-come-lately are mere footnotes. For this reason, researchers must keep their data under wraps to avoid "claim jumps".

Of course, objectively, they don't have to. It's really just that we, as humans, assign some sort of importance to the coiners of names. Naming is power. Naming is awesome.

So, in essence, it is human egotism that allows nomenclature to hinder science. That's all.

As I see it, there are two solutions: 1) we stop caring so much about who names stuff and get on with our lives, or 2) we revise the system. Option #1 is the ideal, but, like so many ideals, it's pretty unrealistic. So what about option #2?

Well, here's an idea. What if the nomenclatural codes allowed "specimen claims"? That is, what if you could register a specimen as "yours to name" for a specific amount of time, after which someone else could challenge you for the claim? Then no new taxa dependent on those specimens (or on species typified by those specimens) could be named by someone else.

Here are a couple of possible "use cases" under this idea:

Use Case 1.—Early publication of scientific data, later publication of nomenclature.
1) Researcher discovers specimen.
2) Specimen is catalogued in an institution.
3) Specimen is registered under the nomenclatural code's database. Researcher now has X amount of time to name taxa based on the specimen.
4) Researcher publishes a preliminary report on the specimen, noting its registration information.
5) Researcher spends more time assessing the relationships of the organism(s) represented by the specimen. Based on this, Researcher decides that the specimen represents a new species and also decides that a new clade should be named using that species as a specifier.
6) Researcher names the new species, typified by the specimen, and the new clade in a publication which is published before X amount of time has passed.

Use Case 2.—Differing taxonomic opinions.
1) Researcher A discovers specimen.
2) Specimen is catalogued in an institution.
3) Specimen is registered under the nomenclatural code's database. Researcher A now has X amount of time to name taxa based on the specimen.
4) Researcher A publishes a preliminary report on the specimen, noting its registration information.
5) Researcher A spends more time assessing the relationships of the organism(s) represented by the specimen. Based on this, Researcher A decides that it belongs to a preexisting species and decides to publish a paper assigning it to that species.
6) Researcher B reads the preliminary report, and notes data that indicate that it may belong to a new species.
7) Researcher B notes that Researcher A has a hold on naming taxa based on the specimen, and communicates with Researcher A, learning Researcher A's taxonomic opinion.
8) Researcher B maintains disagreement, and decides to name a new species based on the specimen.
9) Researcher B challenges Researcher A's claim, via the nomenclatural code's database.
10) Researcher A relinquishes the claim.
11) Researchers A and B publish their respective papers with their differing opinions.
Alternate course of events.
10) Researcher A maintains the claim.
11) Researcher A publishes the paper placing the specimen in a preexisting species.
12) The claim expires after X amount of time.
13) Researcher B publishes a paper placing the specimen in a new species.

Use Case 3.—Renewal.
1) Researcher discovers specimen.
2) Specimen is catalogued in an institution.
3) Specimen is registered under the nomenclatural code's database. Researcher now has X amount of time to name taxa based on the specimen.
4) Researcher publishes a preliminary report on the specimen, noting its registration information.
5) Researcher spends more time assessing the relationships of the organism(s) represented by the specimen. Based on this, Researcher decides that it belongs to a new species and decides to publish a paper naming the new species.
6) Writing the paper takes more time than expected. Researcher applies for an extension to the claim through the nomenclatural code's database.
7) The extension is automatically approved, since nobody else has filed a challenge.
8) Researcher publishes the paper naming the new species.

Note that the current process is possible under this scheme. That is, the researcher can forego registration if they plan to keep the data under wraps until the new taxa are published. Registration simply allows the researcher to get the scientific data out ASAP.

It does optionally involve a few extra steps, but this scheme allows researchers to get their data out as quickly as possible, and then take some time in establishing the nomenclature. That seems like an eminently desireable outcome.

21 September 2008

Mystery Chart Solved

Mike Hanson pretty much got it (after Malacoda's initial close guess).

Click to see full size.


Each dot represents a known individual. Vertical distribution is, of course, geochronological. Horizontal distribution is meant to be more or less morphological, but it's completely subjective. If it were more rigorous, the vertical distribution would be more stratified, but this is a good approximation.

Some interesting things to note:
  • Wherever there's a gap, it's due to age and/or a rainforest habitat. (Note that the only definite chimpanzee fossils we have, which are all teeth, are from a savannah environment.)
  • Genetic data indicates that the chimpanzee-human split occurred around the Ardipithecus level. In fact, Ardipithecus kadabba (the earlier Ardipithecus population) shares a possible synapomorphy with chimpanzees (the canine cutting complex) not seen in earlier fossils, so it could be a very early stem-chimpanzee.
  • The earliest populations all have some vague indications that they may have been more habitually bipedal than chimpanzees are. Perhaps instead of humans arising from a chimpanzee-like ancestor, we both arose from an ancestor that was sort of in between. (Even today, chimpanzees are certainly not completely quadrupedal.)
  • If you look closely near the dark splotch that is our species, you'll see a dot lying between it and Neandertals. This represents a fossil of a child, which lived after all known Neandertals, with some traits of both species. A hybrid?
  • We have a damn good fossil record.

20 September 2008

A Clue to the Mystery Chart

Malacoda got close (5 points), but nobody's guessed it yet. Maybe it was too hard. Here's a clue:



(Click for full size.)

17 September 2008

Mystery Chart

Ten points to whoever can figure out what this is:



(Click to see full-size.)

23 August 2008

What is it that you hate about the PhyloCode?

Mention of the PhyloCode can incite some pretty strong emotions among biologists. Some are supportive, but there's a lot of vitriol out there. Consider, for example the title of Carpenter's (2003) paper: A critique of pure folly. Yes, a paper with that title actually got published in a scientific journal. Why the hate?

The thing is, it's sometimes hard to pin people down on exactly why they dislike it. Part of the problem is that the PhyloCode is surrounded by misconceptions. Much of what's been written about it is shockingly ignorant, considering that the code is freely available online and not horribly long (certainly shorter than any of the other codes). Consider Benton (2000), who seems to have not even read the then-current draft and proceeded to write an entire review based on what he imagined the PhyloCode to be like.

This is not to say that all critiques are uninformed. But of those that are, I find that they fall into two camps. They either raise points that have since been addressed in later drafts, or they are simple matters of taste.

As an example of addressed issues, the critiques of how the PhyloCode was going to handle species are now defunct, since it won't cover species. I myself raised dozens of smaller issues to the authors of the code, who then either emended the draft of the code or convinced me that no change was needed.

And as an example of difference of opinion, some people don't see the utility of the "crown clade convention" adopted by recent drafts. Some people just don't like phylogenetic nomenclature, period. The rank-based systems (which, incidentally, should not be called Linnaean systems, per de Queiroz [2005]) do well enough for many people's purposes, and they don't see a reason to change. Of those who like phylogenetic nomenclature, some don't see the advantages of a centralized approach, and would rather let it grow freely (e.g., Sereno [pers. comm.]).

That's all fine; it's good for people to point out flaws if they are later addressed, and it's understandable that not all people would agree on matters of opinion. But I see so much misinformation out there that I think it has to be the source of much of the dislike out there. One popular article is titled What if we decided to rename every living thing on Earth?, when the PhyloCode has always advocated using existing names when possible. Pickett's (2005) report on the first ISPN meeting is titled The new and improved PhyloCode, now with types, ranks, and even polyphyly, when the PhyloCode has never had types (only specifiers, which are similar but operationally different), has always allowed ranks, and has never allowed polyphyly.

So let me put a question out there: If you dislike the PhyloCode, what is it about it that you dislike? And are you sure it's something actually in the code?

17 August 2008

Sets for ActionScript

It's been a busy couple of months!

One of the things keeping me busy is, of course, Names on Nodes, the web application I am developing that will automate phylogenetic nomenclature. As part of that project, I have developed a mathematics package that I would eventually like to release as its own package. One class, however, is so useful that I have decided to jump the gun and offer it on its own.

We (ActionScript programmers) all know how useful the Array class is. It can be used to store a sequence of anything, so it can be repurposed as a list, a vector, an edge—all manner of collections.

Well, not all manner of collections. Just ordered collections that allow duplicate elements. What if you want a set: an unordered collection with no duplicates? I find I need sets all the time, but I have to use arrays. And arrays are not optimal for looking up an element's membership, or preventing duplication. As lists they're great, but as sets they suck.

For a while I used a class I'd made called ArraySet that wrapped an array, but this was only an improvement in API, not in performance. Then I took a cue from Java and created: HashSet.


The HashSet class wraps a Dictionary object, which it uses as a hash table. If an element belongs to the set, then that element is a self-referential key in the dictionary. If it doesn't, then there is no such key in the dictionary. And HashSet extends Proxy, so you can use bracket notation for many operations,. You can also use for..in and for each..in loops.

Here's a quick example:


// Create and populate the set.
var s:HashSet = HashSet.fromObject([1, 2, 3]);

trace(s.size); // 3
trace(s[1]); // 1
trace(s[2]); // 2
trace(s[0]); // undefined
trace(s.has(1)) // true

// Trace all elements of the set.
for each (var i:int in s)
{
trace(i);
}
// Trace all elements of the set (different method).
for (var x:* in s)
{
trace(x);
}

trace(s); // {1, 2, 3}
s.add(1);
trace(s); // {1, 2, 3}
s.add(4);
trace(s); // {1, 2, 3, 4}
s.remove(1);
trace(s); // {2, 3, 4}
delete s[2];
trace(s); // {3, 4}
s[3] = undefined;
trace(s); // {4}


...and so on. Full documentation is in the class itself, so you can figure out the details for yourself. I will mention that HashSet also has a number of functions in common with Array (every, filter, forEach, map, some) and others that are unique to sets (get empty, diff, intersect, prSubsetOf, subsetOf, union). It also has a few functions that Array really ought to have (clone, equals, remove).

Download it and try it! The full version is integrated into the mathematics package that I'm still tweaking, but this is too useful to keep to myself any longer. At least, I think so—let me know what you think.

09 June 2008

ISPN3 Meeting: Updates

I've just gotten word of a few changes in the ISPN meeting schedule.
  1. The ISPN meeting will be held on July 21–22, with a social on July 20.
  2. Registration at pre-meeting rate is extended to July 1.
  3. Abstracts will be accepted until July 1.
For more details, see the Protist 2008 website and/or my previous post.

06 June 2008

Three-Pound Monkey Brain: The Open Source Project

In an earlier post, I was bemoaning the unimaginative (and self-centered) name I was using for my general open source ActionScript project: net.tmkeesey. But someone pointed out to me this morning that a better name was staring me in the face all this time. Thus, I have changed the packages from net.tmkeesey to ... threelbmonkeybrain! (A bit long-winded, but unfortunately you cannot start package names with numerical digits.)

Along with this much-better name is a new location for the code. Point your Subversion clients to:
(Or, if you just want the code itself without unit tests, etc.: http://svn3.cvsdude.com/keesey/PROJECTS/ threelbmonkeybrain/as3/trunk/src/threelbmonkeybrain)

I've added a lot of new packages under the rubrics of threelbmonkeybrain.load and threelbmonkeybrain.net, but I have not had time to build full unit tests for them. Once that's done, I'll write more about those.

04 June 2008

More Additions to Open Code: Collections and Connectivity

I've added two new utility packages to net.tmkeesey. SVN repository here.)

net.tmkeesey.utils.mx
Static classes with utilities for handling Flex objects.
net.tmkeesey.utils.mx.ArrayCollectionUtil
Contains a convenience method for converting arrays to ArrayCollection objects with filters and/or sorts.
net.tmkeesey.utils.mx.Filtration
Contains handy functions which can be used for ICollectionView.filterFunction.
net.tmkeesey.utils.mx.ListCollectionViewUtil
Contains a convenience method for converting ListCollectionView objects to arrays, using filters and/or sorts.

net.tmkeesey.utils.net
Static classes with utilities for handling flash.net objects.
net.tmkeesey.utils.net.URLRequestHeaderUtil
Contains methods for cloning and comparing URLRequestHeader objects.
net.tmkeesey.utils.net.URLRequestUtil
Contains methods for cloning and comparing URLRequest objects.
net.tmkeesey.utils.net.URLVariablesUtil
Contains methods for cloning and comparing URLVariables objects.

As always, I commit nothing until I've created ASDoc comments and flexunit tests for everything.

(O.K., not the most exciting update, but....)

03 June 2008

The Dinosauricon Is Dead.

Long live The Dinosauricon.

As some of you may know, I used to run a website devoted to dinosaur information and illustration called The Dinosauricon. In recent years, it went fallow—I had no time to keep it updated, let alone finish building it. The old version stayed online—a living fossil of sorts.

Recently, someone emailed me asking where it was. I looked, and, indeed, it seems the host service (which was hosting it for free) finally pulled the plug. And, honestly, it was overdue—like putting down an old, sick pet.




The Dinosauricon was my biggest labor of love, and something I was very proud of (if never completely satisfied with). It opened a lot of doors for me. I sold illustrations to publishers who had seen the site. It was an excellent showcase for my technical skills when seeking work as a web developer. It got mentioned in books. It got me my first coauthorship on a scientific paper. It helped get me a job as a paleo-technician for the Wyoming Dinosaur Center. And it helped make me a lot of friends at SVP meetings.

It was also a great project for learning web development. Through it I learned HTML, XML, CSS, JavaScript, PHP, MySQL, XSL, XSLT, XPath, and more. (Not to mentioning sharpening my C++ skills—yes, I actually used C++ for one version of it.) I owe a lot of my professional expertise to that site.

Besides just helping myself, though, it was primarily meant to help others. I think it did a very good job, not just of getting scientific information out to the public, but also of promoting illustrators, especially up-and-coming ones. I used to really enjoy viewing all the submissions, providing feedback for the pieces that needed some work and marveling at the ones that didn't.




The Dinosauricon was not always called "The Dinosauricon". Back in 1995, during my first semester in college, it was a bunch of crummy HTML 1.0 pages loosely thrown together as my first website and called, rather unimaginatively, "The Dinosaur Web Pages". Around this time I started subscribing to the Dinosaur Mailing List (which I'm still on), and started hearing about newfangled (to me) concepts like "cladistics" and "phylogenetic taxonomy". (I wasn't a big fan at first, but we've seen how that turned out.) On the original site, I tried to do a blend of Linnaean and phylogenetic taxonomy. (I also illegally used some Greg Paul artwork, but took it down once I realized you couldn't just put anything in your web page.)

In 1996, I took the first-ever class of Tom Holtz' HONR 259C: Topics in Dinosaur Research. Using information I learned in that (excellent) class, I began to patch up the silly taxonomy I'd used at first, replacing it with proper cladograms. (Sometimes I get credit for inventing a style of writing cladograms in ASCII, but, as with many inventions, this was really invented piecemeal by a lot of people and I just pitched in and helped promote it.)

I also started to get interest from young paleo-artists. Rachel K. Clark and Peter Buchholz were the first to offer their work for my site. (I already had some of my own work up.) I gladly accepted, and eventually went on to build up a gallery with thousands of images, by dozens of artists from all over the globe.

Eventually the site needed a new name. After much thought, I decided on The Dinosauricon, an homage to Lovecraft's Necronomicon, and roughly Greek for "image of the terribly great lizard". Many people pronounced it wrong (like "dinosaur icon") or thought it looked like the name of a convention, but I think it was a pretty good name.

The site reached its pinnacle, in my opinion, at the end of 1999. I had procured an independent study program specifically for the project, and I poured tons of time into it. I worked obsessively, feverishly, often tallying dinosaur names into wee hours. (I didn't have much of a life.)

In December 1999 I graduated and in January 2000 I moved to Los Angeles. A new chapter of my life began with the new millennium. (Yes, O.K., technically it started in January 2001, but shut up.)

This was a busier chapter. I began, slowly, to actually acquire a life. I had less and less time for the Dinosauricon. In 2002, during a rough period, I poured a lot of work into a new version, but I never had time to get more than partly done. The new and old versions coexisted for a while, with a better gallery on the new version but more scientific information on the old.

As the years went by, web technologies began to develop at an ever-increasing rate. I always felt the site was hopelessly behind the times. There was a vision in my head of how it could be. But I only had so much time to work on it. Every time I got some time, I'd revisit the old work I'd done, shake my head at how outdated it was, and start over from scratch. Not surprisingly, this led to getting a lot of nothing done fast. (Except for learning new technologies, which was useful.)

For years I kept saying I'd have another version done, but it never came to pass. The old version, which had been hosted at a little donated computer at my college, finally went down. The new version persisted for a while. Now it is dead.




There may be hope for the future. My two big personal projects right now are related to paleontological illustration (March of Man) and biological information (Names on Nodes). Much of the ideas and code going into these could be ported to a new Dinosauricon. I have to see these two ideas through, but once they are in a stable place, perhaps I'll look into the matter of reviving The Dinosauricon.

No promises.

Motion Blur

O.K., last one for the day—I promise.

I just committed a small addition to net.tmkeesey. As alluded to in my last post, it's motion blur. How easy is it to use? Here:

import net.tmkeesey.anim.effects.MotionBlur;
new MotionBlur(myDisplayObject);

Done. Now myDisplayObject will blur whenever you move it. It even works with preexisting filters. (Note that the blur looks best for horizontal and vertical motion, though. I may work on an improvement for that later.) There are also a few optional parameters: blurFactor (how much to blur per pixel moved), optimized (optimization flag—only uses powers of two for blurring if set to true the default), and quality (blur quality).

In the future I'd like to update this so that the parameters can be changed on the fly, but I'm not sure how useful that would really be. Good enough for now.

Once again, the code can be checked out from:
http://svn3.cvsdude.com/keesey/PROJECTS/tmkeesey/trunk

Updates to Open AS3 Code

Pursuant to my last post, I've added some general utility classes to the net.tmkeesey repository. They are arranged in two packages: utils.core and utils.display:

net.tmkeesey.utils.core
  • ClassUtil
  • ObjectUtil
  • StringUtil
  • TimerUtil
  • UIntUtil
  • XMLListUtil
  • XMLUtil
net.tmkeesey.utils.display
  • ColorUtil
  • DisplayObjectUtil

A couple of highlights:

UIntUtil.closestPowerOf2() can be used to optimize blur filters. (Coming soon: MotionBlur class.)

DisplayObjectUtil.findAncestor() searches an object's display ancestry for an object of a certain class. This can greatly facilitate communication between visual components. (And even nonvisual objects, as long as they have a parent property which is an instance of DisplayObjectContainer.)

As always, all classes come with unit tests and all code is commented with ASDoc (except for unit test code, where it would really be superfluous).

Once again, the repository is at: http://svn3.cvsdude.com/keesey/PROJECTS/tmkeesey/trunk

02 June 2008

I'm Going Open Source!

Over the years, I've come up with a large number of ActionScript packages that I reuse on projects. I've been meaning for a long time to release some of these packages to the public. Well, there's no time like the present, so I'm going to start.

One note: I'm using net.tmkeesey as a package name, but eventually I'd like to name it after something other than myself. So this is just provisional until I start opening up collaboration.

The repository is located at:



(I'm assuming that anyone who's read this far knows how to check out a project from a Subversion repository.)

I figured I'd start with the basics. I've included three very low-level packages: assert, core, and relate. These are distilled from packages I am using for Names on Nodes and other projects.

net.tmkeesey.assert.Assertion
Utility class with methods for making assertions.

net.tmkeesey.assert.AssertionError
Generic error type for a failed assertion.

net.tmkeesey.core.Property
Utility class for object properties.

net.tmkeesey.relate.ComparisonStack
Stores a stack of ordered, two-object comparisons. Used to prevent recursion.

net.tmkeesey.relate.Equality
Utility class for determining equality (either qualititave equality or identity) of two objects. Works with Equatable.

net.tmkeesey.relate.Equatable
Interface with a single method, equals(Object):Boolean, for determining qualitative equality.

net.tmkeesey.relate.Order
Utility class for determining the relative order of two objects. Works with Ordered.

net.tmkeesey.relate.Ordered
Interface which extends Equatable and adds a single method, findOrder(Object):int, for determining relative order.

There is also a full complement of unit tests in the flexunit_src folder. All code has full ASDoc comments.

Future additions may include: management of loaded assets, digital puppetry, some general user interface components, animation assistance, collection-related code, buttloads of utility classes, triggers, XML translation, MathML processing, "exoskeleton", and "champagne".

P.S. You may note that I'm defying my previous stance on uncradled brackets. I have to say, I gave them a chance, and I'm starting to understand why people like them. I can't put it into words just yet, but....

30 May 2008

Exopolis Online Ads

Just launched a new Flex minisite: Exopolis Online Ads.

(If you poke around long enough you might find a few little bugs, but it's mostly done.)

This is (obviously) a promotional piece for our banner ad capabilities. Doing the project in Flex made a lot of things easier: transitions, placement, deep-linking, back/forward button capabilities.

It's a bit risky loading banners directly into Flash, but fortunately Flex's AVM1Movie component largely keeps the banner functionality in its own "sandbox" (with a few exceptions that need tending to). Flash banner ads have some of the hackiest programming you'll ever care to see, but fortunately AVM1Movie prevents 99% of it from affecting the rest of the site.

I did get one nice, reuseable thing out of it, too: the MouseScrollCanvas component that controls those scrolling lists of links.

Which reminds me ... I really have to consolidate all the reuseable code I've written someday and release it....

Thoughts on 2001: A Space Odyssey

Recently I saw a special screening of a 70mm print of my favorite film, 2001: A Space Odyssey. This was the second time I'd seen a 70mm screening of it and, I have to say, if you have only seen it on TV, then you haven't really seen it. The level of detail is insane. You can actually read the instructions on the zero-gravity toilet.

Apart from the detail, the feel of seeing it on a large screen is different. You realize that it's not so much a typical film as a ride. Not like a typical "roller coaster" summer blockbuster, but a long, deliberate, and intelligent ride, thoughtfully taking us from our deep past to our far future.

Seeing it with an audience is fun, too. Kubrick (the director) had a very dry sense of humor, I think, and it comes out better with an audience. I've noticed the exact same thing with his Barry Lyndon. When watching it on your own, some lines are sort of dryly amusing. But in an audience, they're hilarious. HAL's calm, persistent politeness is already amusing when watching the film on TV, but with an audience laughing, it's that much funnier (and creepier). (That said, though, the first time I saw it with an audience, they laughed too much. It's not a comedy!)

As a prediction of the future, the film failed in many ways (Pan Am?), but it's held up better than anything else form that time period. In particular I was impressed with the Australopithecus makeup—it's still reasonably consistent with what we know of stem-humans.

I thought of one objection, though, after the film was over. The film supposes that the reason for humanity's greatness, what enabled us to go from rooting around for tubers to walking on the moon, is our ability to create and use tools. The film's greatest, most dramatic moments involve tools. Think of the first one, where the ape-man thinks of the monolith, and then an idea starts to form. He plays with a leg bone, flipping it around, and then sees in his head that it could be used as a cudgel. The majestic strains of Also Sprach Zarathustra swell as the ape-man experiences a violent orgasm of intellectual discovery. That scene still gives me chills.

Tools are certainly important to us, and we are clearly the best at creating them. But is that really the reason for our success?

Since the 1960s, tool use has been observed in a number of non-human species, most famously in chimpanzees, but also in other great apes and some animals much more distant from us. Recently, New Caledonian crows have been seen to not only use tools, but fashion their own, creating hooks out of wire in order to reach out-of-the-way food. (Imagine redoing the Also Sprach Zarathustra scene with a crow.)

So we're not unique in this ability (even if we are much more proficient). It's wrong to suppose that the inspiration to use tools could have suddenly set us on our course of domination, because apes have presumably been using tools for a fairly long time.

What sets us apart, then? Arguably, it's language. Well, not just language, but discrete grammar. Many animals are capable of creating symbols, vocal or otherwise, that can be used to communicate the idea of a particular object to another member of their species. For example, vervet monkeys have different types of screeches for alerting their band to the presence of different types of predator. Honeybees have a system of dance that has something of a grammar (and is used to communicate the location of flowers), but not a discrete grammar like ours. Look at this essay: you have probably not seen most of the sentences in it before in your life, and yet you can understand it (I hope). That's the power of discrete grammar.

So the big dramatic scene should not have been when the ape-man discovered how to use a bone as a cudgel. It should have been when he told the other members of his tribe, through grunts, smacks, and gestures, that a bone could be used as a cudgel, and that they should gang up on that rival tribe. That was the true moment of power.

Names, Nodes, and CRUD

The Third ISPN Meeting (mentioned here) is fast approaching. I'm still hoping to have an alpha version of Names on Nodes online by then, but it's going to be tricky. Currently I'm involved in a massive refactoring.

The basic point of Names on Nodes, as I've mentioned before, is to automate taxonomy. That is, you feed it:
  1. a bunch of phylogenetic definitions,
  2. a phylogeny, and
  3. specifier links, that is, correlations between definition specifiers (apomorphies, species, specimens) and units in the phylogeny (e.g., taxa in NEXUS trees).
Once properly fed, it spits out taxonomies, that is, associations of scientific names with sets of subtaxa.

That part of it is pretty much done. But there are two tricky parts I have yet to complete: data persistence and user interface. And what both basically boil down to is CRUD.

I've mentioned CRUD before here. It's an acronym for the four basic operations involved with data persistence, the four things you can do to a stored object. Those are:
  • Create
  • Retrieve
  • Update
  • Delete


As often happens in programming, I started out with an ad hoc sort of approach that worked well enough up to a point, but then I started finding myself in trouble. Duplicated code. Unnecessarily complex code. Code that was hard to update.

It was time to refactor.


Here's a breakdown of the new system.

Every user interface involved with persistent objects is managed by something called a FlowManager. This stores a navigable tree of FlowEntry objects, each associated with a visual FlowComponent.

The main application handles requests from all components within. These are sent to the application as bubbling events, that is, events that "bubble" up through the display hierarchy (say, from a button, to the form that contains it, to the flow manager, on up to the main application). Two of the major types of request are EditEntityEvent and DemandEntityEvent.

An EditEntityEvent comes with a persistent object (e.g., a species, a definition, a NEXUS file, etc.). The application's responsibility is to create a FlowComponent object that will display the entity and allow the user to edit it (Update).

A DemandEntityEvent comes with a class of persistent object (e.g., Species, Definition, Nexus, etc.). The application's responsibility, then, is to provide the "demander" with an object of that class, either by making a new one (Create) or by selecting an existing one (Retrieve).

(Note that I haven't mentioned Delete. I'm leaving that out of the first version. Any deletions will have to be made by myself, manually.)

One problem with my old approach was that I had different user interface components for each combination of CRU[D] action and persistent object. Take a couple dozen types of persistent object and multiply by three: that's how many components I had to make.

The new system, though, has just two types of FlowComponent: one for handling EditEntityEvent requests and the other for handling DemandEntityEvent requests.

The first one is the simplest: EntityEditor. It basically consists of the following components:
  • a form which shows all data in the persistent entity;
  • a bit of text that summarizes the entity in its current state (e.g., for a Binomen entity, something like "Prenomen nomen Author 1970");
  • a button that updates the entity in the database, or, if it is a new entity, creates it in the database; and
  • a "cancel" button.
The form has to be done individually for each type of persistent entity, but the rest is completely generic.

The other FlowComponent object, EntitySupplier, actually uses an EntityEditor object. Once the EntitySupplier object is given the class of entity that it's supposed to supply, it creates a default instance of that class and gives it to an EntityEditor, which it displays to the left. To the right, it displays a SuggestionBox, a grid showing various existing entities that might match what's in the editor.

The SuggestionBox uses a nonvisual object called an EntitySuggester, whose job is to watch for changes that the user makes to the persistent entity and come up with relevant, existing suggestions. For example, suppose the user is editing a new Publication object and starts to type in the authorship as "Linn". The PublicationSuggester sees this and checks the database for possible matches, coming up with "Linnaeus 1758". If this is the publication that the user wanted, then they can select it from the SuggestionBox without having to fill in any more information.

I still have to create a form and a suggester for every type of persistent entity, but this is a much neater division of labor than I had in the last version, where forms generated their own suggestions (which would be wasteful if you were just editing an existing entity).

Hope to get much done this weekend.
(Have to get much done this weekend....)

19 May 2008

Vectors in Flash Player 10

Last week Adobe released a beta version of Flash Player 10. Many exciting new features: 3D effects, a replacement for those clunky old TextField objects (finally!), improvements to the drawing API (which interestingly mirror some work I'd done for my puppet package), access to low-level audio functionality, local file access (no more stupid scripts to bounce files off a server!), etc. One of the most exciting things for me, though, is the addition of vectors.

The word "vector" has a lot of meanings, but in computer science and some branches of mathematics, it basically means "list". Of course, we already have Array objects for creating lists in ActionScript. Indeed, vectors are very similar to arrays, but with one very important difference: the elements must be of a specified type.

Here's an illustration of the difference:
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;

var list:Array = [];
list.push(1);
list.push("A String");
list.push(new Object());
list.push(new MovieClip());
list.push(new Shape());
list.push(new Sprite());
trace(list.join(", "));
// Output:
// 1, A String, [object Object], [object MovieClip], [object Shape], [object Sprite]

Note that the elements of the array are of all kinds of different types: a number, a string, a plain vanilla object, and several display objects. But suppose we changed list from an array to a vector with elements of the type DisplayObject:
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;

var list:Vector.<DisplayObject> = new Vector.<DisplayObject>();
list.push(1); // throws TypeError
list.push("A String"); // throws TypeError
list.push(new Object()); // throws TypeError
list.push(new MovieClip());
list.push(new Shape());
list.push(new Sprite());

Now the elements must be of a particular type, and attempting to add objects of any other type will throw an error.

Note the syntax for specifying the type of the vector's elements. This is actually an early introduction of parameterized classes, which are going to be part of the ECMAScript 4.0 standard. (They're already features of languages such as Java.) I was surprised that they'd include an ES4 feature so early, but it seems to be implemented only for vectors. I was unable to make my own parameterized classes in the alpha version of Flash CS4. Also, since Vector is a final class, you can't make subclasses, parameterized or not.

Even so, it'll be great to finally have some kind of type-safe collection. I can't tell you how many times I've had to make my own specialized, type-safe classes for this kind of thing.

Vectors will also improve performance, since the compiler can optimize code for vectors of integers, etc. When initializing a vector, you can also fix its length, allowing for further optimization. For example, to store a 3D spatial position as a list of exactly 3 numbers (x, y, and z coordinates), you can use:
var point3D:Vector.<Number> = new Vector.<Number>(3, true);


Can't wait to start using these....

07 May 2008

What happens when you mix invertebrate sex, homemade crafts, and a European actress?

Answer: The Greatest Thing Ever

ISPN3 Meeting: Abstract Deadline

There's only one week left to submit abstracts for the Third Meeting of the International Society for Phylogenetic Nomenclature! (I just submitted two, one for a talk and one for a poster.) The deadline is May 15, which is also the deadline for early registration.

Once again, some important information:
When? 2008 July 21–23
Where? Dalhousie University, Halifax, Nova Scotia, Canada
How much does it cost? $190 (CAD*) if you register by May 15
What if I'm a student? $90 (CAD*) if you register by May 15
Where do I register? At the Protist 2008 website. (Be sure to select "I am registering for ISPN"—unless you're a protistologist, of course.)
How do I submit abstracts? Follow the instructions here, but send the document to harold [dot] bryant [at] gov [dot] sk [dot] ca and use one of these keywords:
  • theory of phylogenetic nomenclature
  • history and development of phylogenetic nomenclature
  • definition of taxon names
  • other (specify).
I'm a U.S. citizen. Do I need a passport? Yes.
Where can I find more information? In the Second Circular.

The last meeting (Yale 2006) was great and hopefully this one will be even better!

* Canadian and U.S. dollars are worth about the same these days.

27 April 2008

DRAGABOK

Over the years I've accumulated quite a lot of doodles, sketches, etc. They're filling up some boxes in my office closet. So I thought I'd start scanning them and posting one per day to a new blog.

I give you:

(The title is Old Norse for "drawing book"—or close enough, anyway.)

Enjoy!

17 April 2008

Comments on the Flex Best Coding Practices

Adobe recently published preliminary coding guidelines for people making contributions to the Flex framework (mx packages). Here's the link:



Although it's specifically meant for the Flex project, the vast majority of their guidelines are applicable to ActionScript 3.0 code in general. Overall, I really like their direction. But I thought I'd take some time to comment on what I don't like or find questionable.

1. Acronyms

When using acronyms in code, the programmer faces a dilemma: convert the case to whatever is appropriate for the context, or leave them all in caps? They opt for the latter, and usually this is fine. However, names that use two acronyms can suffer from ambiguity, as in their hypothetical example loadCSSURL (which some programmers would prefer be rendered loadCssUrl).

Personally, I think there's no good solution here, so I just go with their approach. But I recognize that this approach has problems. As they say about loadCSSURL, "[T]ry to avoid such names."

2. Package names should always be nouns or gerunds

Actually, guys, a gerund is a noun. You're thinking of participles, which are verbs and, in English, look exactly like gerunds. (Gerund: "Walking is fun." Participle: "I was walking.")

Anyway, I don't see why this should be so. I've named a lot of packages after verbs, myself. Is it really that bad to name a package of things that draw something draw as opposed to drawers or drawing?

3. Start interface names with "I"

I've gone back and forth on this one and have finally decided that I actually hate it. Suppose I start out making something an abstract class and then later decide it should be an interface (or vice versa)? Why should I have to rename it when, to external code, nothing has changed? In most cases, external code shouldn't care whether an entity is an interface or a class (the obvious exception being when external code is expected to implement the interface).

I tend to use adjective for interfaces when possible, but often I just use plain old nouns. What's the harm?

4. Brackets on their own lines

They never explicitly recommend this, but all the examples show it. To illustrate what I mean, they recommend this:
function foo():void
{
if (test())
{
doSomething();
doSomethingElse();
}
else
{
doAnotherThing();
}
}
Over this:
function foo():void {
if (test()) {
doSomething();
doSomethingElse();
} else {
doAnotherThing();
}
}


Now I've heard people swear by the former, saying it makes blocks of code much easier to spot. But to me, it seems like a huge waste of space. I can only see so many lines at once, and if half of them are brackets, I'm going to have to be paging up and down an awful lot. Besides, I've been using cradled brackets for over a decade and I don't have any problems spotting blocks.

That said, I've never tried the other way, so I reserve final judgment until I give it a fair chance.

5. Event handler names

The recommend the form eventNameHandler. I like the older ActionScript convention onEventName. Not only is it more succinct, but it has the added benefit of placing all your handlers together when you sort methods alphabetically.

6. Postfix vs. prefix operators

They recommend postfix over prefix operators, despite the fact that prefix operators are generally faster. This completely baffles me. If this:
for (var i:int = 0; i < n; ++i) {
trace(i);
}
...is faster than this:
for (var i:int = 0; i < n; i++) {
trace(i);
}
... then why on Earth would you ever use the latter? It's not like one is more readable than the other. They're equally legible, and one is faster—no contest.

7. Single-statement if blocks

They recommend leaving brackets off. Personally, I prefer to always use brackets—it's more visually cohesive, and it makes things easier when you later realize you do need another statement in there, after all.




By this time it probably sounds like I hate their ideas, but actually, these are the only ones (and I follow that first one, anyway). Everything else is great and much of it had me going, "Yes! Preach it!"

This is something every ActionScript coder should read. Like me, you may not agree on every detail, but overall, it's an excellent guide.

16 April 2008

The Third Meeting of the ISPN: Second Circular

The second circular for the Third Meeting of the International Society for Phylogenetic Nomenclature has been posted on the ISPN's website.

The Third Meeting of the International Society for Phylogenetic Nomenclature will be held in Halifax, Nova Scotia, at Dalhousie University, from July 21 to July 23, 2008. This meeting is an opportunity to discuss topics that pertain directly or indirectly to phylogenetic nomenclature in general, as well as the International Code of Phylogenetic Nomenclature (PhyloCode) and the Companion Volume in particular. In addition to providing a forum to contribute oral and poster presentations, this meeting will also include plenary talks by invited guest speakers. This meeting is organized in close collaboration with the International Society of Protistologists (ISOP) and the International Society for Evolutionary Protistology, which are hosting the joint Protist 2008 meeting, at the same venue, from July 21 to July 26, 2008.


The deadline for early registration and for abstract submissions is May 15.
(I better go get working on my submission[s].)