Подтвердить что ты не робот

Макросы для чтения

Есть ли способ сделать простые макросы чтения в 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

Похоже, было бы очень просто определить макрос "стенографий-лямбда" и сопоставить префикс "#" с этим.

4b9b3361

Ответ 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, принимает это.