Showing posts from April, 2011

Patterns in Chess Square Enumerations

In my bit manipulation post awhile back I posed a problem involving "closed form" calculation of chess endgame table indices. Back when I originally solved the problem, it was a big help to create some visualizations of some of the patterns embedded in the square numbering scheme. I had mentioned that I thought the patterns were interesting, so I thought I'd come back and elaborate on that statement.One way of visualizing some of the patterns involved is to partition the squares according to the equivalence classes defined by the binary bits of the index. Bits 0-2 are the three low-order bits and bits 3-5 are the three high-order bits. Here are the equivalence classes defined by each of the bits of the natural square numbering.Bit 070717273747576776061626364656667505152535455565740414243444546473031323334353637202122232425262710111213141516170001020304050607Bit 37071727374757677606162636465666750515253545556574041424344454647303132333435363720212223242526271011121314…

Splice Subtleties

In the recent release of Heist 0.5.1, there was performance bug in my implementation of head merging. I turned off the head merging, and then fixed the bug but did not reenable head merging. If you want to turn it back on, you need to bind the html tag to the htmlImpl function from the Text.Templating.Heist.Splices.Html module. I think I'll continue to leave it off by default because it does have some potential to impact performance.

While analyzing the problem, I realized that it involves fairly obscure details of Heist internals that have not been mentioned in any of our tutorial materials. And if I, the original author of Heist fell prey to this problem, it's probably safe to assume that eventually someone else will too. So let's take a look at some details of Heist's internal behavior and the implications for splice developers.

As I alluded to in Heist in 60 Seconds, you can think of a splice as follows:

type Splice = Node -> m [Node]

The actual implementati…

Heist Template Abstractions in a Nutshell

In the last post I discussed how logic and control flow can (and I argue should) be done in splices where types, higher order functions, and the full power of Haskell can be applied to the problem. In this post I want to take some time to think about the raw materials that are available in templates.

At the lowest level, we have just Text (...which is certainly /= Nothing). The templates are read in as Text and parsed into HTML DOM structures: elements, children, and attributes. Heist's abstractions for these entities are roughly analogous to the lambda calculus. The lambda calculus primitives are function definition and function application. HTML structures don't have any kind of representation for functions, so Heist uses lists of DOM tree nodes as the fundamental unit. Two different ways of representing them are splices and templates. The following table summarizes Heist's HTML abstraction tools.

/EvaluationSplices<bind>use the tagTempla…

Looping and Control Flow in Heist

One of the most frequent questions I get about Heist is how to do loops or control flow in Heist templates. I usually respond that we've tried to avoid introducing these constructs into templates to encourage a better separation between view and model/controller. In this post I want to discuss the issue in more detail so that my thoughts are stored and I can refer people here in the future.

Since Haskell is pure and has a strong static type system, the first thing to think about when discussing this question is what types will be involved. Since templates are processed at runtime, they do not have access to Haskell's type system. This puts us square in the middle of byte-land. No generalized looping over things like the list of registered users or recent posts. No type-safe evaluation of arbitrary expressions. It is my contention that you're better off solving these problems with a language designed for that purpose...i.e. in Haskell splices, and not in HTML templat…

Views, Controllers, and Heist

A very common question when using Heist is how to specify views in a splice. There are three different approaches one can take:

1. Specify a splice's view in the Haskell code implementing the splice.
2. Get a splice's view from a template.
3. Pass the desired view to the splice as the spliced tag's child nodes.

Aproach #1 tends to be ugly and violates the principle of separating logic and view.  There are always exceptions to every rule, so we've done a little bit to ease the implementation of #1 by allowing xmlhtml DOM structures to be built with blaze-html syntax.  However, I believe that one of the other approaches will usually be preferable.

Approach #2 seems kind of awkward.  It would result in a whole bunch of small templates on disk that define little pieces of web pages.  An architecture like this might be desireable in some situations as a way to eliminate repetition (and it certainly fits into the functional programming mentality of lots of small functions),…

Heist in 60 Seconds

A template system is a bridge between static data (templates) and dynamic data.

Heist is a template system bridging HTML templates and Haskell code.

A splice is code that Heist binds to an HTML tag.

Every time the tag appears in a template, Heist runs the splice bound to that tag and passes the tag (including its attributes and its children) as input to the splice.

A splice's output is a list of tags that get substituted into the template in place of the original input tag.

Splices can be thought of as functions that can be called from templates to get dynamic data.

Splices can pass this dynamic data back to templates by (temporarily) binding new splices.

<bind> is a tag you can use in your templates to create new splices on the fly.

<apply> is a tag that lets you insert one template into another.

A more in-depth tutorial is here.