球拍-使用宏实现let *函数 [英] Racket - implementing the let* function using macro

查看:79
本文介绍了球拍-使用宏实现let *函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 defmacro 来实现my_let *,该方法与let *相似,但是当let *扩展为一系列嵌套的let调用(在幕后)时,my_let *需要扩展进行单次通话调用,并使用 define 语句定义我得到的参数.

I need to implement my_let* using defmacro which works similarly to let*, but while let* is expanded to a series of nested let calls (behind the scenes), my_let* needs to be expanded to a single let call, and use the define statement to define the arguments i get.

使用my_let *的示例:

an example of using my_let*:

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

,此代码的返回值应为10,就像使用let *一样. 上面的代码将在 my_let * 中扩展为以下内容:

and the return value of this code should be 10. just as if it was use let*. the code above will be expanded in my_let* to the following:

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

我不熟悉使用宏,尽管我成功编写了一些宏,但是这个让我迷失了.
预先谢谢你.

I'm new to using macro, though i successfully written some macros, this one got me lost.
Thank you in advance.

推荐答案

使用syntax-parse.至少甚至不要考虑在球拍中使用defmacro.

Use syntax-parse. At the least don't even consider using defmacro in Racket.

#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必须为表达式.这些简单的注释有助于语法解析 为您提供更好的错误消息.

The name:id means that name must be an identifier and e:expr means that e must an expression. These simple annotations help syntax-parse to give you better error messages.

示例:

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

在这里DrRacket将为4个读取的颜色着色并给出消息:

Here the DrRacket will color the 4 read and give the message:

my-let*: expected identifier in: 4

这篇关于球拍-使用宏实现let *函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆