增量宏定义是否可行?

Dav*_*rak 6 lisp macros scheme

我经常发现以下类型的增量定义很有用:

(define (foo) (display "bar"))
(foo)
;prints bar
(define foo (let ((bar foo))
              (lambda ()
                (display "foo")
                (bar))))

(foo)
;prints foobar
Run Code Online (Sandbox Code Playgroud)

如何使用宏预先形成此类增量定义?我无法让let-syntax提供相同的功能.

目前我使用plt方案,但也希望在不同的lisp实现中看到答案.

编辑:

天真的我想做以下事情:

(define-syntax foo
  (syntax-rules ()
    ((_) (display "bar"))))

(define-syntax foo
  (let-syntax ((old-foo (syntax-rules () ((_) (foo)))))
    (syntax-rules ()
      ((_) (begin
             (display "foo")
             (old-foo))))))
Run Code Online (Sandbox Code Playgroud)

将朴素宏翻译为工作plt方案宏:

(require-for-syntax scheme/base) 
(define-syntax foo
  (syntax-rules ()
    [(foo) (display "bar")]))
(define-syntax foo
  (let ([old (syntax-local-value #'foo)])
    (lambda (stx)
      #`(begin #,((syntax-rules ()
               [(_) (begin (display "foo"))]) stx)
             #,(old #'(_))))))
(foo)
Run Code Online (Sandbox Code Playgroud)

如果我错过了一个更好的方法让我知道.

Eli*_*lay 2

FWIW(这绝对不是很多,因为这几乎是用脚进行目标练习的练习),以下是您在 PLT 方案中仅使用卫生syntax-rules宏执行此操作的方法:

(define-syntax foo
  (syntax-rules ()
    [(foo x) (list 'x '= x)]))
(define-syntax foo
  (let ([old (syntax-local-value #'foo)])
    (compose (syntax-rules ()
               [(_ x ...) (list 'begin x ... 'end)])
             old)))
(printf ">>> ~s\n" (foo (+ 1 2)))
Run Code Online (Sandbox Code Playgroud)

这不能在模块内部工作,只能在 REPL 上工作——这是一件好事。也可以在模块中执行类似的操作,但如果您要这样做,您也可以使用过程宏(又名syntax-case宏),并使用在语法级别绑定的标识符和“set!”-ing其价值在于扩展它。仍然不是一个好主意,仍然会导致眼睛流血,但有些人喜欢伤害自己......

(哦,顺便说一句 - 即使这样做仍然与所讨论的宏是否卫生完全无关。)