【问题标题】:Racket macro to stringify all but s-expressionsRacket 宏用于字符串化除 s 表达式之外的所有表达式
【发布时间】:2020-07-14 04:24:45
【问题描述】:

我正在尝试弄清楚如何创建一个球拍宏,它将简单地将所有内容转换为字符串,除了 s-expressions 它将不理会。​​p>

我已经弄清楚如何将所有内容字符串化

  #+begin_src racket
    (define-syntax (stringify-all stx)
      (syntax-case stx ()
        [(_ args ...)
         #'(begin
             (~s 'args)
             ...)]))

    (stringify-all one 2 (add1 2))
  #+end_src

  #+RESULTS:
  : "one"
  : "2"
  : "(add1 2)"

但不知道如何测试某事物是否为 s 表达式。

我该怎么做?

【问题讨论】:

    标签: macros racket


    【解决方案1】:

    “s-expression”是语法列表/对,因此您可以对()(a . b) 进行模式匹配,如下所示:

    #lang racket
    
    (require (for-syntax (only-in racket/format ~s)))
    
    (define-for-syntax (compute stx)
      (syntax-case stx ()
        [() #'null]
        [(a . b) #`(cons #,(compute #'a) #,(compute #'b))]
        [_ (~s (syntax-e stx))]))
    
    (define-syntax (stringify-all stx)
      (syntax-case stx ()
        [(_ args ...)
         #`(begin #,@(map compute (syntax->list #'(args ...))))]))
    
    (stringify-all one 2 (add1 2))
    
    ;; "one"
    ;; "2"
    ;; '("add1" "2")
    

    【讨论】:

    • 啊,谢谢!我只想评估嵌套的 s 表达式,但我想我可以弄清楚这一点。太好了,谢谢。
    【解决方案2】:

    如果我们使用atom? 过程的通常定义作为参考:

    (defne (atom? exp)
      (and (not (null? exp))
           (not (pair? exp))))
    

    那么我们可以定义一个 s-expression 谓词为:

    (define (s-exp? exp)
      (or (null? exp)
          (pair? exp)))
    

    当然,您需要将其递归地应用于 s 表达式的每个元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      相关资源
      最近更新 更多