You are viewing xeno_by

Excelsior

Jan. 1st, 2020

12:00 am - Давайте познакомимся

Всем привет! Меня зовут Женя или Ксено. Здесь я буду постить свои новые идеи, рассуждения о программировании, события и факты, преломленные через призму моего восприятия. Не знаю даже, чего больше хочу - поделиться своими идеями во славу Мирового Разума, или заодно еще и получить фидбэк, но по ходу дела разберемся.

Коротко о главном. Очень люблю творчество (в моем случае оно находит выражение в программировании). Ищу общения с людьми, которым интересно жить. Хорошо, если вам будет тут интересно, очень хорошо, если что-нибудь пригодится, совсем замечательно, если мы подискассим посты в каментах. Меня можно и нужно называть на "ты". Кроме каментов связаться со мной можно по мылу/гтолку: xeno.by@gmail.com или по скайпу xeno.by. Также, у меня есть профайлы в плюсе, в твиттере и на фейсбуке.

Из интересного:
  1) Мои опен-сорс проекты проиндексированы вот тут: http://projects.xeno.by (некоторые из них описаны в этом ЖЖ: пост про метапрограммирование в C#, пост про Конфлакс),
  2) В аспирантуре EPFL работаю над макросами для Скалы,
  3) В аспирантуре ОИПИ НАНБ работал над Конфлаксом, системой для гетерогенных параллельных вычислений,
  4) Люблю анализировать и оптимизировать wetware - ментальный фреймворк организации сознательной деятельности,
  5) Проверяю на практике идею расширения сознания посредством смены инструментов работы: языка программирования, программного окружения, операционной системы. На этом пути меня порадовал Линукс, я был наповал сражен Емаксом, и смог заменить тотал коммандер на гораздо более эффективный файловый менеджер. Впрочем, через несколько месяцев линукса я вернулся на винду с багажом новых впечатлений и скиллов. А закончилось все тем, что я теперь работаю в макоси,
  6) Расшарил и проиндексировал подборку статей и книжек по программированию (там есть по разным аспектам функционального программирования, метапрограммирования, теории типов и еще много всякого разного, например, набор статеек и слайдов для подготовки к собеседованию по алгоритмам).
  7) Собрал заметки по переезду в Лозанну: как привезти баблос, как сделать мобильный интернет, как снять жилье, о резиденс пермите и всякое разное остальное.

Через меня можно задать вопросы команде разработчиков Scala. Сразу отмечу, что непонятки по синтаксису и функциональности лучше отправлять на stackoverflow или в почтовую рассылку - там на них весьма быстро ответят люди более опытные, чем я. С другой стороны, открытые вопросы и предложения (вроде, например, вот такого или вот такого) можно запостить и сюда. Так как я нахожусь географически недалеко от Мартина и других участников Scala Team, то у меня есть дополнительная возможность обсуждать с ними сабжевые вещи. Не стоит ожидать чудес, но обещаю делать все, что смогу.

Под катом инфа о правилах бложекаCollapse )

Tags:

Aug. 29th, 2013

10:24 am - Макросы vs шаблоны

Продолжая дискуссию про метапрограммирование в D: http://thedeemon.livejournal.com/68456.html.

С одной стороны, дишный стиль МП кажется очень адхочным, но, с другой стороны, поверхностное знакомство и отзывы автора журнала оставляют впечатление чего-то крайне легкого в использовании. Цитируя уважаемого thedeemon:

Я видел много разных попыток сделать удобные лисп-стайл макросы (camlp4, nemerle, haxe, какие-то кусочки скалы...), и везде это пляски с бубном, часто отдельные фазы компиляции, отдельный синтаксис и длинное страшное слово "метапрограммирование". В D же просто берешь и пишешь generic код, даже и мысль о таком длинном слове не приходит.
Вот, например, надо сгенерировать класс, который в зависимости от типа, передаваемого в генератор, будет иметь или не иметь какие-то мемберы [1].

Макросы

В скале мы пишем макрос, который заворачивает шаблон класса в квазицитату. В эту квазицитату мы сплайсим условно генерируемые кусочки. Например, вот так:
val length = if (R.method("hasLength").exists) q"..." else EmptyTree
val empty = if (isInfinite(R)) q"..." else EmptyTree
q"""
  class MyRange {
    val innerRange: R = ...
    ... // code that exists in all instantiations of MyRange
    $length
    $empty
  }
"""
Да, классно, что есть полноценный рефлекшен API вместо пачки захардкодженных в язык __traits и основанных на них самописных темплейтах, которые, например, делают is(typeof(...)). Да, классно, что сниппеты кода являются первоклассными сущностями и что, соответственно, нет проблем их модуляризировать как угодно. Да, классно, что МП реализуется только макросами, а не кучей языковых фич вроде alias, enum, template, и так далее [2, 3].

Шаблоны

Но все же, посмотрите, как задорно выглядит дишный вариант! (Ниже приведена моя личная экстраполяция примера из книжки, может содержать ошибки). Заметьте отсутствие ада метауровней вида q"бла" бла бла q"бла бла" бла q"бла" (что-то похожее мы обсуждали на scala-internals в контексте тайп макросов [4]). Понятное дело, метауровни никуда не делись - они просто перемешались с генерируемым кодом, но насколько стало удобнее читать:
struct MyRange(R) {
  R innerRange;
  ... // code that exists in all instantiations of MyRange
  static if (hasLength!R)
    auto length() { return innerRange.length; }
  static if (isInfinite!R)
    enum bool empty = false;
}

Вопрос

А теперь вопрос. Какой стиль метапрограммирования кажется вам предпочтительным для решения повседневных задач: макросы или темплейты? Если ответ неоднозначный, то в каких случаях вы бы выбрали макросы, а в каких - темплейты?

Предлагаю оставить в стороне проблемы имплементации того или иного стиля (падения компилятора на сложных темплейтах, сырость первой (экспериментальной!) версии макросов в Скале 2.10, и так далее). Предположим, что подлежащие реализации работают идеально без глюков.

Также хочу отметить, что не принимается ответ "макросы круче потому, что на них можно реализовать темплейты". Вопрос не в том, какой фундамент для МП теоретически более элегантный, а в том, какой тул вам было бы приятнее использовать, независимо от того, на чем именно этот тул реализован.

Ссылки

[1] https://github.com/PhilippeSigaud/D-templates-tutorial/raw/master/D-templates-tutorial.pdf, страница 21, раздел "Optional code"
[2] http://dicebot.blogspot.ch/2013/04/7-trivial-tips-for-compile-time-meta.html, часть 1
[3] http://xeno-by.livejournal.com/86259.html
[4] https://groups.google.com/d/msg/scala-internals/91W0-PxMQ9Q/hq5n47RxfN8J

Tags: ,

Aug. 28th, 2013

08:31 pm - Обсуждение метапрограммирования в D

Читаем вот тут: http://thedeemon.livejournal.com/68456.html. Спасибо уважаемому thedeemon за подробные ответы!

Tags: ,

02:10 pm - Эмуляция ключевого слова static из D на макросах

Очень порадовал комментарий некоего схемиста [1] к посту про compile-time function execution в D.

Если вкратце, в D перед объявлением переменной можно написать ключевое слово static (например, static int r1000 = euler1(1000)) и это приведет к тому, что компилятор попытается посчитать правую часть объявления во время компиляции.

Увидев оригинальный пост, я сразу начал думать, как то же самое можно было бы наколбасить на макросах в Скале. В принципе, что-то похожее можно изобразить уже прямо сейчас, объявив euler1 как макрос, который потом раскроется во время компиляции и дальше понятно. Но, конечно, это далеко не так интересно, как static, т.к. таким образом встраиваемые функции: 1) нужно объявлять специальным образом, 2) в них нужно работать с абстрактными синтаксическими деревьями, а не с обычными значениями, 3) как следствие пункта 2, не получится шарить эти функции между компайл-таймом и рантаймом.

Впрочем, есть решение, которое позволяет изобразить в точности ту же самую семантику, которая доступна в D. Для этого нужно написать хитрый макрос, назовем его ct, который будет использоваться вот так: val r1000 = ct(euler1(1000)). При желании, можно завернуть этот макрос в аннотацию, чтобы все выглядело предельно похоже на D: @static val r1000 = euler1(1000).

Что же будет делать этот макрос? На каждый экспаншен он будет генерить по макросу и тут же эти макросы вызывать. Например:

ct(euler1(1000))

↓

{
  macro temp = lift(euler1(1000))
  temp
}
Крутота неописуемая. Жаль только, что в текущей реализации макросистемы в Скале такие фокусы не пройдут из-за требования раздельной компиляции макросов и кода, их использующего.

[1] http://www.reddit.com/r/programming/comments/cb14j/compiletime_function_execution_in_d/c0rcqac

Tags: ,

Aug. 27th, 2013

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

На днях просмотрел паперу Dependent Type Providers [1] и магистерскую диссертацию Reflection in Agda [2], которые используют средства рефлекшена, предоставляемые Агдой, для метапрограммирования.

Прикольно было увидеть как народ брутфорсит некоторые вещи (например, подмножество функциональности тайп провайдеров) просто за счет того, что в Агде более мощная система типов.

Но самое интересное было в том, что, несмотря на навороченность системы типов, в Агдовском рефлекшене наблюдаются примерно те же самые проблемы, с которыми мы боремся в Скале:
1) Низкоуровневость API синтаксических деревьев
2) Невозможность использовать квазицитирование для нетипизированных фрагментов кода
3) Отсутствие возможности создавать новые конструкторы данных во время компиляции
4) Протекание деталей реализации (например, [3])

На мой взгляд, это очень показательный факт для иллюстрации того, что удобное метапрограммирование не получается автоматически из факта продвинутости языка программирования. Для метапрограммирования необходим серьезный доменно-специфичный фундамент [4].

[1] https://groups.google.com/forum/#!topic/scala-internals/B9g31aAkebE
[2] http://igitur-archive.library.uu.nl/student-theses/2012-1030-200720/UUindex.html
[3] http://code.google.com/p/agda/issues/detail?id=466
[4] http://xeno-by.livejournal.com/85721.html

Tags: ,

Aug. 7th, 2013

08:11 am - Зачем компилятор должен поддерживать гигиену?

Затем, чтобы синтаксический сахар в вот таких ситуациях

case class C(x: D)

↓

object C {
  def apply(x: D) = new C(x)
}
Не приводил к казусам вроде:
case class C(x: D)
object C { type D = Double }

↓

object C {
  type D = Double
  def apply(x: D) = new C(x)
}
Как говорится, science. It works. Низкотехнологичные решения в таких ситуациях вынуждены прибегать к очень некрасивым хакам для реализации того, что в гигиеничных системах достигается забесплатно.

Tags: ,

08:00 am - Новый релиз macro paradise: теперь есть макро аннотации и можно использовать с 2.10

Всем привет! Сегодня хочу рассказать о том, что на днях выпустил новую версию macro paradise: http://scalamacros.org/news/2013/08/05/macro-paradise-2.0.0-snapshot.html. По ссылке есть детали, а здесь я просто вкратце остановлюсь на главных моментах:

1) Теперь paradise это плагин к компилятору Скалы, поддерживающий квазицитаты и макро аннотации для серии 2.10.x. Народ из Spire уже подтянулся использовать его для переписывания существующих макросов на квазицитаты. Остальной народ ждет ближайших выходных :)

2) Как обычно, в плане того, что касается макросов, можно рассчитывать на мою личную поддержку. После публикации Скалы 2.11 будет выпущен плагин для 2.11 и возможности из парадайза, которые не войдут в Скалу 2.11 (например, макро аннотации, если мы не успеем реализовать соответствующий Scala improvement process до заморозки кода), я буду поддерживать в 2.11.

3) Появились правильные макро аннотации, в которых можно: а) аннотировать любые определения, б) раскрываться в список определений, в) изменять объекты-компаньоны при раскрытии классов. Народ пока приценивается (хотя Simon Ochsenreither уже воплощает свою мечту о нормальных енумах), и, я уверен, мы придумаем интересные способы использования, но вот сразу один из несложных и одновременно полезных сценариев - реализация тайп-провайдеров для генерации статически типизированных оберток для внешних источников данных.

4) Продолжая традицию макросов приносить в мир добро, макро аннотации позволяют значительно упростить внутренние детали реализации компилятора и дать пользователям возможности для конфигурации стандартных возможностей языка. Похоже на то, что удастся объединить разрозненные куски кода, отвечающие на синтетические мемберы (кейс классы, геттеры/сеттеры для валов, и так далее) в единый механизм. Например, удалось практически полностью реализовать @kase классы на макросах. Будущие выпуски парадайза позволят полностью покрыть спецификацию, даже в самых ее крайних случаях.

Tags: ,

Jul. 20th, 2013

01:27 pm - Для чего полезны макросы?

Интересно ваше мнение по поводу моего недавнего выступления на Scalapeño 2013: http://scalamacros.org/paperstalks/2013-07-17-WhatAreMacrosGoodFor.pdf.

В презентации я попробовал классифицировать то, как в Скаловском сообществе используются макросы. В результате получились три (частично пересекающиеся) области применения: кодогенерация, статические проверки и доменно-специфические языки. Для каждой области в слайдах приведены по три примера и показывается как именно они выражаются на макросах (какие-то из этих примеров я уже публиковал, какие-то нет).

Tags: ,

Jul. 12th, 2013

07:20 pm - Новые трюки в мире макросов

1) Структурные типы без издержек на рефлексию: http://meta.plasm.us/posts/2013/07/12/vampire-methods-for-structural-types/
2) Тайп провайдеры на деф-макросах: http://meta.plasm.us/posts/2013/07/11/fake-type-providers-part-2

Tags: ,

Jun. 25th, 2013

12:01 am - Why not be dependently typed?

МакБрайд про зависимые типы в Хаскелле: http://stackoverflow.com/questions/12961651/why-not-be-dependently-typed/13241158#13241158 + свежая папера его же на ту же тему: http://www.reddit.com/r/haskell/comments/1gz03w/hasochism_the_pleasure_and_pain_of_dependently/.

Еще понравилась цитата: "Dependent types make a lot of people nervous. They make me nervous, but I like being nervous, or at least I find it hard not to be nervous anyway" :)

Navigate: (Previous 10 Entries)