?

Log in

No account? Create an account

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

Jul. 5th, 2014

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

Previous Entry Share Next Entry

Comments:

[User Picture]
From:xeno_by
Date:July 6th, 2014 04:42 pm (UTC)
(Link)
Одна из целей новой платформы - обеспечить anytime metaprogramming.

На слайде 53 кратко упоминается о том, что сохранение AST обеспечивает равные возможности для всех хостов. Это значит, что в новой системе не должно быть разницы между compile-time и runtime метапрограммированием - и там, и там будет информация про полный AST программы. По факту, единственной проблемой, которую мы пока что заметили, является erasure, но тут без тяжелой артиллерии не справиться.

Для примера. Сейчас в разработке находится GSoC проект по рантайм экспаншену макросов. По задумке, он предоставит возможность откладывать раскрытие определенных макро вызовов до рантайма, позволяя макросы, исполняемые во время компиляции, прозрачно раскрывать в рантайме. Посмотрим как оно будет, но пока что я надеюсь, что удастся во многом стереть границу между compile-time и runtime.
(Reply) (Parent) (Thread)
[User Picture]
From:_xacid_
Date:July 6th, 2014 04:48 pm (UTC)
(Link)
скоро в lisp превратитесь так :) шутка

а ваще конечно круто будет

когда (в какой версии) можно будет это использовать на работе? :)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 6th, 2014 04:58 pm (UTC)
(Link)
Если честно, неплохо было бы иметь настолько же солидные макросы как в лиспе (например, как в Racket). Только с типами, конечно - в этом главная идея наших макросов :D

Насчет сроков сложно говорить, так как работы непочатый край. На данный момент единственное, что мы точно планируем, это technology preview этой осенью. Там будет первый майлстоун scala.meta API, а также scalac host (хост, который реализует meta API поверх внутренней кухни scalac). Как следствие, уже можно будет начинать смотреть как существующие макросы портируются на новый API. Что-то большее пока что обещать не рискну.
(Reply) (Parent) (Thread)
[User Picture]
From:_xacid_
Date:July 6th, 2014 05:01 pm (UTC)
(Link)
ну дык я о том же что неплохо было бы лиспу нос утереть

а рекурсивные макро-лямбды в рантайме планируете? :)
шутка конечно (но естественно было бы не плохо тоже)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:July 6th, 2014 05:04 pm (UTC)
(Link)
Было бы неплохо :D

В принципе, с новыми механизмами должно все получиться. Сохранение AST обеспечивает рантайм экспаншен. Интерпретация обеспечивает раскрытие макросов независимо от того, где они объявлены. Но, конечно, это еще надо детально посмотреть - подводные камни бывают везде.
(Reply) (Parent) (Thread)
[User Picture]
From:_xacid_
Date:July 6th, 2014 05:05 pm (UTC)
(Link)
вау

ну тады ждем с нетерпением
(Reply) (Parent) (Thread)
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) (Expand)
[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)