我正在尝试编写与此CL代码等效的Scheme:
(defmacro alias (new-name prev-name)
`(defmacro ,new-name (&rest args)
`(,',prev-name ,@args)))
;; Sample use:
(alias co concatenate)
我的目标是能够使用符号和函数名称的简写名称,如:
(alias sa string-append)
(sa "ok" "not ok")
要做到这一点,我已经尝试过这个,但它不起作用:
(define-syntax alias (new-name prev-name)
`(define-syntax ,new-name (#!rest args)
`(,',prev-name ,@args)))
任何帮助表示赞赏。谢谢。
您可以使用定义另一个syntax-rules
宏的syntax-rules
宏轻松完成此操作:
(define-syntax alias
(syntax-rules ()
((_ new-name prev-name)
(define-syntax new-name
(... (syntax-rules ()
((_ arg ...)
(prev-name arg ...))))))))
最棘手的是这个宏是使用...
来逃避...
的嵌套用法。
但是,这不一定是执行此操作的最佳方式。最好的方法可能取决于您的精确Scheme实现,因为Scheme不是一种语言,而是一系列语言。编写便携式Scheme通常不是很有用。
如果您的方案支持R6RS语法案例和同源语(例如,guile或chez方案),则标识符语法是实现所需内容的最直接方式:
(define-syntax new-name (identifier-syntax old-name))
从而:
(define-syntax new-display (identifier-syntax display))
(new-display "hello\n")
编辑:我看到你正在使用鸡肉。在这种情况下,您可以使用er-macro-transformer来重现您的defmacro解决方案(无论如何,这适用于鸡-4.1.0):
(define-syntax alias
(er-macro-transformer
(lambda (exp r c)
(let ([new-name (cadr exp)]
[old-name (caddr exp)])
`(define-syntax ,new-name
(ir-macro-transformer
(lambda (exp i c)
`(,',old-name ,@(cdr exp)))))))))
顺便说一句,在Common Lisp中,你可以通过设置symbol-function
来表示别名,如下所示,使别名成为真正的函数而不是宏。
CL-USER> (defun foo (name)
(format nil "Hello ~A!~%" name))
FOO
CL-USER> (setf (symbol-function 'bar)
#'foo)
#<INTERPRETED-FUNCTION FOO>
CL-USER> (bar "Bob")
"Hello Bob!
"