Pull to refresh

Comments 56

Замечание от переводчика: этот пост напомнил мне, что с момента последнего основательного обзора состояния дел в D прошло изрядно времени и все успело поменяться. Предлагаю всем, кто заинтересован, но не имеет времени разобраться в деталях оставлять здесь запросы на интересующие темы по D(2), и, кто знает, быть может эта информация вскоре появиться на Хабре ;)
UFO just landed and posted this here
Можно, но вероятность изменений в коде, склеивающим frontend и backend крайне велика. Сами по себе они не сильно связаны, так так frontend у всех 3х компиляторов D один и тот же. Лучше всего пообщаться на этот счёт с Ian Buclaw, он является на данный момент ведущим мейнтейнером GDC. Дополнительно может потребоваться подправить druntime, в зависимости от того, насколько система posix-compliant.

Конкретно под qnx едва ли кто-то пытался завести, несколько человек неторопливо пилят в сторону Android NDK, можно получить некоторое представление о возникающих проблемах при портировании под новые ОС/железо в этой теме: forum.dlang.org/thread/20120204203109.26c9a80b@jpf-laptop

Общее мнение — ничего неподъемного или сверхдолгого, но засучить рукава и разобраться в исходниках toolchain придётся. Тема достаточно специфическая.
Хотел спросить про веб-разработку на D. В комментах уже нашел ссылку на проект vibe.d (http://vibed.org).
Расскажите больше! Это единственный «движок» для веб-проектов на D или есть и другие? Какие-нибудь истории успеха в запуске веб-сайтов написанных на D?
Если интересует именно фреймворк «всё включено», то да, единственный. А так есть, например, ещё и github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff — этот добрый молодец ведёт коммерческую разработку сайтов на D2 уже несколько лет в связке с fastCGI. Выше уже упомянули, что веб-клиент к официальным newsgroup тоже написан на D2.

По vibe.d собираюсь делать отдельный обзор в ближайший месяц-два.
Что у D с работой под ARM, и игровыми движками? Интересуют мобильные платформы.
ARM как таковой — не проблема, GDC вполне умеет под него собирать. Проблема в системном окружении, т.к. тот же Anroid не вполне posix-compliant и требуются внимательные изменения в druntime как минимум. Выше уже приводил ссылку на эксперименты со сборкой gdc под Android NDK: forum.dlang.org/thread/20120204203109.26c9a80b@jpf-laptop

Про iOS не знаю ничего.

C мобильными игровыми движками всё проще — ничего не мешает использовать их через C-bindings прямо сейчас кроме того, что runtime базового языка не готов. В целом это одно из тех направлений, где формально со стороны языка/компиляторов почти всё готово для создания инфраструктуры, но нужен кто-то, достаточно заинтересованный, чтобы потратить усилия на изначальное портирование и поиск багов. На данный момент в D community специализирующихся на этом направлении я не знаю. Геймдевелоперы есть, но не под мобильные системы.
UFO just landed and posted this here
Это очень обширная тема, даже на хабре уже есть штук 5 статей на тему обзора плюшек D. В один комментарий по-хорошему не уложусь. Попробую совсем бегло.

Быстродействие при сравнении gdc vs gcc — одного порядка, больше зависит от мастерства разработчика, чем от особенностей языка. Память — зависит от того, сколько волностей разрешаете garbage collector. Стартовый overhead выше за счёт druntime, но потребление памяти приложением как таковым полностью зависит от выбранной модели работы с оной. Скорость и удобство разработки — в пользу D на порядок, без преувеличений, просто не сравнимые вещи.

Кроссплатформенность, конечно, возможна, на сейчас как раз идёт бета-тест версии DMD с поддержкой Win64 и COFF формата, после его релиза базовый набор Linux/Windows/Mac 32/64 будет поддержан в полном виде. ARM — через GDC.

Прелести в сравнении с С++ навскидку:
— система шаблонов, изначально спроектированная для массового использования, в отличии от случайной находки С++
— полноценные делегаты и иже с ними
— более мощная система типов за счёт доп. гарантий от компилятора и способов статической интроспекции
— ranges ( дальнейшее развитие итераторов ) как базовое понятие языка и основа дизайна как встроенных массивов, таки и стандартной библиотеки

dlang.org/comparison.html

Один из старых слоганов D ЕМНИП — «C++ done right»
UFO just landed and posted this here
bitbucket.org/qtd/repo
Довольно давно не обновлялось, впрочем, не знаю насколько сейчас юзабельно.
Gtkd поддерживается сейчас несколько активнее.
> как раз идёт бета-тест версии DMD с поддержкой Win64 и COFF формата
1.1 Что вообще могут на текущий момент генерировать компиляторы (dmd2, ldc, gdc)? В случае последних — всё, что поддерживается бэкэндами? Или же поддерживается только х86? Я имею ввиду именно генерацию кода в объектники.

1.2 Что из вышеперечисленного реально работает? (Тут вопрос уже про полноценную поддержку окружения)

По андроиду — насколько я понял, есть форк gdc, но у них проблемы с druntime over bionic.
1.1 — да, всё что поддерживается бэкэндами

1.2 — помимо x86 мне известно об успешном запуске под ARM/Linux. В теории должно без большой головной боли заводится всё, что поддерживает backend и что достаточно posix-compliant, чтобы на нём с пол пинка собрался druntime.

Про android всё верно понимаете.
Слышал, что при ручном управлении памятью придётся отказаться от стандартных библиотек.
Невозможность абсолютно полного ручного управления памятью — единственное, что меня отталкивает от D.
Это не совсем так. Garbage collector и ручное управление памятью прекрасно соседствуют в D бок о бок. Некоторые известные мне проекты используют предаллоцированные пулы памяти управляемые вручную для основной массы данных и garbage collector — для «менеджерских» задач, поддержки делегатов и тому подобных плюшек. Получается довольно практично.

Другое дело, если существование garbage collector для вас вообще непримлемо, даже в качестве скулящего в углу бедного родственника. Тогда да, про phobos придётся забыть, т.к. там может выделяться память, которая начнёт течь. С другой стороны, вся стандартная библиотека С все ещё в полном распоряжении, так что относительно С вы ничего не теряете.

Когда Александреску опубликует спеки по аллокаторам ( он очень серьёзно относится к их дизайну и не хочет ничего показывать, пока не будет наверняка ) ситуация просто превратится из нормальной в великолепную: )
А можно поподробней про эти аллокаторы? Почему жизнь с ними станет лучше?
I'm making good progress on an allocator design. If things come together
as I hope, it'll kick some serious ass.

I'm currently looking at four allocation models:

* straight GC, safe (no deallocation)
* GC + the ability to free memory
* malloc/free, unsafe, buyer beware (STL-level safety)
* reference counted (based on either malloc or GC+free)
* region (scoped)

© Alexandrescu этой весной. С тех пор что-то застопорилось, но продолжаем верить :)

Почему станет лучше — а) исчезнет привязка аллокации в phobos на garbage collector, станет возможным использование всей стандартной библиотеки вообще не включая gc в приложение б) это будет означать зелёный свет для добавление продвинутых контейнеров в стандартную библиотеку.
Ещё одну хорошую IDE забыли — D-IDE
Лично мне нравится больше всех остальных. Простая и умеет почти всё что надо. Интерфейс только странный.
Во-первых, это перевод.
Во-вторых, я подозреваю, что автор оригинального текста упомянул те, над которыми ведется активная работа именно сейчас.

P.S. Хотя, как вижу, у D-IDE тоже совсем недавно были коммиты, это отрадно.
У D-IDE и Mono-D один разработчик и даже единый code-base.
Спасибо, не знал, думал это одна из многочисленных полузаброшеных попыток сделать IDE с нуля.
Или попробуйте стэковые scoped классы. Или счётчики ссылок. Или RAII.

я не совсем понимаю, где там RAII, когда в Andrei Alexandrescu — The D Programming Language — Addison Wesley 2010 я читаю:
tearing an object down follows a little protocol:

4. At some implementation-dependent point, the system acknowledges that the object's memory may be recycled and invokes its destructor.

так деструктор вызывается сразу при выходе из scope/удалении объекта (как в С++), или когда-нибудь в будущем, когда у сборщика до него дойдут руки (как финализаторы в Java/C#)?
О, это хороший вопрос и отличное напоминание о том, что стоит бы потереть устаревшую документацию на офф. сайте.

Основной предлагаемый способ RAII шаблон scoped!T: dlang.org/phobos/std_typecons.html#scoped
Создаёт экземпляр класса на стеке, запрещает любое его присваивание, при выходе из scope вызывается деструктор, а состояние объекта вырождается в T.init. Реализовано через структуру с полем аналогичного классу размера, alias this и emplace.

Не вполне RAII по букве, но решает ту же задачу — scope(exit) / scope(success) / scope(failure). Формата:
lock(mutex);
scope(exit) unlock(mutex);
// code here


Когда-то предполагалось использовать для этих целей специальные scope классы, которые имеют специальные правила по аллокации. И спеки ещё можно найти на сайте, и оно ещё работает. Но считается deprecated из-за небезопасного диазайна и оттого не упоминается в TDPL.

По хорошему, надо пройтись по репозиторию с доками офф. сайта и вычистить всё это. Я даже собирался заняться, но это как минимум пара дней нуднейшей вычитки спеков и пока не собрался: )
спасибо. а если объект не на стеке, а в куче? или data member другого объекта? решение будет таким же?
Тогда согласно приведённой вами цитате из TDPL. Если это управляемая GC куча. Если память была выделена через malloc & Co — то как в plain C, только руками.
просто раз D позиционируется как полноценная замена С++, то я не понимаю, зачем нужно было отказываться от детерминированных деструкторов :(
а есть еще какие-нибудь области С++ (как языка), кроме хитрых шаблонов, в аналоге которых в D придется делать костыли?
Судя по моему опыту, как раз хитрые шаблоны в D сделаны на славу, и это скорее в C++ будут аналоги смотреться костыльно :)
Модель памяти уровня языка в D сложнее, оттого несколько другие задачи при дизайне. Деструкторы детерменированны, время жизни объекта под контролем сборщика мусора — нет. Деструкторы стэковых объектов ( структуры, например) вызываются при выходе из области видимости гарантированно. Точно так же возможно явно использовать destroy для вызова деструктора, но детерменированно освободить принадлежащую gc память — нет.

Про костыли сказать не могу, т.к. мне это не кажется костылём, но плохо задокументированной частью языка, которая требует переосмысления подхода к дизайну :) Я затрудняюсь придумать хоть одну фичу С++, аналогия которой в D будет выглядеть костыльнее.
А вообще из неожиданностей — у структур не может быть конструктора по умолчанию, const/immutable/shared — транзитивны, глобальные переменные thread-local по умолчанию.

Выпад в сторону шаблонов не понял, т.к. при переходе это скорее «убрать костыли на С++ и написать нормально на D».
ясно, спасибо.
«костыли» не относились к «шаблонам», просто я неудачно сформулировал =\
При использовании Scoped финализатор вызывается сразу по выходу из области видимости, но память не освобождается сразу а освободится когда-нибудь GC.
Вы можете сравнить сборщик мусора в D со сборщиком мусора в .NET? Поддерживается ли сборка по поколениям, есть ли фоновая сборка? Насколько GC хорош для серверных приложений?
Легко, сборщик мусора в D — не очень: ) Он основан на Hans Boehm’s C++ Garbage Collector и находится в состоянии «работает, ничего не портит, вот и славно». Недавно в компилятор была добавлена поддержка для precise garbage collection и вообще простая возможность менять стандартный компилятор на свой. В рамках последнего Google Summer of Code пресловутый precise gc был написан, но мне ничего не известно ни о планах по замене текущего на новый, ни о бенчмарках.

С .NET и JVM тут очень трудно конкурировать если играть по тем же правилам. Модуль, отвечающий за управление GC: dlang.org/phobos/core_memory.html

Но насчёт серверных приложений — использование gc ничуть не мешает vibe.d ( vibed.org ) смешивать всех с грязью в плане производительности, так что аделкое от совершенства качество сборщика мусора отчасти компенсируется возможностями языка по управлению моделью памяти.
только сейчас заметил: не «менять стандартный компилятор» а «менять стандартный сборщик» конечно же
vibe.d приятно удивила. Посмотрел минут 15 примеры кода, напомнило замечательный фреймворк Play! в Java/Scala. С такими инструментами D может продвинуться в массы из-за пригодности к веб-деву.
Написал был в свое время под D1 harmonia GUI framework.

Из проблем которые были в то время:
1. D1 менялся радикально с каждым билдом, т.е. каждую неделю. Очень тяжело было shooting moving target.
2. Не ясен был принцип D.dll — т.е. создания компонент на D коде в DLL для non-D consumers. Единственынный способ «компонентизации» в D это компоненты в исходных текстах (т.е. статическая компиляция).

Вообще D хорош для «лохматых» проектов когда разумную политику владения (кто что создает а кто освобождает) трудно описать. Но приходится все хозяйство писать на D. С код (и DLL с plain C интерфейсами) можно ипользовать, но завимодействие с С++ и его new/delete уже известная проблема.

Ого, это же целую вечность назад, я тогда ещё и слышать не слышал ни про какие D :) С тех пор многое поменялось, даже в D2 нет таких частых релизов, а уж обратную совместимость ломают только в совсем отчаянных случаях :)

DLL и сейчас является проблемной областью, но, в основном, из-за невозможности нормальной динамической линковки druntime и phobos, больно уж жирновато выходит. А вот насчёт взаимодействия с С++ — я как-то даже не знаю, даже С++ программы между собой общаются через plain C интерфейсы обычно. Отсутствие стандартного ABI + шаблоны = то ещё удовольствие.
Скажите, а вы используете D в продакшене? Или это просто, условно говоря, хобби? Любопытно.
Ох, мне в продакшене даже о С++ приходится только мечтать :) Или хоть о компиляторе С посвежее…
Основной язык для личных экспериментов в свободное от работы время, наверное, это можно назвать хобби, да.
Периодически смотрю на D, но есть тяжелый груз — своя библиотека математики на C++, которая по разным причинам содержит еще и собственные контейнеры и прочую лабуду. С точки зрения ентерпрайз-программирования все проекты довольно маленькие, но очень специфичные (электронная микроскопия, томография, эндоскопия, потоковое аудиораспознавание) и удельная стоимость строчки кода (условно говоря) очень высокая. Все внешние интерфейсы на чистом ANSI-C, даже если с другой стороны GUI, также написанное на C++. Сейчас появились ресурсы, позволяющие стартовать пару новых проектов на D. Из библиотеки я бы перетаскивал по мере необходимости только нужное в данный момент. Насколько это самоубийственно по Вашему мнению?

Upd. Да, забыл сказать, еще и система сборки проектов собственной разработки, слегка похожий на jam. И еще самодельная интеграция с lua, но с этим проблем быть не должно.
С удовольствием могу сказать, что ваша ситуация обещает наименьшее количество проблем :) Как минимум, мне известно успешное использование D в области биоинформатики, что выглядит как тема, похожая по подборке инструментов. Если интерфейсы на чистом ANSI-C, то из библиотеки перетаскивать ничего не потребуется, можно использовать её напрямую. Проблема может возникнуть только с этим: d.puremagic.com/issues/show_bug.cgi?id=5570. Если нацелены на x64 системы, я бы подождал, пока этот баг не закроют.

Система сборки не важна, у D нет «православной» системы сборки.

Если интересуют какие-то конкретные вопросы — буду рад помочь, дам адрес электронной почты по пингу в личку.
Да, мне тоже кажется, что не должно быть особых проблем.

Под интерфейсами я понимал интерфейсы с клиентской частью софта — той частью, которая нас использует. Библиотека же линкуется статически, так что перетаскивать код из нее все же придется.

На 64-битные системы только начинаем переориентироваться, в основном в связи с новым проектом высоконагруженного сервиса потокового аудиораспознавания.

А как там с вещественной арифметикой в ее самых грязных проявлениях? Имеется в виду такая ужасная вещь как people.sc.fsu.edu/~jburkardt/c_src/paranoia/paranoia.html :)
Имеется в виду, что если API библиотеки объявлено как extern «C», то можно её линковать напрямую с программами на D, он понимает C ABI. Если C++ — тоже можно, но чревато большей головной болью.

Вещественная арифметика:
dlang.org/d-floating-point.html
dlang.org/phobos/std_numeric.html
dlang.org/phobos/std_math.html
Я не очень силён в этой теме, так что, думаю, вам эти ссылки скажут больше, чем мой пересказ.
Скажите, а по каким ресурсам вы D изучали?
Может, есть какая-нибудь свежая книжка? А то в издании 2010го года первый же пример отказывается собираться без допиливания.
Я совсем недавно начал его щупать, сейчас пробую всякие простейшие возможности языка и фобоса, так приходится иногда в исходники залезать.
1) TDPL от Александреску. Там могу быть проблемы со сборкой примеров, особенно в старом издании, но это основной источник представления о _намерениях_ авторов языка.
2) официальные доки с dlang.org — для рутинной разибрательства «баг компилятора или я не очень?»
3) forum.dlang.org/group/digitalmars.D.learn и stackoverflow.com если ничего не помогает

Примерно на 2/3 переведена с турецкого отличная книга ddili.org/ders/d.en/index.html — если TDPL больше рассуждения и дизайн-решениях, то Ali Çehreli написал именно подробное руководство для новичков.

Мне было проще, т.к. я внимательно изучал содержимое forum.dlang.org в течение года-полутора до того, как реально что-то начал писать, там часто бывают очень познавательные дискуссии :)
Спасибо!
1) У TDPL старое издание — это какое. Я вообще только одно нашёл (за 2010 год). Хотел купить, но сначала скачал с торрентов и упёрся в такое вот положение дел с примерами :( Решил подождать пока.
2) Кстати, а баги сейчас часто встречаются? А то я с промежутком в несколько дней наткнулся сначала на неработающий поиск Бойера-Мура, а потом на то, что commonPrefix для строк отдаёт результат, обрубленный посреди кодюнита. Вот и думаю, то ли лыжи не едут, то ли я чего-то не понимаю, то ли std.algorithm заброшен сейчас в дальний угол.

Турецкую книжку посмотрю обязательно, благодарю :)
У меня тоже 2010 года, возможно именно переизданий не было, но errata точно есть: erdani.com/tdpl/errata/

Баги встречаются довольно редко в пределах «idiomatic D», и довольно часто — если начинать экспериментировать :) dlang.org/bugstats.php как бы намекает. std.algorithm как раз в очень хорошем состоянии по моим ощущениям, пришлите тест кейсы личкой — разберусь, в чём дело.
За еррату спасибо, посмотрю.
Про баги в личку написал.
Раз уж пошла такая тема: попробовал сегодня портировать один сишный хедер на D, все прошло нормально, кроме одной закавыки.
Есть там одна структура с виртуальными функциями вида:
struct CServerInterface
  {
   virtual int             __stdcall Version(void);
   virtual time_t      __stdcall TradeTime(void);
...
};

Судя по докам, struct нужно заменить на interface, поменял(иначе не компилируется, исходников этих функций у меня нету).
Как ни пытался комбинировать extern(C, C++, Windows), никак не получилось заставить это работать:
после того, как получаю указатель на CServerInterface, я пытаюсь вызвать Version(), но падаю с ошибкой:
First-chance exception at 0x33560004 in mtsrv.dev.exe: 0xC0000005: 0xC0000005.
Всё это происходит в dll-ке.

А так давно хотел попробовать, после того, как прочитал на русском призывы и доводы Александреску(не помню как называлась та статья).
Она и на хабре есть, я участвовал в её переводе :)

По теме: я никогда не пробовал интерфейс напрямую с С++ и никому не советую, даже если формально оно поддерживается :) Отсутствие стандартного ABI чревато проблемами в дальнейшем. А в plain C struct остаётся struct.

Если можете подсократить код до минимально проблемного — вышлите личкой, посмотрю.
Спасибо за перевод! Меня вы зажгли =) Получится портировать — заинтересую коллег по работе и попробую в продакшене на простых вещах.
В целом вроде(пока с проблемами не сталкивался) получилось заставить работать программу.
Сделал как написано здесь dlang.org/cpp_interface.html, хотя удивился — вроде передаем указатель на CServerInterface, а принимаем по значению, и все работает:
//изначально было так:
//int  __stdcall        MtSrvStartup(CServerInterface *server);
export extern (Windows)
int MtSrvStartup(CServerInterface server)
{
//здесь уже можно обращаться к server
...
}

Сам интерфейс объявил таки вот так:
extern(C++){
interface CServerInterface
  {
   extern (Windows){
	   int         Version();
	   time_t      TradeTime();
           //остальные функции интерфейса
          ...
    }
  }
}
Классы в D — исключительно полиморфные ссылочные типы, в отличие от структур. Они никогда не передаются по значению. CServerInterface всегда будет неявным указателем.

Вообще если с такими сигнатурами и без дополнительных хаков завелось — могу только порадоваться и позавидовать, как разработчик под Linux :) Тут всё куда интереснее, банальным extern©/extern(C++) динамическую либу не завести.

Да, как у же упоминал в личке, у портирования под dll есть своя специфика, описанная тут: dlang.org/dll.html. Опять же, сам не проверял, ибо Windows.
Скорее всего из-за того, что это виртуальные методы. Баг ли, должен D такое уметь?

Решение обычное: обернуть вызовы этих методов в сишные (cdecl) функции.
Sign up to leave a comment.

Articles