Language with a Bright future
Aug. 25th, 2013 01:18 amВ начале мая в логове фейсбука прошла конференция DConf, посвященная языку D. Финансировали ее всем миром через проект на кикстартере, я там тоже поучаствовал скромным спонсором. Видео всех выступлений были выложены на ютюбе, вот наиболее мне понравившиеся, которые могу порекомендовать всем тем, кто открыт к новому и имеет немного любопытства:
1. Web Development in D - какие есть замечательные инструменты (в первую очередь vibe.d), как с ними все получается просто и красиво (и эффективно), благодаря грамотному использованию возможностей D.
2. Writing Testable Code in D - тут больше демонстрация умений и удобств языка.
3. Metaprogramming in the Real World - занятный experience report от компании с сотней программистов, где весь код пишется на D.
1. Web Development in D - какие есть замечательные инструменты (в первую очередь vibe.d), как с ними все получается просто и красиво (и эффективно), благодаря грамотному использованию возможностей D.
2. Writing Testable Code in D - тут больше демонстрация умений и удобств языка.
3. Metaprogramming in the Real World - занятный experience report от компании с сотней программистов, где весь код пишется на D.
no subject
Date: 2013-08-24 06:21 pm (UTC)no subject
Date: 2013-08-24 09:40 pm (UTC)no subject
Date: 2013-08-25 07:19 am (UTC)Rust выглядит наиболее обещающим и перспективным, но он сейчас наиболее недоделанный, все время там все ломают и переделывают.
D находится где-то между ними: как язык довольно приятен, реализации более-менее юзабельные, но есть еще недоделки.
Из этих трех мой выбор сейчас - D.
no subject
Date: 2013-08-25 07:56 am (UTC)no subject
Date: 2013-08-25 09:29 am (UTC)no subject
Date: 2013-08-25 10:33 am (UTC)long fac(long n) { return iota(1,n+1).reduce!"a*b"; }
no subject
Date: 2013-08-25 09:53 am (UTC)no subject
Date: 2013-08-25 10:21 am (UTC)no subject
Date: 2013-08-28 07:42 am (UTC)no subject
Date: 2013-08-28 06:14 pm (UTC)С вызовом функций в компайл-тайме на практике редко сталкиваешься, т.к. все интересные данные программа получает уже в рантайме, а при компиляции какие данные есть? Собственные исходники разве что, так что фича эта в основном используется внутри всяких шаблонов, генерирующих код. Чтобы код удобно было генерить, нужна работа со строками, массивами и основные алгоритмические штуки из стандартной библиотеки, вот они и используются. Т.е. в целом фича, может, и мегакрутая, но замечают это лишь библиотекописатели, а при написании обычных программ ее и не замечаешь, даже если где-то внутри используемых библиотек она и работает активно.
no subject
Date: 2013-08-28 06:16 pm (UTC)no subject
Date: 2013-08-28 06:29 pm (UTC)class MyClass(T) { ... static if (SomePredicate!(T)) { Result!T my_function(T x, ...) { .... } } ...Тут и квазицитаты не нужны, пишешь обычный код.
no subject
Date: 2013-08-28 06:30 pm (UTC)no subject
Date: 2013-08-28 07:44 am (UTC)no subject
Date: 2013-08-28 06:04 pm (UTC)Типичные же юзкейсы - это получить на вход некоторый заранее неизвестный тип Т, используя развитую компайл-тайм рефлексию разузнать, подходит ли он и что он умеет, и на выходе родить новый тип R, сохраняющий или преобразующий полезные свойства Т и делающий что-то свое. Например, так комбинаторы map/take/reverse/zip и т.п. сохраняют такие свойства переданных в них последовательностей как "известная длина", "клонируемость", "доступ по индексу за О(1)" и т.д. Или, например, берется на вход некоторый класс и возвращается его аналог, где методы превратились в RPC вызовы или наоборт обработчики RESTful запросов. Вся рефлексия и рождение кода происходят при компиляции, рантайм-оверхед нулевой.
Ну и всевозможная сериализация-десериализация, конечно.
no subject
Date: 2013-08-28 06:08 pm (UTC)no subject
Date: 2013-08-28 06:19 pm (UTC)no subject
Date: 2013-08-28 06:09 pm (UTC)no subject
Date: 2013-08-28 06:55 pm (UTC)А если про конкретную реализацию, то:
1. Порой хочется увидеть результат раскрытия всех шаблонов. Вон в Си можно посмотреть результат препроцессора, в GHC куча всяких промежуточных представлений доступна, а тут я не знаю, как заглянуть в середину между исходником и бинарником. Воможно, в GDC или LDC что-то такое есть, не в курсе.
2. Сообщения об ошибках порой не шибко информативные. Например, если есть несколько реализаций шаблона с разными предусловиями, и ни один предикат не сработал, то шаблон не инстанциируется, при этом сообщение об ошибке может быть весьма неожиданным, приходится догадываться.
3. Если писать сложный код в ФП-стиле, где замыкание внутри замыкания замыканием погоняет, и все передаются как alias параметры во всякие комбинаторы, компилятору порой сносит крышу.
no subject
Date: 2013-08-28 06:14 pm (UTC)no subject
Date: 2013-08-28 06:37 pm (UTC)no subject
Date: 2013-08-28 06:49 pm (UTC)Что-то типа:
map(List(1, 2), x => x) возвращает List[Int]
map(Vector(1, 2), x => x.toString) возвращает Vector[String]
map(Map(42 -> "42"), x => true) возвращает BitVector
no subject
Date: 2013-08-28 07:21 pm (UTC)http://ddili.org/ders/d.en/ranges.html
Сейчас контейнеры умеют представлять себя в виде рэнждей, с которыми работают всевозможные алгоритмы и комбинаторы. Если контейнерам еще добавить универсальный способ создаваться из рэнджей (не помню, есть ли это сейчас), то запрошенная тобой функция будет совсем простой. Завтра могу попробовать сделать пример.
no subject
Date: 2013-08-28 07:39 pm (UTC)no subject
Date: 2013-08-29 09:14 am (UTC)no subject
Date: 2013-08-29 12:34 pm (UTC)http://en.wikipedia.org/wiki/Expression_templates
т.е. сделать лямбды не простыми, а строящими AST. С перегрузкой операторов это не так сложно.
no subject
Date: 2013-08-29 03:21 pm (UTC)no subject
Date: 2013-08-28 06:29 pm (UTC)В целом, мне нравится дишный подход к метапрограммированию. Да, многие вещи довольно адхочно сделаны, но в целом все очень задорно, и, что главное, народ не стесняется МП как у нас в коммьюнити.
Конечно, когда я читал посты и тексты, в голове сразу начал работать сравнитель. С одной стороны, стратегия как в лиспах, как у нас, когда вычисления времени компиляции спрятаны за макросами, которые основаны на reflection API. С другой стороны ди, в котором есть куча разных средств CTM (как утверждает один пост, "here is the basic tool box: typeof, is, alias, static if, __traits, std.traits, CTFE."), которые можно юзать вперемешку с кодом.
Какой из этих двух стилей МП тебе больше нравится? Да, в ди некоторые вещи можно делать очень просто, но за это приходится расплачиваться пачкой фич в языке + винегретом из метауровней. Насколько это является проблемой на практике?
no subject
Date: 2013-08-28 07:08 pm (UTC)no subject
Date: 2013-08-28 07:35 pm (UTC)no subject
Date: 2013-08-29 08:25 am (UTC)no subject
Date: 2013-08-28 07:15 pm (UTC)А я-то, грешным делом думал, что он сдох давно.
no subject
Date: 2013-08-29 12:30 am (UTC)no subject
Date: 2013-09-08 10:37 am (UTC)Например, вот в этом случае могут ли раскрываемые шаблоны видеть мемберы класса C и какие именно мемберы они увидят:
class C { int x; mixin(genJsonSerializable!C); // перебирает мемберы и создает метод toJson mixin(genXmlSerializable!C); // перебирает мемберы и создает метод toXml int y; }no subject
Date: 2013-09-08 06:29 pm (UTC)mixin template ToJSON(C) { void toJSON() { enum mbs = [__traits(allMembers, C)]; // compile-time created array writeln(mbs); } } mixin template ToXML(C) { void toXML() { enum mbs = [__traits(allMembers, C)]; writeln(mbs); } } class X { int x; mixin ToJSON!X; mixin ToXML!X; int y; } void main(string[] argv) { auto x = new X; x.toJSON; x.toXML; }Выводит:
["x", "toJSON", "toXML", "y", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]
["x", "toJSON", "toXML", "y", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]
no subject
Date: 2013-09-08 08:39 pm (UTC)no subject
Date: 2013-09-09 03:55 am (UTC)no subject
Date: 2013-09-08 10:44 pm (UTC)no subject
Date: 2013-09-09 03:52 am (UTC)module mymodule;
и в коде пишем:
writeln([__traits(allMembers, mymodule)]);
получаем
["object", "std", "ToJSON", "ToXML", "X", "main", "D12TypeInfo_Axa6__initZ"]
Если еще вспомнить про user-defined attributes, получаем довольно могучий струмент.
no subject
Date: 2013-09-09 06:37 am (UTC)no subject
Date: 2013-09-09 07:51 am (UTC)mixin template ToXML() { void toXML() { writeln([__traits(allMembers, __traits(parent, toXML))]); } } class X { int x; mixin ToXML; }Вызов toXML выводит
["x", "toXML", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]