Поддержка Racket R6RS: syntax-case

Эта простая программа R6RS:

#!r6rs
(import (rnrs base)
        (rnrs syntax-case)
        (rnrs io simple))

(define-syntax stest
  (lambda (x)
    (syntax-case x ()
      ((_ z) #'(z 0)))))

(stest display)

работает с Chez, Guile и Ypsilon, но не с Racket. Это дает мне это:

test.scm: 7: 3: lambda: несвязанный идентификатор в среде преобразователя;
также, преобразователь синтаксиса #% app не привязан

У меня вопрос, он сломан для R6RS или надо что-то еще делать? Тестирую с версией 6.12.


person Watcom    schedule 12.06.2018    source источник


Ответы (1)


В этом случае реализация Racket R 6 RS не является несовместимой. На самом деле, во всяком случае, он более точно подчиняется стандарту: ваша программа в том виде, в котором она написана, не заботится о фазах импорта. Проблема в том, что define-syntax оценивает свою правую часть во время развертывания, как указано в разделе 11.2.2 Определения синтаксиса:

Привязывает ‹keyword› к значению ‹expression›, которое должно оцениваться во время расширения макроса трансформатору.

В отличие от других стандартов Scheme, R 6 RS заботится о различении фаз, поскольку он разрешает произвольное программирование во время компиляции (в то время как другие стандарты Scheme этого не делают). Поэтому раздел 7.1 Форма библиотеки указывает, как импортировать библиотеки на определенных этапах:

Каждая «спецификация импорта» определяет набор привязок, которые необходимо импортировать в библиотеку, уровни, на которых они должны быть доступны, и локальные имена, по которым они должны быть известны. ‹Спецификация импорта› должна быть одной из следующих:

<import set>
(for <import set> <import level> ...)

‹Уровень импорта› может быть одним из следующих:

run
expand
(meta <level>)

где ‹level› представляет собой точный целочисленный объект.

Следовательно, вам нужно импортировать (rnrs base) на фазах run и expand, и вам нужно импортировать (rnrs syntax-case) на фазе расширения. Сделать это можно с помощью следующей программы:

#!r6rs
(import (for (rnrs base) run expand)
        (for (rnrs syntax-case) expand)
        (rnrs io simple))

(define-syntax stest
  (lambda (x)
    (syntax-case x ()
      ((_ z) #'(z 0)))))

(stest display)

Эта программа работает в Racket. Я не проверял, работает ли он также с другими реализациями схемы, которые вы указали, но должен ли они соответствовать стандартам.

person Alexis King    schedule 12.06.2018
comment
Также работает с другими реализациями. Отлично, спасибо! - person Watcom; 12.06.2018