Book Review: Practical Prototype and script.aculo.us 1

Posted by Rich Apodaca Mon, 15 Sep 2008 14:48:00 GMT

Technical books generally fall into one of two categories: tutorials, which rely on examples; and references, which use a high-level, architecture-centric perspective. If you prefer tutorials loaded with good examples framed in relevant context, then Andrew Dupont's Practical Prototype and script.aculo.us may be worth reading.

The examples I find most useful in a technical book are short snippets of code that do something very specific and which are bracketed by concise discussion. This makes it possible to scan pages looking for the answer to an immediate question. Practical Prototype offers many examples of this style of writing.

I generally find long examples difficult to follow - if I miss one key concept (by scanning ahead over something I'm not interested in, for example), then the rest of the example isn't much use. Fortunately, Practical Prototype only contains two extended examples: a fantasy football league and a blog-like application. And both augment material found elsewhere in the book.

JavaScript is a tool that few of its users ever get any formal training in. This can make discussions of technologies based on JavaScript difficult to follow as each reader will have a different set of limitations in their basic understanding. Practical Prototype takes this into account by laying a solid, approachable foundation before diving into the framework details.

For example, Chapter One discusses the basics of the JavaScript language itself and its DOM manipulation capabilities. Chapter Nine reviews DHTML fundamentals. Many chapters begin by discussing how something could be accomplished with bare JavaScript before introducing the way it's done with Prototype and script.aculo.us. Chapter Three, which discusses Prototype's collections support, and Chapter Ten, which introduces script.aculo.us effects, both include especially effective uses of this technique.

Maintaining the focus to write in this style consistently is not easy, but this is what differentiates an academic, unapproachable book from one that readers at all levels of understanding can learn from. Practical Prototype does a good job of consistently providing the necessary context.

One of my favorite things about Practical Prototype is its use of Firebug as a way to both teach the process of doing JavaScript development and to understand the examples.

Practical Prototype's reliance on examples does come with a downside: the book doesn't work well as a reference. What are all of the methods added to Array by Prototype? What's the syntax for creating a class? What are all of the arguments that morph takes? What are the performance implications of using getElementById versus $? When shouldn't you use Prototype or script.aculo.us? The answers to these questions may exists, but you'd need to find the right example. Clearly, this was a concious decision by the author and makes sense to the extent that the online API documentation answers these questions. But if you need a reference on Prototype and script.aculo.us, this may not be the book for you.

In summary, if you're looking for a tutorial containing lots of illustrative examples bracketed by concise discussion, Practical Prototype and scrip.aculo.us is a good choice.

Full Disclosure: I wrote this review as part of a program offered by Apress and O'Reilly to members of users groups - in my case the San Diego Java Users Group. In exchange for writing a review - good, bad, or indifferent - I got a free copy of the book. My main interest is in the Prototype framework, which has been discussed previously here and here.

JavaScript for Cheminformatics: Atom Typing with Prototype and Iterators

Posted by Rich Apodaca Thu, 28 Aug 2008 19:08:00 GMT

The previous article in this series discussed the use of Prototype to build a simple cheminformatics model. But there's much more to Prototype than an improved class-like syntax. This article discusses one specific way that Prototype enhances JavaScript collections through iterators.

The Problem

Let's say we have an instance of Molecule, as defined in the previous article, and we'd like to group the carbon atoms separately from the heteroatoms. In many languages, including Java, we'd have to write a for-loop complete with logic for comparing atoms and then placing them into bins. Prototype makes possible a more modular approach with iterators.

Functional Programming and Iterators

JavaScript is a multi-paradigm programming language that offers tools for both object-oriented and functional programming approaches. In practical terms, this simply means that even functions in JavaScript behave as objects: they can be created dynamically and passed as parameters. Prototype takes advantage of this to extend collections instances such as Arrays with built-in iterators that are analogous to iterators found in languages such as Ruby.

A Simple Test

The JavaScript below builds a pyridine molecule:

function createPyridine(){
  var pyridine = new Molecule();
  var c1 = pyridine.addAtom("C");
  var c2 = pyridine.addAtom("C");
  var c3 = pyridine.addAtom("C");
  var c4 = pyridine.addAtom("C");
  var c5 = pyridine.addAtom("C");
  var n6 = pyridine.addAtom("N");

  pyridine.connect(c1, c2, 1);
  pyridine.connect(c2, c3, 2);
  pyridine.connect(c3, c4, 1);
  pyridine.connect(c4, c5, 2);
  pyridine.connect(c5, n6, 1);
  pyridine.connect(n6, c1, 2);

  return pyridine;
}

Saving this code in a file called molecules.js, we can use Firefox with Firebug to test it with the following HTML:

<html>
  <head>
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="chem.js"></script>
    <script type="text/javascript" src="molecules.js"></script>
  </head>
  <body></body>
</html>
With the Firebug console, we create a Molecule of pyridine:
>>> m = createPyridine();

To separate carbons from heteroatoms, we use the Prototype partition iterator:

>>> m=createPyridine();
Object atoms=[6] bonds=[6]
>>> m.atoms.partition(function(atom){return atom.label == "C"});
[[Object label=C neighbors=[2] bonds=[2], Object label=C neighbors=[2] bonds=[2], Object label=C neighbors=[2] bonds=[2], 2 more...], [Object label=N neighbors=[2] bonds=[2]]]

The partition iterator accepts a function as a parameter and returns an array containing two sub-arrays: the first contains the elements for which the function evaluated to true (carbons) and the second contains the elements for which the function evaluated to false (heteroatoms).

Conclusions

Although the example shown here is rather simple, it's possible to extend the general principle to more complex atom typing systems. By creating a single function that evaluated atom type, we could pass it as a parameter to any number of collection iterator functions.

JavaScript for Cheminformatics: Using the Prototype Framework 1

Posted by Rich Apodaca Tue, 26 Aug 2008 14:01:00 GMT

If you want to do the kind of cheminformatics that involves manipulating atoms, bonds, and molecules, object-oriented programming works well as a development paradigm. Although perhaps not readily apparent, JavaScript offers everything needed to create object-oriented models just as intricate at those written in languages like C++ and Java. This article discusses one approach that makes use of the Prototype Framework.

About Prototype

Prototype is a set of extensions to the JavaScript language that make developing in it less painful. Some of the extensions relate to DOM manipulation. Other have to do with the way Strings and Arrays behave. For the purposes of this article, we'll be using Prototype's syntax support for classes and inheritance.

Atoms, Bonds, and Molecules

To start, we'll need classes that define the basic behavior of atoms, bonds, and molecules. Although we may ultimately need to consider issues such as multicentered bonding, for now, we'll stick to a simplified view of chemistry that has bonds connecting two and only two atoms.

Creating the Classes

We could use JavaScript's built-in method for creating objects from class-like structures, but Prototype's approach is cleaner.

In the following library, we define a Molecule as a collection of Atoms and Bonds with useful relationships:

var Molecule = Class.create({
  initialize: function(){
    this.atoms = [];
    this.bonds = [];
  },

  addAtom: function(label){
    var atom = new Atom(label);

    this.atoms.push(atom);

    return atom;
  },

  connect: function(sourceAtom, targetAtom, bondType){
    var bond = new Bond(sourceAtom, targetAtom, bondType);

    sourceAtom.neighbors.push(targetAtom);
    sourceAtom.bonds.push(bond);
    targetAtom.neighbors.push(sourceAtom);
    targetAtom.bonds.push(bond);

    this.bonds.push(bond);

    return bond;
  }
});

var Atom = Class.create({
  initialize: function(label){
    this.label = label;
    this.neighbors = [];
    this.bonds = [];
  }
});

var Bond= Class.create({
  initialize: function(source, target, type){
    this.source = source;
    this.target = target;
    this.type = type;
  },

  getMate: function(atom){
    if (atom == this.source) return this.target;
    if (atom == this.target) return this.source;

    return null;
  },

  contains: function(atom){
    return (atom == this.source || atom == this.target);
  }
});

Testing the Library

We can test the library interactively by saving it in a file called chem.js and creating some simple HTML:

<html>
  <head>
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="chem.js"></script>
  </head>
  <body></body>
</html>

We can then use the Firebug console to test the library interactively:

>>> m = new Molecule();
Object atoms=[0] bonds=[0]
>>> c = m.addAtom("C");
Object label=C neighbors=[0] bonds=[0]
>>>n = m.addAtom("N");
Object label=N neighbors=[0] bonds=[0]
>>> m.connect(c, n, 3);
>>> c.neighbors.size()
1

Conclusions

Although the cheminformatics library discussed here is far from being useful, it's not difficult to see how to extend it. Prototype offers a several possibilities for doing so.