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.