Brief Intro to Quasi-Quotation (Show me the types already)

This posts serves as a brief introduction to quasi-quotation in Haskell, because I couldn’t make much sense of the existing documentation, which gets bogged down in unnecessary details about writing parsers, the use of SYB, etc. Also, although quasi-quotation borrows syntax from Template Haskell, the TH expression  [|e|]  and the QQ  [qq|e|]  are false friends at best.

Recap: Template Haskell

Template Haskell is a library and language extension for writing Haskell meta programs: Haskell code that generates Haskell code (sometimes called macros in other language communities). The language extension allows us to quote Haskell expressions:

The quote syntax  [| someExpression |] is a convenient way to create quoted expressions; that is, values of type  Q Exp ; likewise,  [t| someType |]  can be used to quote types.  Q is the Template Haskell monad, which allows to create fresh variables, get location information, or even perform arbitrary IO;  Exp and  Type are types from the TH library that reify Haskell expressions and types. There’s nothing special about them; we could have written 

instead (the double tick indicates we want the name of the type, not the type itself).

We can use a quoted expression where Haskell expects an expression by splicing it; similarly for quoted types. For instance, we can write

Quasi-Quotation

Quasi-quotation extends Template Haskell and makes it possible to write custom parsers. The most important data type is

Here’s a trivial example:

But now here’s the confusing part: consider the following example

This is a splice, not a quote! The appropriate parser in the quasi quoter (depending on context) is used to convert the string to a quoted expression, and is then spliced in as an actual Haskell expression; in fact, this example is equivalent to

Really the only difference is that the syntax is somewhat more convenient, that it automatically picks the right parser for the context (type vs expression, etc.); moreover, quasi-quotes can be used in patterns, as we shall see below.

Meta-Variables and Anti-Quotation

First two more Template Haskell examples:

The first example uses simple type class defined in the TH libraries:

The second example shows that we can splice inside quotes; actually,  ex8 is an identify function (quoting and splicing are inverses). Unless we modify our quasi-quoter, however, the following two functions probably don’t have the intended effect (whatever the intended effect was):

Both of these functions ignore their argument; the first evaluates to the string "x"  and the second evaluates to the string "$x" . If we want to support meta-variables we need to modify the parsers for our quasi-quoter. The convention is that parsers in quasi-quoters recognize $x  as referring to a meta-variable x . We can define a quasi-quoter that only recognizes these as

and then define

(But note the difference in type between ex8  and ex9.) In fact, if we extend our quasi-quoter with a parser for patterns too:

then we can also use a quasi-quote in a pattern position (something that TH does not support):

Conclusions

If you are already familiar with Template Haskell then quasi-quotation isn’t much of an extension, except that the resemblance in syntax is confusing and misleading. The only thing I haven’t covered in this short post are  dataToExpQ  and  dataToPatQ , which are basically generic versions of TH’s  Lift class, with support for anti-quotation. See Section 3.2 of the original paper for details.

How to be a good coach

Over the years in my insane attempt to reach my Black Belt Instructor qualification in Krav Maga I have trained with a great many coaches in a great many countries. Some have been awesome; Gerwin Kranenburg (2nd dan) of Safety Training Center in the Netherlands and Matt Romond (3rd dan) of Krav Maga Worldwide in Los Angeles spring to mind; and, more recently but in a different field, John and Evelyn of Salsa Dublin are fantastic instructors. Other instructors have been terrible. But what exactly makes a good coach? Continue reading

Comprehensive Haskell Sandboxes

Serious Haskell developers will want to test their packages against different versions of ghc, different versions of libraries, etc. It is therefore useful to have multiple Hackage development environments, or sandboxes. A comprensive sandbox contains:

  1. An installation of ghc
  2. A package database
  3. cabal configuration (for instance, so that we can pin packages)

Moreover, good sandboxes are

  1. isolated from each other: only the active sandbox can be modified
  2. relocatable: it should be possible to copy the sandbox ~/env/ghc762 to ~/env/client1 to use as the basis for a new sandbox, or to copy the entire set of sandboxes (~/env) from one machine to another (suitably similar) machine (this means that paths in config files or baked into executables should never mention the name of the sandbox)
  3. self-contained: there should be no need for a system wide install of ghc
  4. transparent: we should be able to use the standard tools (ghc, cabal) as they are

There are existing tools for Haskell sandboxes (such as cabal-dev or hsenv), but none satisfy all of the above requirements (to the best of my knowledge). However, it is easy enough to set up our own.

Continue reading

Performance problems with -threaded?

Consider the following two implementations of a very simple ping/pong server and client, one written in C and one written in Haskell:

Neither of them has been particularly optimized, that’s not the point of this post. The point of this post will become evident when we measure the latency for the following three programs:

  1. The C program compiled with -O2
  2. The Haskell program compiled with -O2
  3. The Haskell program compiled with -O2 and -threaded

Continue reading