What is the difference between regular and read macros?

I am relatively new to Clojure and cannot completely ignore the difference between reader macros and regular macros and why the difference is significant.

In what situations could you use one after the other and why?

+5
source share
3 answers

Reader macros change the syntax of the language (for example, @foo turns into (deref foo) ) in ways that ordinary macros cannot (a regular macro cannot get rid of parentheses, so you'd have to do something like (@ foo) ) . It was called a reader macro because it is implemented in the read repl pass (check the source ).

As a clojure developer, you will only create regular macros, but you will use many reader macros without counting them explicitly.

A complete list of reader macros is here: https://clojure.org/reference/reader and includes common things like @ ' and #{} .

Clojure (unlike some other lisps) does not support user-defined reader macros, but the reader has built-in extensibility through marked letters (for example, #inst or #uuid )

+5
source

TL; DR *

Macros [regular macros] expand during evaluation (E of REPL), are attached to characters, work with lisp objects and appear in the first or โ€œfunctionโ€ part of the form. Clojure, and all lisps, let you define new macros.

Reading macros during reading, before evaluating, are single characters, work with a character string before all lisp objects are emitted from the reader, and are not limited to what they are in the first or function, "part of the form. Clojure, unlike some other lisps, it is not possible to define new reader macros without editing the Clojure compiler itself.

more words:

Regular non-read macros, or simply โ€œmacros,โ€ work with lisp objects. Consider:

(and 1 b :x)

The and macro is called with two values, one value is 1 , and the other is a list consisting of the character b (and not the value b) and the keyword :x . All and macros are lisp (Clojure).

Macro-exchange occurs only when the macro is at the top of the list. (and 1 2) extends the and macro. (list and) returns the error "Unable to accept macro value"

The reader is reasponsible for turning a character string into In Clojure. The reader macro is the only character that changes the way the reader works, the part responsible for turning the text stream into lisp objects. The submit for Clojure lisp reader is in LispReader.java . As stated by Alejandro S., Clojure does not support the addition of reader macros.

Reader macros are one character. (I don't know if this is true for all lisp, but Clojure's current implementation only supports macros for reading individual characters.)

Reader macros can exist anywhere in the form. Consider (conj [] 'a) , if the macro ' was normal, the tick should become a lisp object, so the wold code will be a list of conj symbol, empty vector, symbol ' and, finally, symbol a . But now evaulation rules will require that ' evaluated on its own. Instead, the reader sees ' completes the full s-exp that follows quote , so the value returned to the evaluator is a conj list, an empty vector, and a quote list on a . quote is now the heading of the list and can change the rating rules for what it quotes.

+3
source

In short, reader macros are a low-level function. That's why there are so few of them (just @ , quiting and a little more). Having many reading rules will turn any language into a mess.

A regular macro is a tool that is widely used in Clojure. As a developer, you can write your own macros but not read them if you are not the core of the Clojure developer.

You can always use your own tagged words as a substitute for reading rules, for example #inst "2017" will provide you with an instance of Date , etc.

+1
source

Source: https://habr.com/ru/post/1268101/


All Articles