代码之家  ›  专栏  ›  技术社区  ›  Pinochle

阅读宏:你用它们做什么?[关闭]

  •  17
  • Pinochle  · 技术社区  · 15 年前

    我试着去感受一下lisp的一些部分,这些部分到目前为止我还没有用过。读宏现在引起了我的注意。没有关于他们的大量信息 使用 这将有助于了解人们对他们做了什么,既有助于了解他们是如何工作的,也有助于了解他们能解决什么样的问题。在此基础上,有什么指导方针可以帮助我们了解什么是read宏的好的和坏的使用?

    7 回复  |  直到 8 年前
        1
  •  19
  •   Rainer Joswig Michael Fox    15 年前

    s表达式是lisp的lisp数据语法。使用函数read读取s表达式,而read宏是lisp扩展读卡器的内置方式。这意味着read宏最直接的用途是实现预定义的数据语法,并打开改变或扩展lisp读取s表达式方式的可能性。

    lisp为许多数据类型提供了预定义的外部语法:符号、数字、字符串、数组、字符、conse、列表、结构等等。它允许打印和读取数据对象。

    1. lisp缺少其他几种数据类型的语法,特别是哈希表和clos对象。因此,在用户代码中使用read宏的第一个目的是扩展读取器,使其能够读取数据结构,如哈希表、并行向量、新的数字类型等等。基本上,开发人员希望每个数据类型都有一个可以读回的外部语法。

    2. 由于lisp也对代码使用s表达式,所以read宏的第二个用途是扩展lisp程序的符号。一个典型的例子是使用[和]编写嵌入式sql代码。通常的lisp语法看起来很相似,但是使用[和]有助于sql表达式在代码中脱颖而出。另一个例子是使用read宏为嵌入式编程语言提供标识符,如目标c常量、消息等。clozure cl使用它来表示区分大小写/保留大小写的标识符,并在读取期间使用外部可用标识符的索引来查找它们的定义。

    3. 第三个用途是在lisp语法中嵌入不同的语法。一个旧的例子是中缀读取宏,它允许嵌入中缀表达式。其他示例包括嵌入的HTML或XML语法,或其他编程语言语法的嵌入片段。

    4. 有时,read宏用于实现其他(相关)语言,这些语言使用不同于预定义的通用lisp语法的s表达式语法。一个例子是scheme s s-expressions的阅读器,它与普通的lisp略有不同。

        2
  •  7
  •   dmitry_vk    15 年前

    读卡器宏用于可能需要的文本对象语法。它们唯一的问题是可能的语法的平面名称空间(但是,有办法解决这个问题)。 读卡器宏的用法并不多。我想到的一些例子是:

        3
  •  4
  •   Dirk    15 年前

    实际上,我倾向于在普通的lisp代码中避免使用它们;最近,我甚至发现自己拒绝使用第三方库,因为它使用了reader宏。这主要是因为,与符号不同,读取器宏只有一个“名称空间”。在选择合适的调度字符时,我似乎常常不同意图书馆作者的观点。

    但是,我使用了定制的非标准读表+ 阅读 成功执行简单的分析任务。到目前为止,我使用自定义 可读取的 是一个html模板引擎(另一个,抱歉),语法类似于jsp/asp,但使用的是common lisp作为实际的模板语言,因此您可以

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

    (这并不是仅仅通过readtable黑客完成的,尽管,代码必须经过预处理阶段)。

        4
  •  2
  •   AticusFinch    15 年前

    虽然我使用了很多宏,但除了一些偶然的实验之外,我从未发现需要使用read宏。如果有帮助,在“Let over Lambda”中,您会找到关于它们的广泛讨论: http://letoverlambda.com/index.cl/toc

        5
  •  2
  •   jfm3    13 年前

    我在github上有两个小项目,展示了在通用lisp中使用读卡器宏的方式和原因。这些是 SHELLSHOCK BOXEN . 如其他答案所述, CL-INTERPOL 是一个站得住脚的有用的例子。

    这些是不是 好的 读卡器宏的使用显然是主观的,但我肯定认为它们很有用,否则我就不会编写代码!

        6
  •  1
  •   Pillsy    15 年前

    一个特别常见和有用的替代语法,您可以嵌入读宏是正则表达式语法。实现它一点也不难,因为它只是读取一个具有不同转义规则的字符串,但是如果您经常使用regex,它确实会有回报。这个 CL-INTERPOL dmitry vk提到的库提供了此功能,以及 许多 其他特征。

    推荐文章