LINUX.ORG.RU

Вопрос по quasiquote и unquote-splicing

 quasiquote, scheme.racket, unquote, unquote-splicing


0

1

Продолжаю пилить свою имплементацию r5rs на Java.

Наконец дошли руки до quasiquote/unquote/unquote-splicing.

Скажу честно - это кошмар какой-то. Читаешь и, вроде, все более-менее понятно. Довльно простые штуки.

Но потом оказывается, что там стопицот особых случаев. И код превращается в непонятную кашу сплошных if-else'в (не говоря уже о том, что в разных Схемах quasiquote работат немного по-разному).

А, да, всю эту quasi-кашу делаю через list и append (http://repository.readscheme.org/ftp/papers/pepm99/bawden.pdf)

Так вот, оно вроде как работает, практически все тесты проходят. Но возник вопрос по одному тесту:

`(1 ,@())

Как эта штука должна работать?

Guile ругается:

guile> `(1 ,@())

Backtrace:
In standard input:
   5: 0* (quasiquote (1 (unquote-splicing ())))

standard input:5:1: In procedure memoization in expression (quasiquote (1 #)):
standard input:5:1: Illegal empty combination ().
ABORT: (syntax-error)

Racket не ругается и выдает:

Welcome to Racket v6.2.1.
> `(1 ,@())
'(1)

Chicken Scheme:

#;1> `(1 ,@())

Error: illegal non-atomic object: ()
inside expression `(##sys#cons ...)'

        Call history:

        <syntax>          (quasiquote (1 (unquote-splicing ())))
        <syntax>          (##sys#cons (##core#quote 1) ())
        <syntax>          (##core#quote 1)      <--

Если перевести это на аналогичный код в Clojure, то он выдает ответ, аналогичный Racket'у:

user=> `(1 ~@())
(1)

Кто прав?

Чисто интуитивно я согласен c Guile и Chicken:

unquote-splicing пыдается вычислить последующую форму (и если она вернет список, то оно подставит элементы списка вместо себя).

Форма после unquote-splicing - пустой список без quote: ()

Оно пытается его выполнить и фейлится (что логично и понятно).

Если «починить» этот пример, добавив quote, то все работает:

guile> `(1 ,@'())
(1)

Но я не совсем понимаю как Racket и Clojure выполняют эту штуку и возвращают '(1).

Ладно, Clojure еще можно понять, там () evaluate'иться в () (quote не нужен). Но Racket?

Или это очередной особый случай?

★★★★★

Последнее исправление: kovrik (всего исправлений: 4)

Ага, это они, видимо, в r6rs поменяли что-то и там этот пример валиден, тогда как в r5rs - нет (Guile, Chicken).
Так ли это?

kovrik ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.