Fork me on GitHub
isolate.js via AST analysis
interactivate
Recent changes in SDK
nodeconf 2012
Write logic, not mechanics
protocol based polymorphism
(clojurescripting :intro)
namespaces
JS Guards

I’ve written micro library, to solve a very common problem in JS code today. Most likely following example looks familiar:

function Constructor(options) {
  options = options || {}
  if (typeof options.url !== 'string')
    throw new TypeError('url is required!')

  // Finally, your logic here!
}

First of all, code is wrong. If falsy value is passed to a function it will misbehave. Secondly, boilerplate code makes it less readable. It takes three lines to validate just one property (very likely to have more) of the given data structure. Finally, validation code does not even belongs there, as it has nothing to do with an actual logic of a function.

What we actually need is an annotation enforcing certain constraints. We don’t have annotations in JS, but we have functions that are omnipotent! Just about everything can be solved everything using functions.

function ConstructorOptions(options) {
  if (options === null || options === undefined)
    options = {}
  if (typeof options !== 'object')
    throw new TypeError('Options must an object!')

  if (typeof options.url !== 'string')
    throw new TypeError('url is required!')
}

function Constructor(options) {
  options = ConstructorOptions(options)

  // Your logic here!
}

This example is much better, because reader of Constructor function can concentrate on function logic, without being distracted by a validation boilerplate. In addition, options’ validation code can be independently unit tested and in some cases reused.

JS guards, is a small library that takes this idea to the next level. It provides declarative and recomposable way to define data type & data structure validations.

var guards = require('https://raw.github.com/Gozala/guards/v0.3.0/guards.js')

// Define a { x, y } data structure, where x and y fallback to 0.
var Point = guards.Schema({
  x: guards.Number(0),
  y: guards.Number(0)
})

// Define any type of guard as a function
function color(value) {
  // If validates just return value
  if (typeof value === "number" && value <= 255 && value >= 0) return value
  // If not throw TypeError
  throw new TypeError("Color is a number between 0 and 255")
}

// Define a [0-255, 0-255, 0-255] data structure guard.
var RGB = guards.Tuple([ color, color, color ])

// Compose data structure out of existing guards.
var Segment = guards.Schema({
  start: Point,
  end: Point,
  color: RGB,
})

Segment({ end: { y: 23 }, color: [17, 255, 0] })
// { start: { x: 0, y: 0 }, end: { x: 0, y: 23 }, color: [ 17, 255, 0 ] }
Segment({ start: 0, end: { y: 23 }, color: [17, 255, 0] })
// TypeError: Object expected instead of number `0`
Segment({ color: [ 10, 40, '30' ]})
// TypeError: Color is a number between 0 and 255

You can use this library in browsers, jetpack and nodejs. Also, you can try it out right now via interactive example on JSFiddle. For more details and examples check out library documentation. Finally, there is a guards proposal for EcmaScript and chances are we’ll get a syntax sugar some day (It will take a while though as it’s not even in Harmony).

As always I’m more than happy to hear your feedback!

JavaScript JS Documentation: JS Array some, JavaScript Array some, JS Array .some, JavaScript Array .some
Packageless modules
Addons in multi process future
Yet another take on inheritance
Shareable private properties
Evolving VS Adjusting
oh my zsh
Git status in bash prompt
CommonJS based Github library
Taskhub
Gist plugin for Bespin
Reboot
google pages is dead
narwzilla
JSDocs
bespin - JavaScript Server
bespin chromend
Google App Engine + Helma = geekcloud
Bespin to Helma
bespin multibackend mockup
Adjectives | Ubiquity + Bugzilla love
Some Mock-up around Ubiquity
Mozshell
Ubiquity command Say
ubiquity command dictionary
Picasa Photo Viewer (Linux port) - Updated
Ubiquity command for JIRA & Crucible
Picasa Photo Viewer (Linux port)
VirtualBox
KeyZilla 0.1
XUL Development