When to use backquote in scheme?

1.2k views Asked by At

For scheme implementation supporting R5RS, defining a macro can be done by pattern matching in syntax-rule, in this case why we need backquote?

I learn some very basic lisp through emacs lisp , in elisp we have to use lots of backquote to write a macro, but for scheme which support pattern matching, is there any situation that having a backquote can be useful? Or should I ask under what circumstances a schemer will usually use backquote to help them solve the problem?

3

There are 3 answers

0
John Clements On

Backquote is enormously helpful in "templating". To take a simple example, lets say I want to construct an html-like element containing an unordered list whose second element comes from a program variable called placeholder. I would write that like this:

`(ul (li "the first item")
     (li ,placeholder)
     (li "the third item"))
0
Neowizard On

Quasiquote (i.e. backquote) is just a syntactic suger for runtime list construction.

It's a very useful one too. First off it gives you the obvious quick list construction, allowing you to quickly move from evaluation to quotation context.
For instance the code (cons (append (list a 'b) c) d)) can be written as `(,a b ,@c ,@d) (unquote-splicing, denoted with ,@ is used to append the list resulting from an expression).

Second, it allows to very quickly trace debug a piece of code. Say you have the following code:

(define string-split
  (lambda (s delim)
    (reverse (car (fold-left
                   (lambda (p ch)
                     (let ((str-lst (car p))
                           (char-lst (cdr p)))
                       (if (char=? ch delim)
                           (if (null? char-lst)
                               (cons str-lst '())        
                               (cons (cons (list->string (reverse char-lst)) str-lst) '()))
                           (cons str-lst (cons ch char-lst)))))
                   `(()  ())
                   (append (string->list s) `(,delim)))))))

If you call it with the arguments "abc def" and #\space, you'll get an error from list->string. It's hard to see what went wrong and where, but if you quasiquote the call to list->string and unquote (using ,) the argument char-lst, it'll give you a good hint to get started.

3
Sylwester On

You make it seem like the only time we make lists it is to generate code. This is not the case.

The backquote syntax is just syntax sugar for some literals and some expansions. So instead of writing:

(list 'this 'is expr)

You can write

`(this is ,expr)

These have pretty much the same object code. So to answer you question: In the event you are going to produce a list or tree (lists of lists) which has parts that are literals and some parts that are not, using backquote and unquote greatly simplifies the code to something which is easier to read which again reduces errors.

BTW: Since syntax-rules have limitations, most implementation has at least one alternative macro system and it might have quasiquote unquote or even a special version of it for syntax. From R6RS syntax-case has #` and #,.