Quasiquotation

Description

A discussion about quasiquotation on Hacker News with a link from Jesse to some reader macros for MIM was enough motivation for me to write some quasiquotation macros for Zilf. Rather than being done entirely through reader macros (the Lisp tradition), I implemented it mostly through eval macros (the Scheme tradition).

This takes a small change to the parser: backtick and tilde respectively give QUASIQUOTE and UNQUOTE forms, just like how quote gives QUOTE.

The quasiquoter uses the algorithm from Bawden, "Quasiquotation in Lisp," but adapted for MDL. Since MDL already has SEGMENTs, the algorithm is somewhat simpler since there is no UNQUOTE-SPLICE. The quasiquoter is able to have UNQUOTE forms anywhere within structures with a PRIMTYPE of LIST or VECTOR. Some TYPEs are self-quoting, like atoms, numbers, and strings. Also, quasiquotation can be nested arbitrarily deep.

There are some examples at the end of quasiquote.mud, where I translated macros like IF-PLURAL and VERB? to use quasiquotation.

My implementation is only lightly tested, but perhaps it's enough to evaluate whether or not Zilf should have quasiquotation.

Activity

Show:
Jesse McGrew
January 20, 2021, 8:57 AM

Fixed in ea31ec9aaa9c093a01f17eb624d8611fd9bbbb7c

Jesse McGrew
January 17, 2021, 8:44 AM

Jesse McGrew mentioned this issue in a commit of zilf / zilf:

Added QQ package for quasiquoting.

Kyle Miller
April 24, 2019, 6:27 PM

I guess I should mention a difference between a reader-macro-based quasiquoter and an eval-macro-based one, which is what happens when you QUOTE a quasiquoted expression: either it is a quoted expansion of the quasiquotation, or it is the quoted quasiquotation itself. So long as that expression finds its way into some code that will be macro expanded, they are (practically) indistinguishable.

Reasons to have a reader-macro-based quasiquoter: this is traditional for lisps, code walkers don't need to worry about new special forms like QUASIQUOTE, and it is more efficient in interpreters that need to expand macros in eval repeatedly.

Reasons to have an eval-macro-based quasiquoter: Scheme and modern lisps (like SBCL) do so, the expression prints the same as it was read in, macros can do things with QUASIQUOTE expressions themselves if they wish to, the algorithm comes from a technical paper, and (very minor) it could be added before Zilf gets a full reader macro facility.

It shouldn't be too hard to rewrite it to be entirely reader macros (in case that were wanted), but it is not exactly clear to me how to modify the algorithm in a way that guarantees nested quasiquotations and unquotations (with splicing) work properly. It's possible that it might just be a matter of removing the QQ-QUASIQUOTE? clauses from each COND. (The reader macros would be "on '`', read in an expression and call QQ-EXPAND on it" and "on '~', read in an expression and wrap it in the UNQUOTE form.")

Jesse McGrew
April 24, 2019, 10:45 AM

Cool, thanks! It's definitely more readable than the templating macros I have now.

Fixed

Assignee

Jesse McGrew

Reporter

Kyle Miller

Components