Изпълнявам Chez Scheme 9.5 и се опитвам да дефинирам синтактичен трансформатор в библиотека. Ето един пример:
(library (forlib)
(export for)
(import (rnrs (6)))
(define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
Записвам това във файл forlib.ss
и стартирам chez
от същата директория. Тогава в REPL получавам това:
> (import (forlib))
> (for x in '(1 2 3) (display x))
Exception: invalid syntax (for x in (quote (1 2 3)) (display x))
Type (debug) to enter the debugger.
Ако променя дефиницията на синтаксиса на
(define-syntax for
(syntax-rules ()
[(for x lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
(без ключовата дума in
), всичко работи:
> (import (forlib))
> (for x '(1 2 3) (display x))
123
> _
Обратно към старата дефиниция с ключовата дума in
. Ако поставя тестовия код в тестов файл:
;;; test-for.ss
(import (rnrs (6))
(forlib))
(for x in '(1 2 3) (display x))
и опитайте да изпълните този файл, резултатът зависи от това как изпълнявам файла. Ако стартирам тази програма с помощта на chez --program
, тя работи според очакванията:
$ chez --program test-for.ss
123
$ _
Ако го стартирам с помощта на chez --script
, получавам същата грешка като по-горе:
$ chez --script test-for.ss
Exception: invalid syntax (for x in (quote (1 2 3)) (display x)) at line 6, char 1 of test-for.ss
$ _
Това повдига два въпроса:
- Защо REPL и
--script
се справят добре с импортирането на синтактични форми без специални ключови думи, но отказва да приеме синтактични форми, които имат специални ключови думи в тях? - Каква точно е разликата между
--script
и--program
? Ръководството за потребителя казва, че--program
означава, че съдържанието на файла се интерпретира като rnrs програма от най-високо ниво, но не се споменава каква е семантиката на--script
.
И накрая, за да направя объркването си пълно, ако въведа горната дефиниция на синтаксис директно в REPL, тогава всичко работи както се очаква:
> (define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
> (for x in '(1 2 3) (display x))
123
> _
И така, какво е различното в REPL между синтактични трансформатори, импортирани от библиотека, и синтактични трансформатори, дефинирани директно в REPL?
in
, както предлагате, получавам грешка, защото вforlib
няма дефинирано име за експортиране. Както е посочено от @gmw по-долу, за да работи това, е необходимоforlib
да създаде фиктивно имеin
, което може да бъде експортирано. - person Norbert Zeh   schedule 21.01.2019