Макросы считывателя ракеток - PullRequest
18 голосов
/ 28 ноября 2011

Есть ли способ сделать простые макросы для чтения в Racket.Я имею в виду такое обобщение:

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

Я использовал встроенный синтаксис, чтобы прояснить, что я имею в виду.Одна из вещей, для которой я хотел бы использовать это, - репликация сокращенной лямбды clojure (#(+ 1 %) 5) ; => 6

Кажется, что было бы очень легко просто определить макрос "shorthand-lambda" и отобразить "#"префикс к этому.

Ответы [ 2 ]

17 голосов
/ 28 ноября 2011

Вот как реализовать сокращенную лямбду:

#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)
8 голосов
/ 28 ноября 2011

Посмотрите руководство в readtables и расширениях для чтения, чтобы узнать, как это сделать. Этот справочный раздел также полезен. Расширения для чтения немного сложнее, чем в вашем примере, но они очень мощные.

Для вашей конкретной проблемы SRFI-26 предоставляет аналогичный синтаксис для Схемы, и Сэм Тобин-Хохштадт написал модное приложение Макет ракетки, который реализует Scala.

...