Macros 球拍阅读器宏

Macros 球拍阅读器宏,macros,lisp,scheme,racket,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

有没有办法在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


定义“速记lambda”宏并将“#”前缀映射到该宏似乎非常容易。

查看上的指南条目,了解如何执行此操作。这也很有用。可读扩展比您的示例要复杂一些,但它们非常强大


针对您的具体问题,为Scheme提供了类似的语法,Sam Tobin Hochstadt编写了一个Racket宏来实现Scala对此的理解。

以下是如何实现速记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)

在第一个示例中的
(λ(c In.
)中,什么是
c
?触发读卡器宏的字符,在本例中始终是
\\\\
。请参阅的文档。您可能有兴趣查看或的代码,这两个代码都定义了简写lambda表达式的读卡器扩展的完整实现。