common lisp:宏如何使用以编程方式生成的名称定义其他方法/宏?

2024-03-04

我意识到我的代码的某个部分由看起来相似的方法组组成(就像我有多个三重奏:一个由程序员的其他两个函数调用的辅助函数)。我正在尝试编写一个宏来为我定义这三个函数,以便我所需要做的就是调用该宏。但我的尝试导致 defun 和函数调用将引用字符串而不是生成的名称作为新符号。我究竟做错了什么?

示例(错误代码)

(defmacro def-trio (base-name)
  (let 
    ((helper-name (format nil "helper-~a" base-name))
     (method-1 (format nil "~a-1" base-name))
     (method-2 (format nil "~a-2" base-name)))
    `(progn 
          (defun ,helper-name () 'helper-called)
          (defun ,method-1 () (,helper-name) '1-called)
          (defun ,method-2 () (,helper-name) '2-called))))

现在发生以下情况:

(def-trio my-trio)

==>

(PROGN (DEFUN "helper-MY-TRIO" () 'HELPER-CALLED)
       (DEFUN "MY-TRIO-1" () ("helper-MY-TRIO") '1-CALLED)
       (DEFUN "MY-TRIO-2" () ("helper-MY-TRIO") '2-CALLED))

另外,在我学习如何让它工作之后,如果我让这个宏定义其他宏而不是其他函数,是否会有任何额外的问题?我读如何在 Common Lisp 中编写宏定义宏 https://stackoverflow.com/questions/3121145/how-do-i-write-a-macro-defining-macro-in-common-lisp但我认为我的问题有点不同,因为我问的是以编程方式生成的符号/名称。不过,我愿意接受纠正:) 谢谢!


尝试这个:



(defmacro def-trio (base-name)                                         ; changes:
  (let*                                                                ; 3.
    ((package (symbol-package base-name))                              ; 2.
     (helper-name (intern (format nil "HELPER-~a" base-name) package)) ; 1. 4.
     (method-1 (intern (format nil "~a-1" base-name) package))         ; 1.
     (method-2 (intern (format nil "~a-2" base-name) package)) )       ; 1.
    `(progn 
          (defun ,helper-name () 'helper-called)
          (defun ,method-1 () (,helper-name) '1-called)
          (defun ,method-2 () (,helper-name) '2-called) )))
  

对您的原始定义进行了以下更改 - 第一个更改是关键的更改:

  1. 使用以下命令将每个计算符号名称插入到与基本名称相同的包中(intern ... package).
  2. 引入了变量package与所提供的包装绑定在一起base-name symbol.
  3. Changed let to let*允许新引入的变量package在后续变量中引用。
  4. 将辅助方法的前缀更改为大写,以匹配普通 Lisp 符号的约定。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

common lisp:宏如何使用以编程方式生成的名称定义其他方法/宏? 的相关文章

  • 人们可以放心地忽略宏和内置宏之间的区别吗?

    我从 Clojure 开始 这也是我的第一个 lisp 显然有很多东西需要吸收 为了减轻认知负担 我尝试找到我可以安全地忽略的部分 目前 人们能否安全地以相同的方式处理带有宏的表单和带有内置函数的表单 或者是否会出现以后出现的陷阱 换句话说
  • 什么是“3D语法”?

    在编写 Racket 宏的上下文中 3D 语法 是什么意思 这句话我听过好几次了 包含一次对宏的引用I正在写作 但那是不久前的事了 我修复了它 现在我不记得我最初做错了什么 另外 是 3D 语法吗always坏的 或者是像eval 如果你认
  • Rust 中带有纯宏的函数组合链

    我读了 如何在 Rust 中编写函数 https stackoverflow com questions 45786955 how to compose functions in rust Rust 中的函数组合链 https stacko
  • AIRFLOW:在 jinja 模板中为 {{ds}} 使用 .replace() 或relativedelta()

    我的目标是根据气流宏变量 ds 返回上个月的第一天并使用它 例如在 Hive 操作符中 例如 对于 ds 2020 05 09 我预计返回 2020 04 01 我找到并尝试的解决方案是 SET hivevar LAST MONTH ds
  • GCC/CLANG 与 MSVC 的预处理器之间有何差异?

    以下预处理器宏 通常的嫌疑人 测试空参数列表并计算参数数量 在 gcc clang 上运行时没有警告 但在 Microsoft VisualC 上失败 IS EMPTY returns nothing if the parameter li
  • 宏扩展忽略了 MSVC 中的一些标记

    我在 msvc 编译器中遇到宏扩展问题 我希望将以下代码扩展为F x 它在 gcc 和 clang 上执行 但 msvc 将其扩展为F忽略x令牌 这里发生了什么 define S s s define F define M S S F x
  • Scheme/Lisp 嵌套循环和递归

    我正在尝试解决方案中的一个问题 该问题要求我使用嵌套循环或嵌套递归 例如我有两个列表 我必须检查它们的笛卡尔积的条件 解决这些类型问题的最佳方法是什么 有关如何简化这些类型的函数的任何指示吗 I ll elaborate a bit sin
  • 如何用其他树替换子树?

    在 Scala 宏中 我想做这样的事情 我有一个Tree 可能很大 现在我想找到这棵树的一个具有某种具体形式的子树 例如Apply 现在我想创建一棵新树 它是原始树的副本 但找到的子树被其他树替换 例如 通过类似的方法 我可以用调用某些其他
  • 宏、Clojure 与 Common Lisp

    我和我的一些朋友正在开发一个新平台 我们想用 lisp 构建它 主要吸引力是宏 我们都使用 Common Lisp 但我想探索 Clojure 的选择 当我提出这一点时 其中一位说宏观体系 较弱 我想知道这是否属实 以及在哪些领域 就您可以
  • 宏中 do { } while(0) 与 ({ }) 的优点?

    Stack Overflow 上有很多关于使用的问题do while 0 在宏中 但这有点不同 我明白为什么do while 0 用于将多行代码包装在宏扩展中 但我经常看到另一种形式 The form 的优点是它是一个表达式并且可以有 返回
  • Common Lisp——为什么这个符号不是外部的?

    我正在尝试在 ASDF 中运行测试 如下所示 foo asd defsystem foo tests depends on foo fiveam components module tests components file main pe
  • ^ 和 _ 宏之后出现的数字(是:LaTeX 限制?)

    我在 LaTeX 中遇到了一个恼人的问题 我有一个大约 1000 行的 tex 文件 我已经有了一些数字 但是当我尝试添加另一个数字时 它会吐出 Undefined control sequence
  • Lisp 中的 (定义 (平均 ....))

    我只是在玩scheme lisp 并正在考虑如何纠正我自己的定义average 我不确定如何做一些我认为需要的事情 定义一个接受任意数量参数的过程 计算这些参数 将参数列表传递给 以将它们加在一起 有人有定义的例子吗average 我似乎对
  • 为什么 LISP 中符号名称中的连字符是约定俗成的?

    这个推荐的理由是什么 为什么不与使用下划线的其他编程语言保持一致 我认为 LISP 使用连字符有两个原因 历史 和 因为你可以 History LISP 是一种古老的语言 在早期输入下划线可能会很困难 例如 我用于 LISP 的第一个终端是
  • 解决斐波那契数列的 Lisp 方法

    我想尝试学习 Lisp 但很快就放弃了 我想我会再试一次 我正在看 求 400 万以下所有偶数斐波那契数的总和 我写了下面的代码 它可以工作 但是很丑陋 其中最主要的是它太慢了 因为它一直在进行简单的递归 当我用 Python 编写这个程序
  • Xcode 中定义的宏 CURRENT_PROJECT_VERSION 在哪里?

    这个帖子如何在 xcode 8 中设置 CURRENT PROJECT VERSION https stackoverflow com questions 39673280 how to set current project versio
  • F# 类型提供程序与 Lisp 宏

    我一直在阅读有关 F 3 0 类型提供程序的内容 例如here http msdn microsoft com en us library hh156509 aspx 并且它们似乎基于一种编译时代码生成 在这方面我想知道它们与 Lisp 宏
  • 我的钳位宏有问题

    我的钳位宏有问题 当我的值超过 10 并且我的最高值超过 17 时 它会停止工作 任何想法 define CLAMP value low high value lt low low value gt high high value 我建议使
  • 宏未产生所需的结果

    我是 C 新手 之前来自 Python 我对这部分代码感到困惑 include
  • 在 C 语言中替换宏内的宏

    我正在尝试使代码部分可重用 我下面的评论片段没有达到我想要的效果 define NAME ABC define LOG SIZE NAME LEN 我想LOG SIZE决心ABC LEN 我尝试过使用 但没能让它发挥作用 LOG SIZE在

随机推荐