Lisp - Read Time Macros



A read time macro is a powerful feature that allows to modify the LISP reader default behavior. A "read time" macro is also referred as "read macro" or "reader macro". A read time macro can customize how LISP interprets the textual representation of code before it is parsed in LISP S-expressions.

Key Concepts

Let's discuss relevant key concepts before moving further to understand a read-time macro.

Read-Time

Read-Time occurs when LISP Reader acts. A LISP reader converts text into LISP objets, as s-expressions. Read Time macro works at this stage.

Compile-Time

Comple-Time occurs when LISP code is expanded into other LISP code by macros.

Run-Time

Run-Time is when the compiled/interpreted LISP code is executed.

LISP Reader

A LISP Reader is a critical component of LISP ecosystem which takes raw text as input and transforms it into LISP objects like symbols, numbers, lists etc.

Purpose of Read Macros

  • A read macro allows to extend LISP syntax. We can create our own notation or embed other languages in LISP.

  • A read macro controls how to interpret a specific character or character sequences by the LISP reader.

How a Read Macro Works?

A read macro is function associated with a specific character. When LISP reader encounter this character, the read macro is invoked. This read macro then can manipulate the input stream, read additional characters and return a LISP Object representing the parsed input.

Example - Read Macro Usage

(defun single-quote-reader (stream char)
   (declare (ignore char)) 
   (list 'quote (read stream t nil t))) 

(set-macro-character #\' #'single-quote-reader)
(print(get-macro-character #\'))

Output

When you execute the code, it returns the following result −

#<FUNCTION SINGLE-QUOTE-READER (STREAM CHAR)
  (DECLARE (SYSTEM::IN-DEFUN SINGLE-QUOTE-READER) (IGNORE CHAR))
  (BLOCK SINGLE-QUOTE-READER (LIST 'QUOTE (READ STREAM T NIL T)))>

Applications of Read Macros

  • Customize Syntax− A read macro can be used to create shorthand notation or domain specific language within LISP.

  • Embed Other Language− We can used to parse data formats like JSON, XML directly into LISP data structures.

  • Syntactic Sugar− Single quote character is a classic example, it provides syntactic sugar for quote form.

  • Read Time Evaluation− #. (Hash dot) is commonly used read macro to evaluate a LISP Form during read time. It is useful when we need to insert result of S-expressions into a code being read.

Advertisements