【问题标题】:lambdas throwing error inside a user defined macrolambdas 在用户定义的宏中抛出错误
【发布时间】:2021-01-14 21:52:38
【问题描述】:

我定义了以下宏...

(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))))

问题是,命名函数一切正常,但是当我使用上面示例中描述的 lambdas 时,我收到“lambda: bad syntax in lambda”这样的错误,知道为什么会发生这种情况吗?

【问题讨论】:

    标签: lambda macros racket


    【解决方案1】:

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

    [(>> 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/basecompose。诚然,它不允许您为每个函数传递固定参数,但您仍然可以通过 eta-expansion 获得。

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

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

    (请注意,这些功能与您的示例相反。)

    【讨论】:

    • 感谢您的回答,我感觉是这样的,我知道这是另一个问题,但您似乎知道您在说什么,所以,有没有办法检查更精确的模式类型?还是一种将语法分派到最终返回语法对象的表达式主体内的另一个模式匹配的方法?
    • 是的。 “派发”到另一个模式的最简单方法是在模板中再次使用宏。查找有关语法“类型”的信息的最简单方法是使用syntax/parse 库。不幸的是,评论中没有足够的空间来回顾示例,但值得为此提出一个新问题。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    相关资源
    最近更新 更多