lambdas 在用户定义的宏中抛出错误

lambdas throwing error inside a user defined macro

我定义了下面的宏...

(define-syntax >> ;;compose
  (syntax-rules ()
    [(>> f1 [args ...]) 
     (lambda (x) (f1 args ... x))]
    [(>> f1 [args1 ...] f2 [args2 ...] rf ...) 
     (>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]
    [(>> f1 [args1 ...] f2  rf ...) 
     (>> (lambda (x) (f2 (f1 args1 ... x)) ) rf ...)]
    [(>> f1 f2 [args2 ...] rf ...) 
     (>> (lambda (x) (f2 args2 ... (f1 x)) ) rf ...)]
    [(>> f1 )           
     (lambda (x) (f1 x))]
    [(>> f1 f2 rf ...) 
     (>> (lambda (x) (f2 (f1 x))) rf ...)]))

帮助我以这种方式编写函数:

(define composed-function (>> (lambda (x) (+ x 1))  (lambda (x) (+ x 1))))

问题是,命名函数一切正常,但是当我使用上面示例中描述的 lambda 时,我收到类似“lambda:lambda 中的错误语法”的错误,知道为什么会这样发生了什么?

问题是您的宏陷入了错误的模式。你认为应该应用这个:

[(>> f1 f2 rf ...) 
 (>> (lambda (x) (f2 (f1 x))) rf ...)]))

但实际上它实际上可以匹配这个模式:

[(>> f1 [args ...]) 
 (lambda (x) (f1 args ... x))]

f1 匹配 (lambda (x) (+ x 1))(args ...) 匹配 (lambda (x) x)。扩展为:

 (lambda (x) ((lambda (x) (+ x 1)) lambda (x) x x))

这是胡言乱语。您可能最好使用需要在每个参数周围加上括号的模式:

(define-syntax >> ;;compose
  (syntax-rules ()
    [(>> (f1 args ...)) 
     (lambda (x) (f1 args ... x))]
    [(>> (f1 args1 ...) (f2 args2 ...) rf ...) 
     (>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]))

这也减少了您需要的参数数量。要使用它,请执行:

(define composed-function (>> ((lambda (x) (+ x 1)))  ((lambda (x) (+ x 1)))))

当然,第三种选择就是使用racket/base中的compose。不可否认,它不允许您为每个函数传递固定参数,但您仍然可以通过 eta-expansion 获得它。

要使用 compose,您的示例将如下所示:

(define composed-function (compose (lambda (x) (+ x 1)) (lambda (x) (+ x 1))))

(请注意,尽管函数与您的示例相反。)