Макросы для чтения
Есть ли способ сделать простые макросы чтения в 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
Похоже, было бы очень просто определить макрос "стенографий-лямбда" и сопоставить префикс "#" с этим.
Ответы
Ответ 1
Здесь, как реализовать сокращенную лямбду:
#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)
Ответ 2
Посмотрите на запись руководства readtables и расширения для читателей, чтобы узнать, как это сделать. Этот справочный раздел полезен. Расширения readtable немного сложнее, чем ваш пример, но они очень мощные.
Для вашей конкретной проблемы SRFI-26 предоставляет аналогичный синтаксис для Схемы, а Сэм Тобин-Хохштадт написал a причудливое приложение Макрос для ракеты, реализующий Scala, принимает это.