用CL编写的这个别名代码的Scheme等价物是什么?

问题描述 投票:1回答:3

我正在尝试编写与此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)))

任何帮助表示赞赏。谢谢。

scheme common-lisp
3个回答
2
投票

您可以使用定义另一个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通常不是很有用。


2
投票

如果您的方案支持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)))))))))

1
投票

顺便说一句,在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!
"
© www.soinside.com 2019 - 2024. All rights reserved.