Thomas Mayfield

Introducing Literate Minuteman

It’s a little odd to be writing an introduction to something I’ve been actively working on and using for the better part of a year. I think I’ve fallen into the trap of wanting to add just one more thing and polishing that one feature before showing the world what I’ve made.

So, hello world. Here’s Literate Minuteman. It’s a free service to check the books on your Goodreads to-read list against your local library’s catalogue, letting you know which books are available and where, right now.

You can use it to see which books the whole library system has, or those at just a particular branch, or those at a particular set of branches—for example, those closest to your house. You can also use custom lists from Goodreads; instead of my to-read list, I’m using a list that has everything I’ve been meaning to read, but don’t actually own.

Right now, the supported library systems are the BPL and Minuteman networks in the greater Boston area and the Orange County system in North Carolina. This is simply because I live in Boston and have friends and family in Orange County, so that’s what I’ve written so far! I’ve tried to create a set of helpers to make it pretty easy to add new libraries: it just requires a bit of Ruby code and the library to have a publicly accessible catalog search on the web. Both pull requests on Github and alcoholic bribes are encouraged ways to get your local library supported.

There’s a ton of improvements I’m working on, particularly:

  • Better mobile support. The site’s workable on a smartphone right now, but the design could be more responsive and badly needs offline support. The Cambridge main library’s science fiction section is in the basement and, as far as I can tell, was built inside a Faraday cage for all the cell phone signal I get in there. I’ve got work on this underway right now.

  • Call number support. No reason to have to go to a terminal or card catalog while at the library find out where the book is.

  • Support for services like PaperBackSwap. There’s an ISBN-importing Javascript thing I use to import my Goodreads wishlist to PaperBackSwap, but I have to remember to run it manually. This should be easier.

If it sounds like Literate Minuteman tickles your fancy, give it a whirl and let me know what I can do to make it more useful for you; this is very much a labor of love.

Notes on Haskell: Seven Languages in Seven Weeks

I’ll admit I approached Haskell with a bit of trepidation: the language has a tongue-in-cheek unofficial motto of “avoid success at all costs” and a reputation of only being used by academic ivory-tower types.

Functional Strength

Haskell’s functional programming model is pure as the driven snow: unlike some of the functional languages earlier in the book, there’s no mutatable state whatsoever. Period, end of story. Like all the previous functional languages, lists of data are a first-class primitive and there are a number of tools for slicing and dicing them. The usual map/filter/fold suspects are around, as are succinct form for defining anonymous functions and some powerful list comprehension forms.

Lazy evaluation seems to be the default mode in Haskell. Under the hood, every function has a single argument—functions with multiple arguments are split into multiple functions that are then applied to each other. This allows for easy currying—saving functions with partially bound arguments for later full evaluation. These partially applied functions let you do some pretty nifty tricks, like incrementing a list via map (+ 1) [1, 2, 3]. Lazy evaluation also allows functions to be infinite generators without any special invocation or magic.

Not My Type

Haskell, while strongly typed, requires surprisingly little type declaration—the type checker can infer much of what it needs from the structure of the code. You can define your own types quite easily, both in terms of other types and recursively. These recursive definitions can lead to some very terse expressions of complex concepts - a one-line tree type definition, for example.

After all that, I have to admit that I don’t totally grok Haskell’s type system. Fighting with type error messages in GHC is what prevented me from doing most of the non-trivial exercises in this chapter. It’s apparent that once you learn to use it well, Haskell’s type system is sophisticated and very powerful—but for me, the learning curve proved greater than my enthusiasm for the language. Perhaps I’m spoiled by more dynamically-typed languages.

Monads (Or, What Is This I Don’t Even)

The book attempts to explain monads initially through an example involving drunken pirates, which is a perfectly good stand-in for my mental state while trying understand how monads work. The idea—I think—is a generally applicable way to represent state in a language that has no mutatable state. Monads seem to act as functions whose return values can work as state accumulators when chained together. Using monads under the covers, the do statement lets you write imperative looking code, but it’s actually chained together with monads and winds up boiling down to one big function invocation. That top-level conceptual understanding is where I stopped—exactly how to implement and practically use a monad was still a mystery to me after a section’s worth of examples.

Thanks For All The Lambdas

At the end of this chapter, my trepidation unfortunately seemed justified. Perhaps it was a bit of new language burn-out or perhaps it was Haskell’s vertical learning curve, but I had a hell of a time getting as much out of Haskell as I did out of the other languages the book covered. Frustration with Haskell aside, I had a blast with Seven Languages In Seven Weeks. Covering big swaths of intellectual territory is always fun, and I’ve got a non-trivial desire to start a deep dive into Clojure soon. Time to get back to building things.

Notes on Clojure: Seven Languages in Seven Weeks

I’ve been looking forward to digging into Clojure ever since I saw Rich Hickey’s keynote at RailsConf2012. I’m still chewing on some of the philosophy Rich introduces in that talk, and wanting to seeing his approach to language design was a big part of why I picked up Seven Languages In Seven Weeks in the first place. Plus, I haven’t had the chance to mess around with a Lisp since that semester in college of finding myself in the empty list…

Basics

Clojure is a Lisp dialect that runs on the JVM, with data and code alike represented in lists. The oft-quoted complaint about “Lisp parenthesis soup” is helped by syntactic suger for Clojure’s basic collection types: associative maps are denoted with {}s, sets use #{} and vectors have[]s. Even in just a couple days with the language, the parenthesis just become a form of whitespace when visually scanning properly indented Clojure.

These basic data structures in Clojure feel very well thought out, with Sequences serving as a common abstraction over most collections. Sequences are simply anything that implements the following interface: get the first element, get the rest of the sequence without the first element, and add an element to the front of the sequence (car, cdr, and cons for you Schemers playing along at home). Sequences can be lazy, allowing for some pretty powerful generator-like effects.

Clojure’s tools for working with these sequences are great. The usual functional suspects are there: map, foldl, and filter, along with a terse form for anonymous functions. There’s also some new stuff: the take function grabs a finite number of elements from the front of a sequence- so given a lazy sequence computing the fibonacci numbers, you could get the first N with (take N fibonaccis). interpose works like Ruby’s join, but works on and returns a sequence, so can be chained with other operations. Clojure also sports one of the most powerful list comprehension forms I’ve seen, supporting an arbitrary number of clauses and filters, even acting over multiple collections.

On the JVM

Rather than attempt to remain platform agnostic, Clojure seems to embrace the JVM as its host environment. Just like Scala, native Java types make appearances all over the place, though without a great deal of friction. The book didn’t have the space to elaborate, but hinted at some pretty slick integration with native Java libraries. Beyond just existing code integration, Clojure gets to reap the man-centuries put into making the JVM fast, stable and possessed of one of the sophisticated garbage collectors out there.

Running on the JVM has its limitations. Without native support, Clojure has no tail recursion, although it provides a loop/recur construct for efficiently unrolling recursive calls.

Also interesting is that although Clojure binds itself tightly to the JVM, there are independent ports of the language to Javascript, Python, C, .NET and more…

Records and types, not objects

Clojure eschews Java’s approach to object-oriented data modeling, particularly leaving behind the notion of class-based inheritance. Types are defined with defrecord and functions are grouped around types with defprotocol. Types are immutable - instead of modifying a record in-place, you return a new, different copy. There’s an emphasis on just enough abstraction over the data; types behave like maps, so you can start with a simple associative data structure and just add more behavior when you need it.

Types can interact fully with other code on the JVM, although the implications of this are unclear to me. Can I pass Clojure records to other JVM languages and have their immutable semantics respected?

Concurrency

Clojure’s functional approach and strong push for immutatable state were designed to aid writing concurrent programs. State mutations can only be done inside explict transactions that prevent concurrent modifications from attempting to muck with a value at once. The atom construct provides some sugar for concurrency-safe changes on a single value.

There are a couple of different mechanics to actually executing code in parallel. Agents can do asynchronous processing with the same thread-safe transactional access mechanics as atoms. Reading a value from a reference, agent, or atom won’t lock or block - updated values are just flipped in transactionally. So you might get an out-of-date value, but never one in an inconsistent state. Futures are another option for concurrency: they evaluate asynchronously, but reading their value returned blocks until evaluation is finished.

Clojure runs deep

My brief tour of Clojure had me recalling the ‘oh, wow’ feeling I felt learning Python for the first time after a few years of Java and C++. Clojure’s got some powerful ideas that I’m going to be trying to wrap my head around for a while. There’s a fit-togetherness about the language that makes me want to dig into it further. This is the first language in Seven Language In Seven Days that made me go out and buy a book on it before I was even done with the chapter—I’ll be tucking into Clojure Programming just as soon as I’m done with Haskell.

Notes on Erlang: Seven Languages in Seven Weeks

Erlang’s syntax and semantics feel like modern Prolog. It’s another almost-purely functional language, with all immutable variables. Basic operations are done via pattern matching with free variables and list deconstruction that make it clear why Prolog came first in the book. Erlang also shares Prolog’s bizarre-to-modern-eyes punctuation rules; I still haven’t quite figured out when a statement should be terminated with a comma, period or semi-colon.

Practical Prolog?

Thankfully, actually doing anything in a functional manner felt a lot easier with Erlang than with Prolog. Erlang is dynamically typed and has anonymous functions, along with the usual raft of each/map/reduce-type helpers. There are also a couple of functional primitives I hadn’t seen before: takewhile and dropwhile select or drop the all of the first items from a list that match the passed function until the first item that doesn’t match. Most of these operations can be further simplified syntactically with list comprehensions that can take an arbitrary number of conditional or modifying clauses. Cool stuff.

Interestingly, there’s also native syntax for binary packing and unpacking, which I suppose makes sense if Erlang was developed for telephony systems.

Free-Range, Grass-Fed Organic Systems

Erlang’s whole raison d’être is building fault-tolerant distributed systems. Like Scala, the basic concurrency primitives in Erlang are actors: lightweight processes that share nothing between them and communicate by message passing. Erlang’s pattern matching works quite beautifully for interpreting and acting upon these passed messages. Message-passing itself is asynchronous, but it’s fairly simple to build services that can provide a synchronous, blocking interface to actors.

There’s a marked emphasis on dealing with failure (“let it crash”) instead of attempting to recover from errors.Building a process that monitors other processes and restarts them when they die is a matter of a couple lines of code. The book alludes to built-in mechanisms for setting up distributed servers, communicating between them, and even hot-swapping code in-process but doesn’t go into depth due to space constraints.

I’ve got admit that I enjoyed my brief tour of Erlang more than I thought I would, especially after how unenthusiastic I was about Prolog. I’m still not sure I’d reach for Erlang unless I’m building a system that I know will be massively multi-server from the get-go. The actor model for concurrency is elegant as hell—but a lot of other, more familiar-feeling languages have copied it.

Notes on Scala: Seven Languages in Seven Weeks

After Prolog’s brain-bending, it was a bit of a relief to tackle Scala and return to a more familiar general-purpose language with a C-descended syntax.

Java++?

Scala seems to be attempting, in many ways, to be a better Java. It runs on the JVM and interoperates with Java freely - you can literally mix and match Scala and Java files in a single project, with all the classes involved able to call into each other without any translation layer. Many of the design choices made seem to attempt to solve Java’s problems, while still remaining compatible:

  • Scala, like Java, is strongly and statically typed, but does away with much of the ceremony around type declaration. Types are often simply inferred by the compiler, with no need to declare them.
  • Scala has Java’s classical object inheritance model, but there are syntactic shortcuts for many parts of the system. Stuff like: constructors with no parameters can just be expressed as bare code after the class definition line, and short functions can be expressed on one line.
  • Class methods and interfaces are present in Scala, but are actually separated out more cleanly into companion object declarations. Things defined with the Object keyword are straight-up class method structs, but Traits actually behave more like Ruby mixins than Java interfaces.

This level of improvement feels akin to CoffeeScript vs. Javascript: pretty great stuff, some nice improvements, but nothing that will affect the macro-level patterns one uses to write code or one’s overall productivity.

LISP-y Behavior

Here’s where Scala actually adds something to its Java roots: it supports real functional programming right alongside OOP. Scala has first-class, anonymous functions with lexical closures and a nice terse syntax for expressing them. Working with Scala’s collections will feel natural to Rubyists: you’ll find yourself happily mapping and folding along.

Scala’s concurrency model ties neatly into its functional nature. Rather than threads that share data and must deal with locking and concurrent access, Scala (like Io) uses asynchronous actors with no shared state These actors communicate via messages, the receiving of which can take advantage of some of the very powerful pattern matching at the core of the language These aren’t just case statements, but can do matching with conditional guards, regular expressions and even singleton types declared just for message-passing.

Scala’s typing model is clearly built to aid both concurrency and function programming - the choice of val vs. var when declaring a variable determines whether the variable is mutable or not. Given that immutability is so important for FP and parallel programming, that Scala has mutable variables at all feels like a compromise to interoperate with Java.

Friction

Though Scala seems to be trying to do away with the syntactic bulk of Java (and the cognitive overhead associated with it), it certainly comes with its own set of baggage and ceremonies. For example, when extending a class via inheritance, you must use the override keyword anywhere the original classes signatures are overridden, even constructor parameters. Even at a syntax level, there’s a lot going on, even if it doesn’t contribute to lines-of-code-bloat like Java: a <- here means dereference something enumerable in a loop and there a -> means mapping a key to a value in Map creation shorthand. Types get odd at times as well: Any is everything’s superclass (ok) and Nothing is a subclass of everything (wat).

Then there’s the XML literals. I think it’s ultimately a gimmick: if you’re slicing and slicing a lot of XML files, having XPath querying built into your language can be nice, but do we really need support for this at a syntactic level? And because the web isn’t generally valid XML, using this for HTML screen-scraping is a non-starter. I just don’t get why this sort of thing isn’t a user-space library.

I’ve got mixed-to-negative feelings of Scala after this little first date with the language. If I were stuck on a big Java project and needed a better tool I could use without chucking the existing codebase, I might reach for Scala - but I’m not, and the language does doesn’t hang together well enough for me to consider putting a lot of time into learning more about it.

Notes on Prolog: Seven Languages in Seven Weeks

A quick note on setup: on OS X Lion, I had to install GNU Prolog with brew install gnu-prolog --use-gcc to avoid compilation errors when using Clang.

Let’s get this out of the way: Prolog is not a general purpose language. It has its niche and can do some pretty interesting stuff inside that domain, but it’s not exactly suited for talking over a network or processing XML. Instead, Prolog is a declarative logic engine: you feed it knowledge and rules, then given these facts and constraints, it can be used to solve for values that fit your world of truth. You can prove statements true or false (“is a cat a mammal?”) or find missing pieces to make true statements (“I need yeast, barley, water and what else to make beer? Solve for what else.”).

Most of Prolog’s power seems to come from defining recursive rules that operate on lists of data. You can split apart lists with the [Head|Tail] syntax that reminds me of messing with lists in Lisp recursively with car/cdr. Problem solving using this approach feels very much like when I used to mess around with Scheme in college, but the process of unification—making symbols on both sides of rule agree— was hard to wrap my head around. For example, rather than saying something like result = sum([1, 2, 3]), you’d say sum([1, 2, 3], Result)., with Prolog supplying the value for unbound variable Result that would make it equal the sum of 1, 2 and 3. I would up doing a lot more thinking than typing when working through the problem sets.

I’ll be honest: Prolog was pretty unexciting to me, and I couldn’t muster up a lot of enthusiasm to work through the example problems. Writing a 27-line sudoku solver by just defining the rules of sudoku is pretty cool and all- but it’s a long leap from there to actually solving someone’s problems in the real world. A more practical example the book gives is a scheduling problem- given a set of scientists with varying schedules and given a laboratory with equipment they need to share, find a schedule that will fit all of them. Parsing languages according to a grammar seems like another interesting application, as do some forms of AI decision-making. All the same, I can’t see myself investing a lot of time in learning more about Prolog until I’ve got a Prolog-shaped problem in my daily work.

Notes on Io: Seven Languages in Seven Weeks

I realized recently that though I’d learned a number of new technologies over the last few years, it had been far too long since I learned a new language. I picked up Bruce Tate’s Seven Languages In Seven Weeks a month ago to remedy this, and wanted to jot down some notes as I went on my Magical Mystery Tour of programming languages.

Quick aside: The books starts with Ruby. I’ve been writing Ruby on and off since 2007, and professionally with Rails for the last year, so I have a reasonable grasp on the language already. I didn’t do the exercises, but was impressed with the author’s approach. Each language is split into three days- Ruby’s chapter goes very quickly from syntax and type system basics all the way down to Ruby’s flavor of metaprogramming. Relative newcomers to Ruby (especially in the Rails world) would do well to work through this chapter- you might just come away with a much better understand of how all that Rails magic actually works.

On to Io.

What Moving Parts?

Io’s core syntax is the simplest thing this side of Scheme. All the hard rules are contained in a scant few pages of this chapter. Everything else is malleable to a pretty ludicrous degree.

Everything in Io is an object; objects, in turn, are just sets of named slots. Slots can contain either methods or data. All interaction is done via message-passing: Foo bar sends the message bar to object Foo - either returning the data in slot bar on Foo or calling the method bar on Foo, depending on what’s in the slot.

Io, like Javascript, is prototype based. You clone existing objects rather than instantiating new ones from class templates. Messages are passed up the prototype chain to the object’s parent if the object itself doesn’t know how to handle the message. If you’re fuzzy on prototype-based inheritance in Javascript, read this chapter. It’ll help even if you’re using a library or transpiled JS language that mocks class-based inheritance for you.

Interestingly, types in Io are just themselves objects. Creating an object with a lowercase name gives the resulting object a type slot with a reference to the cloned object; objects with uppercase names don’t get this type slot and get treated as types by convention only. Cloning Meat from Food would create an object you’d likely use as a type, but cloning bacon from Meat would simply give you an object with a type of Meat.

Bending Reality

And you thought Ruby was great for making DSLs? Io lets you redefine and extend everything from the built-in operator table to the semantics of message-passing between objects. Everything is open for reflection - I’m used to object level reflection from Ruby et al, but the message level reflection that lets you get the target and sender of the message inside the call was new and cool.

The last section of this chapter takes you through defining a JSON-ish syntax for map literals and a lispy-looking way to define XML tags, each in around 20 lines of code. It’s pretty indicative of what you can do with the language that I managed to break vim-io’s syntax highlighting with completely valid, executable code while working on these examples.

I’m honestly a bit wary of all this. I’ve seen beautiful APIs created by metaprogramming in Ruby, but I’ve also seen my fair share of coding horrors done with the same. I’d like to be able to rely on at least some common rules when using someone else’s code and not worry that it’s just subtly altered the environment everything else runs in.

All At Once

Io’s concurrency features are slick as hell. There’s no preemptive multitasking here - no locks, no threads, no worries about concurrent state-modification. Everything is done through user-level cooperative coroutines.

The mechanics of using coroutines are as simple as the language’s syntax. Any message can be converted to an asynchronous actor by prefixing it with @@. The message passing then returns nil and the execution of the method goes on in the background: blender liquify can be converted to a background job by just changing it to blender @@liquify. A coroutine can call yield to voluntarily give control back to another coroutine- useful for running two jobs in parallel with interdependent steps.

Prepending a single @ to a message returns a future instead of nil. You can store the future and go about your business while the object in question does its async business out of band. When the caller needs the result, they pass messages to the future as though its result had already returned. If the result is ready, everything proceeds as normal; otherwise, the current coroutine blocks until the future returns. Apparently there’s also automatic deadlock detection - Io will automatically raise an exception if one is detected instead of hanging.

I really like the idea of futures for the low-hanging fruit involved in something like rendering a page that needs 5 database queries worth of data. Each query is independent of the others, so you just kick them off in the background, grab the futures returned and start your rendering, accessing the future-query results as needed. You’re still bound by the length of the longest query, but there’s no reason to wait for the preceding one to return before calling the next.

Up next, Prolog. At this rate, it’s going to be “Seven Languages in Seven Months”. But I’m having fun.

Backbone Views and the Law of Demeter

I’ve been getting more and more excited about Backbone.js over the last few months. One of the greatest things about the framework is that it’s so unopinionated and modular that you can do anything between writing your whole app using Backbone idioms or applying just one or two pieces to an existing app. I’m particularly interested in how Backbone Views encourage cleaner separation between Javascript components on a page, without even using any other Backbone components. Let’s explore this a bit.

Javascript Soup

I was lucky enough to attend Sarah Mei’s great talk on Backbone.js at RailsConf this year. She rather aptly described the phases a Rails app moves through in its usage of Javascript: from the “what Javascript?” view helpers like link_to_remote and friends, to adding just a bit of extra functionality in that one view with a few lines of real JS, to what she terms a “jQuery Explosion”. You know, when that little unobtrusive enhancement somehow became a five-hundred line stateful nightmare that’s hard to modify and harder to test? Her thesis is that this right here is Backbone’s sweet spot: non-trivial existing Javascript apps that are beginning to age and struggle due to lack of structure.

One of the patterns that comes out of poorly structured Javascript is violating the Law of Demeter. The Law of Demeter concerns loose coupling: it states (loosely) that each component of a program should only talk to its immediate “friends”- that is, other components of the program closely related to the current component. This has been generalized to “use only one dot” (meaning a.doSomething() is probably ok, but a.b.doSomething() is using too much knowledge of a’s implementation). In client-side Javascript, this can be applied by thinking of a page component’s DOM elements as out of the reach of other page components. Your navigation widget might communicate with your breadcrumb widget by event binding or direct method calls, but shouldn’t be reaching in and monkeying with the other’s DOM elements directly.

How Backbone Helps

Backbone Views encourage better patterns in a couple ways:

Scoped Event Binding By Default

Let’s look at a trivial Backbone View that represents a navigation bar.

1
2
3
4
5
6
7
8
9
App.NavigationView = Backbone.View.Extend({
  el: '#nav',
  events: {
    "click li.item a": "navigate"
  },
  navigate: function(evt){
    // ...
  }
})

This view binds to the existing element on the page with the id nav - this element becomes the view’s root. All elements under it can be considered direct properties of the view, and only this view should directly manipulate them. The events property in the view’s configuration options here binds click events on elements matching the selector li.item to the view’s navigate method. This is automatically scoped to only match elements that are descendents of the View’s root element. We’ll only ever match events from our private DOM elements, and other Backbone components on the page won’t match events from our elements.

You can get the same effect with something like $('#nav li.item a').click( /* nav function */ ), but this requires more discipline and doesn’t have the same effect of keeping all of our component’s event concerns in one place. It also establishes a common pattern of event handling across all our page components: convention over configuration.

Scoped Selectors

Setting up scoped event binding is great for maintaining our limited knowledge and encapsulation with regard to event handling, but once it’s time to actually modify those DOM elements, we need a way to do those operations with the same limitations.

Backbone provides a convenient way to make a query scoped to just the view’s elements: the this.$ function. Nothing fancy going on here: in a Backbone View, the root element of the View’s DOM is bound to this.el, so this.$ is just sugared-up $(this.el).find. Let’s take our navigation bar example from above again. We’ll make it set a current location field when you click on a navigation link.

1
2
3
4
5
6
7
8
9
10
App.NavigationView = Backbone.View.Extend({
  el: '#nav',
  events: {
    "click li.item a": "navigate"
  },
  navigate: function(evt){
    var location = $(evt.target).text()
    this.$('.location').text(location)
  }
})

Nothing much surprising going on here: we grab the text from the link and plunk it down inside the element with class location. But consider what we got by using the view’s scoped selector instead of a document-wide query:

  • We know we’re only modifying the DOM elements this view directly owns.

  • Our event handling code here doesn’t have to care if there’s more than one instance of NavigationView on the page. Multiple instances require extra care without a wrapping view- you’d need to know whose location element to modify and how to pick the right one.

  • This built-in knowledge of the component’s root also eliminates fragile traversals from the event’s element to the piece you want to modify. No more temptation to do stuff like $(e.target).prev().children('.location') in your event handlers, only to have them break when you alter your structure.

  • Even better, with this pattern, use of queries outside of this.$ can serve as a useful warning sign that you’re stepping outside the limits of knowledge that your component should have.

We’re Just Getting Started

Backbone offers a ton of ways to structure and modularize your Javascript code. You can represent your application’s state as Collections of as validated Models, write single-page apps with Routers, even render your HTML entirely client-side with various kind of JS templating - all of which can be pretty intimidating when you’re staring at years of jQuery soup and wondering where the hell to start. One of Backbone’s most important features, however, is that you don’t have to jump in whole hog. Teasing apart the code for individual page components into Backbone Views that respect the Law of Demeter has some immediate benefits and is a great jumping-off point for bringing some much-needed structure to your app’s Javascript.

Compiling Javascript Templates With Guard

Yesterday, I released the first version of guard-templates, my Guard plugin for compiling Javascript templates as you work. Guard is a nifty tool for watching a directory for changes and taking some kind of action upon the changed files - running tests, compiling SASS or Coffeescript, firing a Growl and about a billion other things.

The idea behind guard-templates is pretty simple: let your JS templates live in their own files in your project’s source tree and have Guard turn them into Javascript you can use, as soon as you save them. Some frameworks have mechanisms for this already (Rails’s Asset Pipeline, for example), but I wanted something I could drop into any project regardless of the technology being used. Let’s say you had the following Handlebars template:

javascripts/templates/post.handlebars
1
<div>{{example}}</div>

With guard-templates configured to watch .handlebars files, it’ll automatically compile to a simple JS string version of the file, ready to be included in the brower:

public/javascripts/templates.js
1
2
3
MyApp.templates = {
  post: '<div>{{example}}</div>'
}

Bam, ready to use JS templating without gross inline string literals or Ajax requiring. But wait, there’s more! My favorite JS templating language is Jade, a HAML-ish language that supports precompilation to JS functions to avoid parsing the template itself at runtime.

javascripts/templates/post.jade
1
2
3
ul
  li.first
    a(href='#') foo

After processing, this becomes a ready-to-call function:

public/javascripts/template.js
1
2
3
4
5
MyApp.templates = {
  post: function anonymous(locals, attrs, escape, rethrow) {
    // contents tuncated for brevity's sake
  }
}

More options and details on usage are documented over on the project’s GitHub page. Drop me a line if it’s useful for you or if something’s broken.