Macros 通用Lisp Lisp-1宏

Macros 通用Lisp Lisp-1宏,macros,common-lisp,lisp-2,Macros,Common Lisp,Lisp 2,我试图在common lisp中模拟scheme的单个名称空间,使用一个基于Doug Hoyte的宏,该宏扩展为lambda,其中f!符号类似于道格·霍伊特的o!还有g!函数位置的符号扩展为相同的表达式,但在每次调用的函数位置都添加了funcall。例如: (fplambda (f!z x) (f!z x x)) 将扩大到: (LAMBDA (F!Z X) (FUNCALL F!Z X X)) 宏当前看起来如下所示: (defmacro fplambda (parms &body b

我试图在common lisp中模拟scheme的单个名称空间,使用一个基于Doug Hoyte的宏,该宏扩展为lambda,其中f!符号类似于道格·霍伊特的o!还有g!函数位置的符号扩展为相同的表达式,但在每次调用的函数位置都添加了funcall。例如:

(fplambda (f!z x) (f!z x x))
将扩大到:

(LAMBDA (F!Z X) (FUNCALL F!Z X X))
宏当前看起来如下所示:

(defmacro fplambda (parms &body body)
  (let ((syms (remove-duplicates
                (remove-if-not #'f!-symbol-p
                               (flatten body)))))
    `(lambda ,parms
       (macrolet ,(mapcar
               (lambda (f)
                 `(,f (&rest parmlist)  `(funcall ,',f ',@parmlist)))
               syms))
         ,@body)))
但考虑到上述输入,它扩展到我所能看到的范围:

(LAMBDA (F!F X)
       (MACROLET ((F!F (&REST PARMLIST) `(FUNCALL ,'F!F ',@PARMLIST))))
       (F!F X X))
在macrolet定义中,F!F不应该被引用或不被引用,而parmlist应该只是不被引用。发生了什么事?
提前谢谢

你的定义基本上是正确的。你刚刚犯了两个很简单的错误。第一个是不匹配的paren。macrolet不包括输出中的主体。macrolet和主体处于相同的缩进级别

至于嵌套的反引号,唯一的错误是parmlist之前的引号。除此之外,其他一切都是正确的。F前面的逗号和引号!F实际上是正确的。从: 一个实现可以自由地将后引形式F1解释为任何形式F2,当对其求值时,将产生与上述定义所暗示的结果相同的结果。由于内部反引号尚未展开,因此它不必没有引号和反引号。表达式“,”x实际上与“x”相同

嵌套的反引号是出了名的复杂。理解它们最简单的方法可能是阅读

编辑:

关于是否可以在函数位置使用fplambda表达式的问题,答案是否定的。根据:如果复合形式的car不是符号,则该car必须是lambda表达式,在这种情况下,复合形式是lambda形式。。由于表单的car fplambda…,不是lambda表达式,因此您的代码不再是有效的公共Lisp代码

我找到了一个解决办法,但有点难看。您可以定义一个允许您编写类似[fplambda…]的内容的。。。并将其读作

((LAMBDA (&REST #:G1030) (APPLY (FPLAMBDA ...) #:G1030)) ...)
你想怎么做就怎么做。下面是允许您执行此操作的代码:

(set-macro-character #\[ 'bracket-reader)
(set-macro-character #\] (get-macro-character #\)))

(defun bracket-reader (stream char)
  "Read in a bracket."
  (declare (ignore char))
  (let ((gargs (gensym)))
    `(lambda (&rest ,gargs) 
       (apply ,(read-delimited-list #\] stream t)
              ,gargs))))

我唯一能想到的另一个解决办法是使用某种我帮不了你的代码漫游器。

你的定义基本上是正确的。你刚刚犯了两个很简单的错误。第一个是不匹配的paren。macrolet不包括输出中的主体。macrolet和主体处于相同的缩进级别

至于嵌套的反引号,唯一的错误是parmlist之前的引号。除此之外,其他一切都是正确的。F前面的逗号和引号!F实际上是正确的。从: 一个实现可以自由地将后引形式F1解释为任何形式F2,当对其求值时,将产生与上述定义所暗示的结果相同的结果。由于内部反引号尚未展开,因此它不必没有引号和反引号。表达式“,”x实际上与“x”相同

嵌套的反引号是出了名的复杂。理解它们最简单的方法可能是阅读

编辑:

关于是否可以在函数位置使用fplambda表达式的问题,答案是否定的。根据:如果复合形式的car不是符号,则该car必须是lambda表达式,在这种情况下,复合形式是lambda形式。。由于表单的car fplambda…,不是lambda表达式,因此您的代码不再是有效的公共Lisp代码

我找到了一个解决办法,但有点难看。您可以定义一个允许您编写类似[fplambda…]的内容的。。。并将其读作

((LAMBDA (&REST #:G1030) (APPLY (FPLAMBDA ...) #:G1030)) ...)
你想怎么做就怎么做。下面是允许您执行此操作的代码:

(set-macro-character #\[ 'bracket-reader)
(set-macro-character #\] (get-macro-character #\)))

(defun bracket-reader (stream char)
  "Read in a bracket."
  (declare (ignore char))
  (let ((gargs (gensym)))
    `(lambda (&rest ,gargs) 
       (apply ,(read-delimited-list #\] stream t)
              ,gargs))))

我能想到的唯一其他解决办法是使用某种代码漫游器,我在这方面帮不了你。

谢谢!我一定会读到的。我的智能参数显然没有他们想象的那么智能。这是可行的,但在使用宏时,它似乎没有在函数位置得到扩展:fplambda。。。x y。有什么办法吗?谢谢!我一定会读到的。我的智能参数显然没有他们想象的那么智能。这是可行的,但在使用宏时,它似乎没有在函数位置得到扩展:fplambda。。。x y。这有什么办法吗?