macros - Racket - 使用宏实现 let* 函数

标签 macros scheme lisp racket let

我需要使用 defmacro 实现 my_let*,其工作方式与 let* 类似,但是当 let* 扩展为一系列嵌套的 let 调用(在幕后)时,my_let* 需要扩展到单个let调用,并使用define语句来定义我得到的参数。

使用 my_let* 的示例:

 (my_let* ((a 2)
 (b 3)
 (c (+ a b)))
 (+ a b c))

这段代码的返回值应该是10。就像使用let*一样。 上面的代码将在 my_let* 中扩展为以下内容:

(let ()
 (define a 2)
 (define b 3)
 (define c (+ a b))
 (+ a b c))

我是使用宏的新手,虽然我成功编写了一些宏,但这个让我迷失了。
预先感谢您。

最佳答案

使用语法解析。至少不要考虑在 Racket 中使用 defmacro

#lang racket

(require (for-syntax syntax/parse))

(define-syntax (my-let* stx)
  (syntax-parse stx
    [(_my-let* ([name:id e:expr] ...) body ...)
     #'(let ()
         (define name e) ...
         body ...)]))

name:id 表示 name 必须是标识符,e:expr 表示 e 必须是一个表达式。这些简单的注释有助于语法分析 为您提供更好的错误消息。

示例:

(my-let* ((4 2)
          (b 3)
          (c (+ a b)))
         (+ a b c))

这里 DrRacket 将为 4 个读数着色并给出消息:

my-let*: expected identifier in: 4

关于macros - Racket - 使用宏实现 let* 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43985964/

相关文章:

macros - Common Lisp 宏参数不匹配,尽管 &rest/&body

exception - 如何在 R6RS Scheme 中抛出和处理异常

LISP 复制函数

基于for循环增量的函数指针的C宏扩展

ios - 如何使用 Swift 从 Xcode 中的代码访问预处理器宏?

scheme - Racket 如何处理(定义(f(x y))主体)?

list - LISP:按升序排列列表项

lisp - 了解函数中的数字数据类型

Clojure - 宏扩展如何在 "some"函数内部工作

scheme - Scheme中的 'when'有什么用?