?

Log in

No account? Create an account

Метапрограммирование в Агде и немного философии - Excelsior

Aug. 27th, 2013

09:49 am - Метапрограммирование в Агде и немного философии

Previous Entry Share Next Entry

Comments:

From:Valentin Budaev
Date:August 29th, 2013 09:24 am (UTC)
(Link)
> (как я понимаю, по сути, правая часть define-syntax-rule является квазицитатой)

Да, define-syntax-rule потом раскрывается в другую макроформу, где правая часть будет под #'

> 1) Как ракет понимает, что x связывать не надо?

Он не не понимает надо или не надо, просто он смотрит на квазицитату, видит там х и ищет переменную с соответствующим именем в лексическом окружении квазицитаты в -1 фазе (-1 для квазицитаты, поскольку квазицитата в макросе, то есть в фазе 1, то это будет окружение 0 фазы, то есть рантайма). let и + в этом окружении есть, а х - нету, вот х и остается свободной.

> 2) Что было бы, если бы macro находился внутри лета, который объявляет свой собственный +? Плюс бы тогда связался или нет?

Тогда бы + связался не с module-level + из стандартной библиотеки, а вот этим самым lexical +.

> Что было бы, если бы в квазицитату что-то сплайсилось?


(define-for-syntax q+ #'+)

(let ([+ 1])
(define-syntax (macro stx)
#`(#,q+ + +))
(macro))

в результате 2
то есть плюс из внешней квазицитаты остается внешним, внутренний - становится внутренним.

> десь splicedTree может перекрыть биндинги как для икса, так и для плюса.

Как он может их перекрыть?

Edited at 2013-08-29 09:30 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:August 29th, 2013 09:33 am (UTC)
(Link)
2) То есть ракет бы разрешил такой квазицитате быть частью какого-то макро экспаншена только если этот макро экспаншен происходит под этим же самым летом?
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:August 29th, 2013 10:00 am (UTC)
(Link)
Вообще, выдернуть такую квазицитату вовне - это уже весьма нетривиальная задача:


(define-for-syntax x-var #f)

(define-syntax (set-var! stx)
(syntax-case stx ()
[(_ var) (begin (set! x-var (syntax-local-introduce #'var))
#'(void))]))

(define-syntax (get-var stx)
(syntax-local-introduce x-var))

(let ([x 1])
(set-var! x))

(let ([x 2])
(get-var))

ошибка: x: identifier used out of context in: x
при этом с марками все в порядке - то есть х который приходит из (get-var) марок не имеет.

И это логично вобщем-то - за пределами ее лексического контекста локальной переменной не существует.

Можно, вообще говоря, имея этот х собрать специально для него лет-форму, но зачем?

Edited at 2013-08-29 10:02 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:August 29th, 2013 03:36 pm (UTC)
(Link)
Познавательный эксперимент, спасибо!

Я скорее имел ввиду вот это:
{
  val x = 2
  @forSyntax val qq = q"x"
  macro foo = qq
  foo
}
Как я понимаю, этот пример работать будет, так?

Edited at 2013-08-29 03:38 pm (UTC)
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:August 29th, 2013 04:25 pm (UTC)
(Link)
Будет, тут никакой проблемы нету. Контекст один - все, что внутри {}, ничего ниоткуда не выносится и все ок.

ЗЫ: как вставлять код, чтобы отступы не бились? А то лиспокод без отступов... ну... :)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:August 29th, 2013 11:53 pm (UTC)
(Link)
Я использую
<code><pre>...</pre></code>


Edited at 2013-08-29 11:54 pm (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:August 29th, 2013 09:34 am (UTC)
(Link)
val splicedTree = q"def +(x: Int, y: Int) = x * y"
q"val x = 1; $splicedTree; +(x, 1)"
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:August 29th, 2013 10:04 am (UTC)
(Link)
Ну сперва (при раскрытии _определения_ макроса, где цитата была) связывание + будет стандартное, со стандартным плюсом, а потом когда макрос раскроется, то анализируется раскрытый код и если с марками все ок, то + из сплайсинга перекроет старое связывание.

ЗЫ: я понял, к чему вы. с такой схемой типизировать цитаты принципиально невозможно - если только не добавлять в тип цитаты информацию о том, какие связывания она добавляет.

Edited at 2013-08-29 10:06 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:August 29th, 2013 03:32 pm (UTC)
(Link)
Ага, понял. Мы пока что не замахиваемся на типизацию квазицитат, так что это не проблема.
(Reply) (Parent) (Thread)