?

Log in

No account? Create an account

scala.meta: новая платформа для метапрограммирования Скалы - Excelsior

Jul. 5th, 2014

12:16 am - scala.meta: новая платформа для метапрограммирования Скалы

Previous Entry Share Next Entry

Comments:

From:Valentin Budaev
Date:July 6th, 2014 05:59 pm (UTC)
(Link)
> По задумке, он предоставит возможность откладывать раскрытие определенных макро вызовов до рантайма, позволяя макросы, исполняемые во время компиляции, прозрачно раскрывать в рантайме.

Тогда у вас, получается, уже не макросы, а самые что ни на есть фекспры с соответствующими проблемами? Или какие-то ограничения есть на них?
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 6th, 2014 06:31 pm (UTC)
(Link)
Я поэтому и сказал "определенные макросы" :)

Пока что эта часть проекта это сплошной скетч, поэтому мне сказать особо нечего. Как вариант, можно требовать того, чтобы функции, вызов которых может осуществлять экспаншен, помечались специальным образом. Второй вариант это требовать специальной пометки в потенциальных коллсайтах. Мы немного обсуждали вот тут: https://groups.google.com/forum/m/#!topic/palladium-internals/xAVdcLWtf0k, но с того времени прогресс пока что шел в других направлениях, поэтому обновлений к тому дискашену пока что нет.
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:July 11th, 2014 05:09 pm (UTC)
(Link)
А не было мысли сделать некий аналог syntax-local-value из racket? Тогда оба варианта можно реализовать в виде сахара. Ну и кроме того подход racket с макросами-структурами, у которых определен prop:procedure, будет выглядеть намного красивее в языке с ООП в ядре.
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 11th, 2014 07:07 pm (UTC)
(Link)
А где можно почитать про syntax-local-value? В документации не очень много деталей по этому поводу.
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:July 12th, 2014 12:14 am (UTC)
(Link)
(syntax-local-value syntax-id) просто возвращает значение макроса, то есть в обычном случае ф-ю из syntax в syntax, но в общем мы же можем в макрос положить все что угодно, вот примерчик
http://pastebin.com/s6GJsyEh


Edited at 2014-07-12 12:17 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 12th, 2014 06:44 am (UTC)
(Link)
Спасибо! А как это работает с раздельной компиляцией?
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:July 12th, 2014 08:57 am (UTC)
(Link)
А никак, очевидно, это так называемый "3-D syntax", и раздельная компиляция с ним невозможна. Если хочется компилировать, то надо делать work around, окружая несереализуемые значения евалом, например, то есть чтобы самой лямбды в коде не было, а была форма, которая при вычислении возвращает эту лямбду.

Тут еще надо отметить, что begin-for-syntax - это core-форма, она никуда не исчезает после экспанда и остается в скомпилированном коде. По-этому даже после компиляции можно выполнять формы 1 фазы. А вот с макросами такое уже не прокатывает - они просто раскрываются. По-этому если хочется выполнить сайд-эффект в макросе, то следует вместо того чтобы просто написать "code", добавить в экспанд макроса #'(begin-for-syntax code), ну или #'(define-syntaxes () (begin code (values)), что то же самое, но работает в локальном контексте.
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 12th, 2014 06:43 am (UTC)
(Link)
Как я понимаю, prop:procedure реализован при помощи define-for-syntax переменной, значение которое извлекается через syntax-local-value?
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:July 12th, 2014 09:14 am (UTC)
(Link)
define-for-syntax никак не извлекается - определенная define-for-syntax переменная имеет значения из фазы 1 (вычисляется в 1) и связана в фазе 1. Переменная определенная через define связана в фазе 0 и имеет значение из 0 (вычисляемое в 0). Переменная определенная через define-syntax (макрос) - связана в фазе 0 и имеет значение, вычисляемое в фазе 1, ее-то значение мы и можем получить через syntax-local-value, при этом мы квотим имя переменной. То есть форма (syntax-local-value #'id) выполняется в 1 фазе, id связано в 0 фазе, если мы напишем (syntax-local-value id), то id в 1 фазе unbound, но под темплейтом (#') фаза опускается, переменная становится связана и мы в первой фазе извлекаем значение из переменной нулевой фазы. В общем случае это невозможно, конечно (ведь переменных 0 фазы в 1 фазе "еще не существует"), но т.к. эта переменная особая (макрос) и значение ее вычисляется в 1 фазе, то мы можем его получить через этот work around.

А prop:procedure - это просто специальный интерфейс ф-й, ну как в скале трейт Function - если структура реализует этот prop:procedure, то ее инстансы могут использоваться везде в качестве ф-й. В частности, мы можем определить структуру с prop:procedur, в котором ф-я будет имет тип syntax->syntax и тогда инстансы такой структуры можно использовать в качестве макросов - но при этом этот инстанс будет не прсото ф-ей макросом, но еще и иметь доп. информацию (поля структуры, собственно)

Например, сама форма определения структуры (struct struct-name args ...) определяет struct-name как макрос (define-syntax struct-name ...) и именно кладет в struct-name инстанс структуры с определенным prop:procedure. Как ф-я-макрос (struct-name args ...) раскрывается в конструктор структуры struct-name, но если мы сделаем (syntax-local-value #'struct-name) то получим обычный инстанс стурктуры к полям которого имеем доступ, с-но в этих полях сеттеры/геттеры, информация о супер-структуре и т.д. - все доступно в 1 фазе из других макросов. С-но макрос match когда в паттерне видит какой-то id, то он проверяет - а не является ли этот id указанным инстансом и если да, то через syntax-local-value получает его поля и на основе этой информации генерирует код для разбора значения.
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 6th, 2014 06:34 pm (UTC)
(Link)
Кстати было бы интересно мнение о потенциальных юзкейсах для рантайм экспаншена. Пока что у нас есть идея поэкспериментировать со стейджингом - в этой области у нас есть спрос, а остальные применения еще очень расплывчатые.
(Reply) (Parent) (Thread)
From:Valentin Budaev
Date:July 11th, 2014 05:49 pm (UTC)
(Link)
> Кстати было бы интересно мнение о потенциальных юзкейсах для рантайм экспаншена.

Не представляю, если честно. Но могут появиться юзкейсы благодаря взаимодействию языковых фич - вдруг получится делать какие-то интересные вещи с рантайм-экспаншеном и имплицитами, допустим? Тут надо точно семантику знать, иначе ничего не скажешь уже.
(Reply) (Parent) (Thread)