Tuesday, March 30, 2010

Javascript for language geeks

A couple years back, I was surprised to discover some cool things about Javascript. I was really into Scheme at the time having read Structure and Interpretation of Computer Programs (aka SICP). It turns out, Javascript was strongly influenced by Scheme, and underneath a blasé curly-brace syntax was some cool stuff. Specifically, Javascript is a dynamically-typed object/functional scripting language as are Ruby and Python. But it's prototype-based object system is very different from either of those. Anyway, here are some notes from a little presentation I did, slightly edited and updated.

History

Javascript was created by Brendan Eich during the good old days of the browser wars. Netscape shipped LiveScript in Navigator 2.0 beta in September 1995 and re-released the language as JavaScript in March 1996. ECMA post-facto specification, ECMAScript standard: ECMA-262, followed. Douglas Crockford's The State and Future of Javascript tells the gory tale of the fall of the fourth edition and the rise of the fifth.

Edition 1June 1997
Edition 2June 1998
Edition 3December 1999
Edition 4...dragged on from 2000 through about 2008 and was finally abandoned
Edition 5December 2009

Closures

A closure is a package containing a function and some state. Here's an example. The purpose of an accumulator is to keep a running total, which requires state. Every now and then we can add something to the total. “Isn't a closure just a poor man's object?” you might well ask... or is it the other way around? Anyway, in Javascript, there's not much difference. Functions are objects and closures just tack on some state.

function createAccumulator(value) {
    return function(i) {
        return value += i;
    }
}
> acc = createAccumulator(100)
> acc(1)
101
> acc(1)
102
> acc(23)
125

Bag 'o properties

A Javascript object is just a bag of properties, like a hash. Since functions are a first class data type, some of those properties are functions. Properties obviously can change at run time. Want to add a method to an object? OK. Delete one? Fine. Change the behavior of a method? Just as easy. This is how objects in a dynamically typed language should be.

// creating a moose object
var moose = new Object();
moose.name = "Bullwinkle";
moose.species = "Alces alces";
moose.toString = function() {
 return this.name + ", " + this.species;
}
> print(moose);
Bullwinkle, Alces alces

> print("moose.name = " + moose.name);
moose.name = Bullwinkle

> print("moose[\"name\"] = " + moose["name"]);
moose["name"] = Bullwinkle

> m.greet = function(who) {  
  print("Hello, " + who + " my name is " + this.name + "!");
}

> m.greet("Chris")
Hello, Chris my name is Bullwinkle!

Constructors

Constructors are a little weird, but kinda cool. By convention, constructors are capitalized. Otherwise, they are just functions. The new keyword creates a new object which becomes this in the body of the fuction, which initializes the object. Because the constructor can build differently formatted objects in different circumstances, it's more like a factory than the poor hobbled Java constructor.

# moose constructor
function Moose(name) {
 this.name = name;
 this.species = "Alces alces";
 this.toString = function() {
  return this.name + ", " + this.species;
 }
}

> m = new Moose("Marty")
Marty, Alces alces    

Prototypes

The weirdest part of Javascript is its inheritance mechanism. Prototyping is inheritance without classes. We don't define templates for stamping out sets of similar objects. Instead, we pick one distinguished object and say, "All these objects are like that one". In other words, we delegate to our prototype object anything we don't need to handle in a customized way.

The new spec says it this way:

In a class-based object-oriented language, in general, state is carried by instances, methods are carried by classes, and inheritance is only of structure and behaviour. In ECMAScript, the state and methods are carried by objects, and structure, behaviour, and state are all inherited.

What's a little weird is how Javascript implements the idea syntactically. Have a look at the example below. Let's factor out stuff common to all moose.

moose_proto = new Object();
moose_proto.species = "Alces alces"
moose_proto.toString = function() {
 return this.name + ", " + this.species;
}

function Moose(name) {
    this.name = name;
}
Moose.prototype = moose_proto;

> a = new Moose("Bullwinkle");
> print(a);
Bullwinkle, Alces alces

To me, it's strange that x.prototype = y doesn't mean "The prototype of x is y." It means, "If x is a constructor, the objects created by x will have y as their prototype." Ya gotta admit, that's nutty. Also nutty is trying to implement something like the Java keyword super. Look around and you'll find a number of long and involved ways to get that behavior to work correctly.

One of key aspects of inheritance in Java is polymorphism. But, in duck-typed dynamic languages, every method call is polymorphic already. No class hierarchy needed. And why bother mucking about with user-defined type hierarchies anyway? Aren't dynamic languages supposed to free us from diddling about with that sort of thing?

I'm glad classes didn't make it into Javascript 5. But, I wouldn't be surprised if they come eventually, for a couple of reasons. Some people think prototypes are too weird and scary for the average Joe Coder. I don't, but I do think Javascript obfuscates the issue a bit. ActionScript has them. Prototype has them. I suppose that means there's a demand, so they'll probably come.

Links

Tuesday, March 23, 2010

How to read a file line by line in Python

The preferred way of reading text files in Python has changed several times over the years, so it's hard to google up a current solution. I think this would be the preferred way as of Python version 2.6.x and 3.1.x. Please comment if this is out of date.

import sys

filename = sys.argv[1]

with open(filename, 'r') as f:
    for line in f:
        dosomething(line)

...or even better, use fileinput which takes the files given as command-line arguments, or if missing, the standard input.

import fileinput

for line in fileinput.input():
    process(line)

Tuesday, March 09, 2010

Protovis: data visualization in the browser

The Javascript world keeps getting cooler. What with JITting VMs like Google's V8 and Mozilla's JaegerMonkey, frameworks like prototype and jQuery, and an effort towards a standard library (commonjs), javascript is looking more and more like a respectable programming language.

The visualization toolkit Protovis is a taste of things to come. Check out the super-slick examples. One of the framework's creators, Jeffrey Heer, is also the designer of two other visualization toolkits, Prefuse for Java and Flare for Flash and also wrote a nice paper about Software Design Patterns for Information Visualization. In, Protovis: A Graphical Toolkit for Visualization, Heer and coauthor Michael Bostock explain that Protovis is aimed at a niche somewhere between point-and-click chart making programs like Excel and direct manipulation of vector graphic primitives as in Processing.

At heart, Protovis is a small domain specific language for charting. Javascript works surprisingly well as a host language. Like other DSLs, they use method chaining, where methods return the object they were called on, allowing the next method call to be tacked right on. If this isn't familiar, think of StringBuilder in Java.

Example

(stolen from the Protovis docs.)

var vis = new pv.Panel()
    .width(150)
    .height(150);

vis.add(pv.Bar)
    .data([1, 1.2, 1.7, 1.5, .7])
    .bottom(0)
    .width(20)
    .height(function(d) d * 80)
    .left(function() this.index * 25);

vis.render();

The way they've implemented “smart properties” is particularly clever. Property accessors accept either constant values or functions. The assignment of height of bars in the bar-graph example above is done this way. Marks (the protovis term for any graphical element) are associated with arrays of data. A pv.Bar, given a 5 element array, draws 5 bars. We've defined height to be a function of d. So, for each element d in the data array, we get a bar of height d * 80. This is a pleasantly seamless mixture of OO and functional constructs which also brings in something of the flavor of vectorized operations in R.

If you like reading code, the Protovis code is very nicely laid out and makes elegant use of Javascript's quirky set of language features.

Browsing genomes

I hacked up a quick test, which is (what else?) a genome browser. Looks pretty good for a dirt-simple hundred or so lines of code. Note that my quick hack loads up about 8MB of data, which will take some time over slow connections.

One bummer is that Protovis doesn't work in current versions of IE. Still, it works nicely in Firefox and Safari and is especially snappy in Chrome. It sounds as if IE support might happen soon.

For more on Protoviz, check out Robert Kosara's A Protovis Primer.

Grab bag of Javascript and Visualization links

Sunday, March 07, 2010

Quotations

“If we really understand the problem, the answer will come out of it, because the answer is not separate from the problem.”
- J. Krishnamurti

“I believe I found the missing link between animal and civilized man. It's us.”
- Konrad Lorenz

“Civilization advances by extending the number of important operations which we can perform without thinking of them.”
- Alfred North Whitehead

Herbert Simon said, “A wealth of information creates a poverty of attention.”

“Institutions will try to preserve the problem to which they are the solution.”
- Clay Shirky

Quantity has a quality all its own
- Stalin

Technicians care about technique

The truth will set you free.
- The Book of John

But something of the shoddiness enters into the minds and hearts of men, when shortcuts are sought in matters of mental growth which are essentially processes of slow maturing. Education requires time. The only time wasted is that spent trying to save time. There should be no haste or crowding or cramming. Mastery of any subject requires years of familiarity with it. The formal training one receives in an institution is but the introduction. Most people never get beyond a mere bowing acquaintance with knowledge.

- Everett Dean Martin, The Meaning of a Liberal Education, 1926

when you don't create things, you become defined by your tastes rather than ability. your tastes only narrow & exclude people. so create.

- _why

Re: computing

Alan Perlis, once said: “A language that doesn't affect the way you think about programming, is not worth knowing.”

“Every program eventually becomes rococo, and then rubble.”
– Alan Perlis

“Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.”
- Philip Greenspun

“…including Common Lisp”
- Robert Morris

More quotations