A Functional Diversion 1

Posted by Oliver on March 23, 2006

Even my friends who aren’t into functional programming find something curously relaxing about this. (And the companion site here.)

I bought foldr.com a year ago when I thought I might do something like Flickr for other types of information. I didn’t realize until last week what I was sitting on. :-)

Update: The use of the infinity symbol sparked a lively discussion on LtU.

JavaScript Gradient Roundrects 7

Posted by Oliver on March 23, 2006

JavaScript Gradient Roundrects adds gradient roundrects to an HTML page, without images. It uses the WHATWG canvas tag if it’s available. Otherwise it uses a stack of divs, whose heights are adaptively chosen according to the height of the graded element, the color components, and the radius curvature. There’s a demo here.

I also wrote a JavaScript CSS parser that lets you attach gradients to an element without writing code. You do this by including CSS inside a div tag whose class is ’style’. View the source of the demo page for an example.

Inline JavaScript Console 11

Posted by Oliver on March 03, 2006

Last week for the first time I did some serious browser JavaScript programming. I put the following tools to good use, but ran against limits with each of them:
* fvLogger
is terrific, but doesn’t include an evaluator. You have to reload your page each time you want to query a new value.
* Rhino is great for pure logic, but you can’t use it with anything that use a browser API. In fact, you can’t use it with anything that uses anything that uses a browser API. This means, for example, that you can’t use it with a library that uses Prototype, without writing some mock objects first.
* The JavaScript Shell is pretty amazing, but I wanted something a bit lighter weight (within the same window), and that works in Safari.

What I came up with is inline-console.js. This file adds an output console, and a text field with an “Eval” button, to the bottom of your application. It also defines some logging functions — info, debug, warn, and error — that append text to the console. (If you include fvlogger, it will use it instead.)

The point of this is to be as lightweight as possible. Add
script type=”text/javascript” src=”inline-console.js” (appropriately tagged) to the document head, and the script will take care of adding the UI.

For more fun, include readable.js after inline-console.js. Then {a: 1} will print as {a: 1} instead of [object Object].

Here’s an example. Try entering some JavaScript expressions, such as 2*3, Math.sqrt(2), or document.body, and then pressing “Eval”. (Click here to open the example in a separate window, where you can view source.)

Files:
* inline-console.js — adds the inline console
* readable.js — adds readable representations for JavaScript objects (optional)
* fvlogger — a nicer console UI with more control over which log levels are displayed (optional)

My other JavaScript libraries are here.

Readable JavaScript Values 6

Posted by Oliver on March 03, 2006

One problem with JavaScript development is that the string representation of a value doesn’t tell you much about the value. For example, [null], [undefined], and '' all display as the empty string. [1,2}, [[1,2]], and [[1],[2]] all display as 1,2 (and so does "1,2"). And ({a: 1}), ({b: 2}), and new MySwankyNewObject() all display as [object Object].

If you use an IDE for development, this may not be a problem. Probably the IDE has its own string representation; even if it doesn’t, you can generally drill into objects by clicking on them. This doesn’t help those us of who prefer REPL development or printf-style debugging. When you display a debugging value (to the browser status line, to the alert() dialog, or to the Rhino console), you’d like some indication of what it actually is. And JavaScript doesn’t generally tell you, at least when the value is more complex than a string, number, or boolean.

Hence, readable.js. Readable adds a Readable class that can stringify a JavaScript value readably, for debugging purposes. Readable.toReadable([1,'', null, [3, 4]]) evaluates to [1, '', null, [3, 4]], not 1,,,3,4. And so on.

To make it easier to use the Readable class, Readable comes with a couple of hooks. First of all, it defines defines info, warn, error, and debug functions1 that display their arguments to the user. In Rhino, these functions call through to print. In a browser, they use alert() — unless fvlogger has been loaded first, in which case they use it instead[]. You can also replace Readable.log(level, message) or
Readable.display(message) to add your own behavior; for example,
to display the message in the status line, or AJAX it up to the server.

Secondly, Readable can add toString methods to Array.prototype and Object.prototype. Do this, and evaluating an expression in Rhino writes a readable representation to the console, without your having to wrap it in info(<var>...</var>) or Readable.toString(<var>...</var>). Doing this has the consequence that iterating over the properties of an Object or Array will yield an extra one (toString), so this is off by default. But define READABLE_REPLACE_TOSTRING before loading the file, or invoke Readable.replaceToString() after loading it, and you’ll get this behavior.

Files:
* readable.js
* documentation

Update: Fixed for Internet Explorer.


1 The reason there’s more than one function is that this is intended to be consistent with fvlogger. It’s also handy to be able to search your sources for one logging function, and not the other.

2 One advantage of including Readable even if you’re already using fvlogger is that now info([1,2]) prints something different from info([[1],[2]]). Another is that Readable extends the fvlogger functions with variadicity: info(key, '->', value) works now. (Without Readable, it’s equivalent to info(key), except that value is also evaluated for effect.) Finally, you can use Readable to extend Rhino with the same logging API. I use this to write modules — such as paths and beziers — that I test with Rhino and integrate into a UI in the browser.