lambda - LISP 宏失败,崩溃史莱姆

标签 lambda macros lisp common-lisp slime

我在 emacs 中使用 common lisp 和 slime 并试图定义一个简单的宏。但是,当我运行宏时,emacs 粘液缓冲区变得无响应,我的计算机很快变得无法使用。即使在退出 emacs 后,我也会在 bash 提示符下收到有关无法分配内存的错误消息。

我想用我的宏来写这两个函数

(defun triad (foo scale)
  "Generates a triad on scale-step FOO of scale SCALE"
  (list (%part (- foo 1) scale)
    (%part (+ foo 1) scale)
    (%part (+ foo 3) scale)))

(defun quad (foo scale)
  "Generates a quad on scale step FOO of scale SCALE"
  (list (%part (- foo 1) scale)
    (%part (+ foo 1) scale)
    (%part (+ foo 3) scale)
    (%part (+ foo 5) scale)))

使用像这样的语法

(defchord 'mtriad '(1 3 5))
(defchord 'mquad  '(1 3 5 7))

我决定使用 mapcar 和 lambda 函数来生成我想要的输出。在解释器中,这可以生成我想要的:

CL-USER> (mapcar (lambda (x) `(%part (+ ,x 2) scale)) '(1 3 5))
((%PART (+ 1 2) SCALE) (%PART (+ 3 2) SCALE) (%PART (+ 5 2) SCALE))

但是,当我尝试将它放入宏中以生成 defun 调用时,它会崩溃并在我调用它时立即破坏我的内存:

(defmacro defchord (name steps)
  `(defun ,name (foo scale)
     (quote ,(mapcar (lambda (x) `(%part (+ ,x 2) scale)) steps))))

我希望这是一个简单的菜鸟错误!

最佳答案

您在引号内引用并且您在引用您的参数,就好像它们是函数一样。如果这是可以接受的,你可以把它变成一个函数:

(defun defchord (name steps)
  (setf (symbol-function name)
        (lambda (foo scale) 
          (mapcar (lambda (step) 
                    (%part (+ foo step) scale))
                  steps)))
  name)

;; test
(defchord 'mtriad '(1 3 5)) ;==> mtriad
(defun %part (x y) (cons x y))
(mtriad 2 10) ; ==> ((3 . 10) (5 . 10) (7 . 10))

关于lambda - LISP 宏失败,崩溃史莱姆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29002506/

相关文章:

c++ - 空函数是否会被不纯的表达式优化?

c - 为什么对单语句主体使用 do {...} while(0) 宏?

macros - 在 rust macro_rules 中捕获生命周期

macros - 不带 eval 取消引用

amazon-web-services - 使用 API 网关和无服务器框架在 AWS Lambda 上超过了速率

python - 为什么我的reduce lambda 表达式没有按预期工作?

list - LISP中列表元素的递归处理

lisp - ACT-r : assigning a chunk as buffer slot value in a production rule

amazon-web-services - AWS Lambda - 在认知用户池中搜索用户

使用 lambda 表达式返回结果的 Java 方法引用