Search code examples
haskellprogramming-languagesmetaprogrammingquotingnemerle

What is the meaning of “quasi” in quasiquotations?


Some languages like Haskell (or Nemerle) have quasiquotations. I wonder what the “quasi” means and if there also exist “quotations” without the “quasi” part.


Solution

  • I believe this notion comes from Lisp languages.

    Program written in Lisp consists of series of lists of lists of lists etc, like this:

     (defn f [x y] (+ x y))
    

    Because of such uniformity it is possible to represent and manipulate such code as data, so the sequence of characters above is interpreted as literal list. This is very useful feature of Lisps, one of their distinctive features. For convenience Lisp languages allow to 'quote' meaningful sequences, turning them from definitions and expressions into lists. It looks like this:

     '(defn f [x y] (+ x y))
    

    In this case it is a literal list, directly available for destructuring using analogues of Haskell's head and tail and other methods. So, 'quote' means 'make a literal value from the list'.

    However, it is not convenient to manipulate lists directly with head- and tail-like functions. It becomes notable when you start writing complex macros or even macro-generating macros. So here comes 'quasiquotation', literally 'almost a quotation'. Usually quasiquotation looks like plain quotation (but with another quote symbol):

    `(defn f [x y] (+ x y))
    

    But it is much more powerful thing. In quasiquoted list you can replace arbitrary elements with their actual values from outer scope, essentially obtaining something like patterns. Example:

     (let [z 10] `(defn f [x y] (+ x y ~z)))
    

    Here we are binding value 10 to z variable and then we are substituting it inside quasiquote. This expression yields

     '(defn f [x y] (+ x y 10))
    

    This is simple example; Lisp languages allow doing many other useful things with quasiquotes.

    This notion has transferred to other languages which support manipulation with syntax trees. For example, Haskell facility here is Template Haskell, and it fully supports quasiquotation, i.e. creating templates and filling them with values from outer scope. In languages with complex syntax (like Haskell) quasi- and plain quotations become nearly the only sane way to manipulate syntax trees.

    UPD: hmm, it seems that in Haskell it is more sophisticated feature than simple substitution. Quasiquote in Haskell looks like arbitrary transformer and evaluator of expressions which can be defined by user.