球拍阅读器宏

时间:2011-11-27 23:04:35

标签: macros lisp scheme racket

有没有办法在Racket中制作简单的阅读器宏。我的意思是像这样的概括:

(define-reader-syntax "'" quote)
; finds expressions that start with "'" and wraps them in `(quote ...)`
'(foo) ; => (quote (foo))
'foo ; => (quote foo)

我使用内置语法来明确我的意思。我想用它做的一件事是复制clojure的速记lambda (#(+ 1 %) 5) ; => 6

似乎很容易定义一个“shorthand-lambda”宏并将“#”前缀映射到该宏。

2 个答案:

答案 0 :(得分:17)

以下是如何实现简写lambda:

#lang racket

(define rt (make-readtable #f #\# 'non-terminating-macro
                           (λ (c in . _)
                             (define body (read in))
                             `(lambda (%) ,body))))
(parameterize ([current-readtable rt]
               [current-namespace (make-base-namespace)])
  (eval (read (open-input-string "(#(+ 1 %) 5)")))) ;; => 6

以下是如何实施更简单的示例,使&等同于'

(define rt2 (make-readtable #f #\& #\' #f))

(parameterize ([current-readtable rt2]
               [current-namespace (make-base-namespace)])
  (eval (read (open-input-string "&(3 4 5)")))) ;; => '(3 4 5)

答案 1 :(得分:8)

查看readtablesreader extensions上的指南条目,了解如何执行此操作。这个reference section也很有用。可读扩展比你的例子复杂一点,但它们非常强大。

针对您的具体问题,SRFI-26为Scheme提供了类似的语法,Sam Tobin-Hochstadt写了一个fancy app Racket宏来实现Scala对此的看法。