Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 610
soc Avatar asked May 11 '12 18:05

soc


People also ask

What is quasi quoting?

Quasiquoting allows programmers to use custom, domain-specific syntax to construct fragments of their program. Along with Haskell's existing support for domain specific languages, you are now free to use new syntactic forms for your EDSLs.

What is quasi dialogue?

Quasi-quotation or Quine quotation is a linguistic device in formal languages that facilitates rigorous and terse formulation of general rules about linguistic expressions while properly observing the use–mention distinction.


2 Answers

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.

like image 100
Vladimir Matveev Avatar answered Sep 19 '22 17:09

Vladimir Matveev


These notions exist in the Lisp language and its variants.

In these languages, whenever the interpreter sees a list (a b c ... z), it evaluates it, by applying a to the other elements b ... z.

If you want a list not to be evaluated (and thus to be interpreted as a list), you must quote it. For instance, '(a b c) evaluates as a list with three elements, not as a applied to b and c. You can see the quote as stopping evaluation.

Now quasiquotation behaves like quotation, except that you can resume the evaluation inside parts of the list. You quasiquote with the backward apostrophe ` and you allow certain subexpressions to be unquoted with the comma operator (at least in Scheme, I don't know about other Lisp variants). For instance

`(a ,(b c)) 

evaluates to a list with two elements: a, and the result of the evaluation of (b c).

This is particularly useful to build templates, where you fill holes by unquoting. Example (taken from there):

(define (create-shipping-employee-association name)   `((name ,name)     (employee-id-no ,(get-next-employee-id!))     (department shipping)     (hire-date ,(get-day) ,(get-month) ,(get-year)))) 
like image 27
Alexandre C. Avatar answered Sep 18 '22 17:09

Alexandre C.