Read macros: what do you use them for? [closed]

2020-02-24 23:17发布

I'm trying to get a feel for the parts of Lisp that I haven't used very much up to now. Read macros have caught my attention at the moment. There isn't a huge amount of info about their use and it would help to see what people have done with them, both to get examples of how they work and also to see what sorts of problems can be approached with them. Following on that, are there any guidelines for knowing what constitutes good and bad use of read macros?

7条回答
对你真心纯属浪费
2楼-- · 2020-02-24 23:49

S-expressions are Lisp's syntax for Lisp data. S-expressions are read with the function READ and read macros are Lisp's built-in way to extend the reader. This means that the most direct use of read macros is to implement the pre-defined data syntax and open up possibilities to change or extend the way Lisp reads s-expressions.

Lisp comes with a pre-defined external syntax for a lot of data types: symbols, numbers, strings, arrays, characters, conses, lists, structures and more. It allows data objects to be printed and read back.

  1. Lisp lacks syntax for several other data types - prominently hash tables and CLOS objects. So the first use of read macros in user code would be to extend the reader to be able to read data structures like hash tables, parallel vectors, new number types, ... basically every data type the developer wants to have an external syntax that can be read back.

  2. Since Lisp uses s-expressions also for code, the second use of read macros is to extend the notation for Lisp programs. A typical example is the use of [ and ] to write embedded SQL code. The usual Lisp syntax looks similar, but the use of [ and] helps the SQL expressions to stand out in the code. Another example is to use read macros to provide identifiers for embedded programming languages, like Objective C constants, messages, etc.. Clozure CL uses this to represent case sensitive / case preserving identifiers and to look up their definition during read time using an index of externally available identifiers.

  3. The third use is to embed different syntaxes into Lisp syntax. An old example for that is the infix read macro, which allows embedded infix expressions. Other examples are embedded HTML or XML syntax, or embedded fragments of other programming language syntaxes.

  4. Sometimes read macros are used to implement other (related) languages that use s-expression syntaxes that are different from the pre-defined Common Lisp syntax. An example would be a reader for Scheme s-expressions - which are slightly different from Common Lisp.

查看更多
等我变得足够好
3楼-- · 2020-02-24 23:58

I have two small projects on Github that show how and why one might want to use reader macros in Common Lisp. These are SHELLSHOCK and BOXEN. As mentioned in other answers, CL-INTERPOL is an oustanding and useful example.

Whether these are good uses of reader macros is obviously subjective, but surely I must think they're useful or I wouldn't have written the code!

查看更多
我命由我不由天
4楼-- · 2020-02-25 00:07

Reader macros are used when there is a syntax for literal objects that you may want to have. The single problem with them is the flat namespace for possible syntaces (however, there are ways to work around that). There are not so many usages of reader macros. Some examples that come to my mind are:

查看更多
孤傲高冷的网名
5楼-- · 2020-02-25 00:08

Although i use a lot of macros, i've never found the need to use read-macros, apart from casual experimentation. If it helps, on "Let Over Lambda" you will find an extensive discussion about them: http://letoverlambda.com/index.cl/toc

查看更多
萌系小妹纸
6楼-- · 2020-02-25 00:09

I actually tend to avoid them for my ordinary Lisp code; recently, I even found myself rejecting a third-party library because of its use of reader-macros. This is mostly due to the fact, that unlike symbols, there is only a single "namespace" for reader-macros. And I often seem to disagree with authors of libraries about their taste when choosing an appropriate dispatch character.

However, I used customized non-standard readtables + read successfully for simple parsing tasks. The most complex parser thing I implemented so far using a custom readtable was a HTML template engine (yet another, sorry) with a syntax similar to JSP/ASP, but using Common Lisp as the actual template language, so you can have things like

<% (for (title . link) in breadcrumb do %><a href="<%= link %>"><%= title %></a><% ) %>

(wasn't done with readtable hacks alone, though, code had to undergo a preprocessing stage).

查看更多
登录 后发表回答