В настоящее время у системных программистов практически нет выбора какой язык использовать. По хорошему все варианты сводятся или к чистому Си или к Rust, хотя как показывает опыт далеко не всем нравится его синтаксис.

Благодаря усилиями команды разработчиков языка у D теперь появилось совместимое с чистым Си подмножество обладающее не только привычным для любого программиста Си синтаксисом, но и значительно расширяющее функционал языка. Новое подмножество называется «betterC». Это подмножество позволяет перевести написание Си приложение на новый уровень.

Вот краткий список того, что позволяет режим betterC программисту:

1. Отсутствие препроцессора
2. Более высокая скорость компиляции
3. Полноценная модульность
3.1 Поддержка различных видов импорта (статический импорт, частичный импорт, ренейминг при импорте и тд)
4. В момент компиляции возможна: генерация кода, интроспекция, проверка различных условий
4.1 Ветвление на этапе компиляции через static if и static foreach
4.2 возможны работа блоков вида version(linux) { ... }
5. Шаблоны
6. Аналог borrow checking из Rust через scope pointers (scope T*), scope slices (scope T[]) и scope references (scope ref T)
7. Поддержка модификаторов доступа const и immutable подробнее
8. TLS по умолчанию
9. Поддержка контрактного программирования
10. Удобные массивы с поддержкой слайсинга
11. Ускорение работы с массивами за счет SIMD
12. Удобные unit-тесты
13. Встроенный профайлер
14. User-defined атрибуты
15. Встроенный и очень удобный генератор документации
16. Привычный каждому программисту Си синтаксис
17. Поддержка Unicode
18. Лучшая чем у C memory safety
19. Замыкания
20. Многое другое.

Давайте теперь рассмотрим примеры.

Следующий код на C:

#include <stdio.h>

int main(int argc, char** argv) {
    printf("hello world\n");
    return 0;
}

Будет скомпилирован в:

_main:
push EAX
mov [ESP],offset FLAT:_DATA
call near ptr _printf
xor EAX,EAX
pop ECX
ret

Размер на выходе: 23,068 bytes.

Теперь тоже самое на D в режиме betterC:

import core.stdc.stdio;

extern (C) int main(int argc, char** argv) {
    printf("hello world\n");
    return 0;
}

Размер на выходе: 23,068 bytes.

Не плохо правда ли? Тот же самый код без режиме betterC будет весить 194Kb.

Более сложный пример:

C версия:

#include <stdio.h>

/* Eratosthenes Sieve prime number calculation. */

#define true    1
#define false   0
#define size    8190
#define sizepl  8191

char flags[sizepl];

int main() {
    int i, prime, k, count, iter;

    printf ("10 iterations\n");
    for (iter = 1; iter <= 10; iter++) {
        count = 0;
        for (i = 0; i <= size; i++)
            flags[i] = true;
        for (i = 0; i <= size; i++) {
            if (flags[i]) {
                prime = i + i + 3;
                k = i + prime;
                while (k <= size) {
                    flags[k] = false;
                    k += prime;
                }
                count += 1;
            }
        }
    }
    printf ("\n%d primes", count);
    return 0;
}

BetterC версия на D:

import core.stdc.stdio;

extern (C): // указываем что надо использовать соглашение о вызове в стиле C

__gshared bool[8191] flags;

int main() {
    int count;

    printf("10 iterations\n");
    foreach (iter; 1 .. 11) {
        count = 0;
        flags[] = true;
        foreach (i; 0 .. flags.length) {
            if (flags[i]) {
                const prime = i + i + 3; // const - значение никогда не будет меняться после инициализации
                auto k = i + prime;
                while (k < flags.length) {
                    flags[k] = false;
                    k += prime;
                }
                count += 1;
            }
        }
    }
    printf("%d primes\n", count);
    return 0;
}

Получилось куда более читабельно и коротко.

Для инициализации пустого проекта вызовите: dub init

Для включения данного режима в dub.sdl необходимо добавить строку:

dflags "-betterC"
Для dub.json строка будет:
"dflags" : ["betterC"],

Требуется версия компилятора dmd 2.076 и старше.

Для начинающих программистов опубликована первая версия русского учебника по языку D.

Так же вышло новое расширение с поддержкой языка для Visual Code.

Комментарии (140)


  1. begemot_sun
    25.08.2017 15:04
    +20

    Какае-то хрень, говорить что он похож синтаксисом на C. Какая разница на что он похож синтаксисом?
    Либо ты поддерживаешь синтаксис С, и таким образом тонны С-кода компилируются и исполняются как надо. Либо ты говоришь что я убрал эти С-родовые травмы, и теперь мой язык D-верх совершенства.
    А то что, что-то на что-то другое похоже. Да какая вообще разница? эти синтаксисы учаться за 2-4 недели, а дальше ты лобаешь код с той же скоростью. Или ты нанимаешь 100500 девелоперов betterC-режима, и они тебе лабают код с той же скоростью.
    Лучше описали бы, плюсы и минусы этого синтаксиса.
    И да, я не увидел паттерн-матчинг. Так сразу вопрос, доколе? :)


    1. beduin01 Автор
      25.08.2017 15:12

      Чем проще синтаксис, тем меньше шансов сделать ошибку. Да и вообще код проще понимается.


      1. begemot_sun
        25.08.2017 15:24
        +13

        Ответ неверен. Синтаксис асемблера проще некуда, вот только ошибки там не отлавливаются в прицнипе.
        Язык это такая клетка для программиста.
        С одной стороны он должен позволять выразить максимум.
        С другой стороны он должег позволять выразить это одним единственным способом.
        Требования противоречивы.

        Про паттерн матчинг мой вопрос был в том, что это очень полезная штука которая из коробки должна быть в языке. Когда её нет, то твой код вместо линейного становится разветвленным, а это очень такая хорошая причина для всяких ошибок.


        1. beduin01 Автор
          25.08.2017 15:28
          -10

          Вы сами себе противоречите.


          1. begemot_sun
            25.08.2017 15:30
            -2

            ЧТо? ГдЕ?


        1. johnfound
          25.08.2017 19:30
          -3

          Ответ неверен. Синтаксис асемблера проще некуда, вот только ошибки там не отлавливаются в прицнипе.

          Отлавливаются и еще как! Посмотрите например как исчезают ошибки в FASM, когда их находят. Буквально за 2..3 часа. В моих проектов на ассемблере, тоже никогда не были проблемы с отловом ошибок.


          1. johnfound
            25.08.2017 21:06
            -2

            Вот пример: https://board.flatassembler.net/topic.php?t=19985


            Баг репорт: 20:41
            Автор прочитал репорт: 22:32
            Исправленная версия: 22:37


            1. Optik
              26.08.2017 10:19

              И где тут время отлова ошибки?


              1. johnfound
                26.08.2017 10:35
                +2

                В 22:32 Томаш написал "попробуйте то то, чтобы мне легче было", то есть он в тот момент не знает как исправить бага, а в 22:37 пишет:


                Anyway, I gave it a shot. Please try with 1.71.63 and see if the produced files are correct.

                Тоесть он в эти 5 минут, открыл сорс, исправил ошибку, перекомпилировал все и загрузил на сайт новую исправленную версию. Чем не отлов ошибки?


                1. Optik
                  26.08.2017 20:55
                  +2

                  Это исправление известного бага. Сколько времени прошло с момента зарождения ошибки до её обнаружения неизвестно, и уж сильно вряд ли 5 минут. Исходная реплика была о том, что отсутствуют инструменты для превентивного поиска ошибок.


                  1. johnfound
                    26.08.2017 22:18
                    -1

                    И какие такие "превентивные инструменты" есть в других языках. Дайте пример, а то совершенно непонятно. По моему баги всегда впервые проявляются, а потом исправляются. И никак иначе.


                    Кстати, перечитал, о "превентивного поиска" не нашел:


                    Синтаксис асемблера проще некуда, вот только ошибки там не отлавливаются в прицнипе.


                    1. apro
                      26.08.2017 23:26
                      +3

                      И какие такие "превентивные инструменты" есть в других языках

                      По сравнению с ассемблером в языках типа C/Rust/D есть типизация,
                      которая на этапе компиляции позволяет предотвратить запись скажем целого числа на место числа с плавающей запятой. Я думаю имелось это ввиду.


                      1. johnfound
                        26.08.2017 23:37
                        -2

                        Там эти ограничения нужны, потому что, уровень абстракции таков, что все делается одинаково. Например то же присвоение, всегда через оператор "=".
                        В ассемблере, такую ошибку, кроме как намеренно, совершить нереально. По крайней мере, мне не встречалась никогда.


      1. rraderio
        25.08.2017 16:23
        +4

        А у D точно проще синтаксис?


      1. AnutaU
        25.08.2017 17:48
        +6

        Самый простой синтаксис у Лиспа. И его же постоянно обвиняют в плохой читаемости.


        1. danfe
          25.08.2017 18:20

          Это потому, что у лиспов, по сути, нет синтаксиса. Достаточно простой и при этом читаемый синтаксис, например, у ML-языков.


          1. AnutaU
            25.08.2017 18:27
            +1

            Он тривиальный, но я бы не сказала, что его вообще нет.


            1. danfe
              25.08.2017 19:45

              Он даже не тривиальный, он как бы вырожденный (я поэтому сказал, что «по сути») — это практически готовое AST-дерево, в более-менее человеко-читаемом виде.


          1. grossws
            25.08.2017 21:56

            При этом, судя по опросу выше не все любят ML-подобный синтаксис Rust'а (правда, ещё с ощутимой примесью угловых скобок в шаблонах).


            1. danfe
              25.08.2017 22:10

              Справедливости ради, когда-то он был намного более подобным (и более приятным на мой вкус); я как-то уже писал об этом:

              [...] раст [для многих] выглядит [всё более] привлекательным именно за счет того, за что его ругают функциональщики — если на первых порах он был скорее больше похож на «ML с плюсами», то сейчас всё чаще говорят о «C++ done the right way». Спорить с этим тяжело, ибо история показывает, что императивно-ориентированный синтаксис — очень сильный буст к популярности. (Тут уместно вспомнить ремарки о чутье Гвидо по поводу того, как должен выглядеть питон.)


            1. TargetSan
              25.08.2017 22:35

              Назвать синтаксис Rust ML-подобным это довольно оригинально. Если сравнивать с хаскеллем и С++, он больше всего похож именно на плюсы — двойные двоеточия, фигурные скобочки, угловые скобки шаблонов и т.п. Наличие же let и указания типа после имени отнюдь не делает язык ML-подобным, как по мне.


              1. danfe
                25.08.2017 22:48
                +1

                Сперва он действительно был таким (вообще, до того, как раст стал self-hosted, его компилятор был написан на окамле), но с течением времени стал куда больше похож на C++ чем на ML (собственно, чуть выше я об этом и пишу).


                1. Wedmer
                  25.08.2017 22:50
                  +1

                  Просто не все наблюдали Rust с момента рождения.


                  1. Vjatcheslav3345
                    26.08.2017 09:29
                    -3

                    Просто не все наблюдали Rust с момента рождения.

                    Вот как то не очевидно сравнить поклонников языка с консилиумом педиатров, наблюдающими за языком с роддома и искренне интерсующимися его анализами "на кровь, кал, мочу" и прививками...:)
                    Интересно — фанаты обидятся или обрадуются?


              1. grossws
                26.08.2017 01:17

                Как уже написали выше, до 1.0 он был более ml-подобным по синтаксису и erlang-подобным в смысле семантики. Сейчас от вещей, роднящих с ml'ами всякие let, вывод типов, match.


                Но меня получившийся результат вполне радует. Правда, я на синтаксис смотрю во вторую очередь. Разве что экстремальные варианты типа pascal/ada/modula-подобности не очень приемлемы: он бы стал слишком громоздким ради нужной семантики. Или, наоборот, apl/j/k-подобность сильно повышает плотность информации до уровня неудобоваримости.


  1. lpwaterhouse
    25.08.2017 15:04
    +19

    Уже 16 лет мучаются, а он так никому и не нужен.


    1. guai
      29.08.2017 10:18
      -1

      за «никого» не надо говорить.
      мне нужен, отличный язык, а альтернативы — или древние сишка с плюсами, в которых чуть ли не каждая изначальная фича успела стать deprecated, или наркоманский руст.


      1. lega
        29.08.2017 10:54

        а альтернативы — или древние сишка с плюсами, в которых чуть ли не каждая изначальная фича успела стать deprecated, или наркоманский руст.
        Nim, Crystal, Julia?


        1. guai
          29.08.2017 11:18

          ну юльку может доведут до ума для матетатики когда-нибудь…


      1. 0xd34df00d
        29.08.2017 22:32

        Альтернативы по каким критериям? Близость к железу? Императивный язык с сиподобным синтаксисом? Скорость разработки?


  1. kez
    25.08.2017 15:41
    +6

    Эта вольный перевод статьи D is a Better C, но нужно было хотя бы перевести её полностью, там описаны некоторые важные тонкости.


    1. VadimVP
      25.08.2017 18:32
      +3

      К слову о важных тонкостях, там "as" а не "is" в заголовке.


      1. kez
        25.08.2017 18:37

        Согласен, забавно получилось (когда заметил, уже нельзя было редактировать). Спасибо :)


  1. rogoz
    25.08.2017 15:43
    +7

    Да это же D--.


  1. egordeev
    25.08.2017 15:47
    +5

    По хорошему, все статьи по поводу языка программирования D напоминают пропаганду! В который раз в этом убеждаюсь!)))) О том, что D — это убийца C++, D — это убийца Rust, D — это убийца C, D — это убийца Go, и т.д. и т.п. Постоянно… сплошное навязывание мнения, что D — лучший язык программирования, но что-то я в этом сомневаюсь.


    1. geekmetwice
      25.08.2017 18:58

      Вы читаете готовые выводы, даже не пытаясь пройти по их логической цепочке. Возьмите ВВЕДЕНИЕ в язык и прочитайте, там обязательно будут отсылки «чем это лучше Си». Тогда все выкрики с задних рядов «ясамниваюсь» уйдут в никуда.
      И да, Ди — это лучшее продолжение Си-подобных языков.


      1. egordeev
        25.08.2017 19:21
        +2

        Вы читаете готовые выводы

        откуда у вас такие выводы?
        Возьмите ВВЕДЕНИЕ в язык и прочитайте

        почему вы мне указываете, что я должен прочитать?
        Тогда все выкрики с задних рядов «ясамниваюсь» уйдут в никуда.

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

        в этом я тоже сомневаюсь.


        1. beduin01 Автор
          25.08.2017 21:11
          -1

          >почему вы мне указываете, что я должен прочитать?
          http://dlang.ru/faq


      1. yarric
        25.08.2017 19:34
        +2

        Замена C со сборкой мусора? Не думаю!


        1. Wedmer
          25.08.2017 19:56

          Most obviously, the garbage collector is removed, along with the features that depend on the garbage collector. Memory can still be allocated the same way as in C – using malloc() or some custom allocator.


          Как то так


          1. grossws
            25.08.2017 21:58
            +2

            Ага, и минус exceptions, strings и большая часть стандартной библиотеки. Хотя libc останется доступна, да.


          1. yarric
            25.08.2017 22:06

            А в C++ при этом есть RAII и все библиотеки работают и доступны.


            1. Wedmer
              25.08.2017 22:32

              Вообще то тут разговор про C и D в режиме betterC.
              В чистом C тоже нет RAII.
              В будущем ничто не мешает адаптировать часть библиотек под этот режим.


              1. DmitryMry
                26.08.2017 17:05
                +1

                Комментарий Уолтера Брайта:

                RAII in D currently has a soft dependency on the GC. A fix for this is in the works, and then RAII will be available for D as better C.


              1. monah_tuk
                28.08.2017 10:17

                В чистом C тоже нет RAII.
                Согласен. Но оно вполне реализуемо, даже в рамках современных компиляторов. Взять для примера GCC: __attribute__((cleanup (...))). Думаю, что в VS, clang что-то подобное тоже может быть. Это не призыв использовать, просто констатация: было бы желание, а реализовать, не ломая язык, вполне возможно.


                1. Wedmer
                  28.08.2017 19:46

                  Нельзя привязывать возможности конкретных компиляторов к стандарту. Выше отписали, что как отвяжут RAII от GC, так он появится для нового режима.


                  1. monah_tuk
                    28.08.2017 23:52

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


                    По поводу привязки конкретных возможностей компиляторов. По сути, это поведение может выступать как Proof of Concept при рассмотрении следующего стандарта.


                    1. Wedmer
                      29.08.2017 00:39

                      IAR тоже многое не по стандарту дает делать. Я не думаю, что это многое войдет в стандарт.
                      GCC позволяет такое впихивать за счет своего бэкенда, как и clang.


          1. TargetSan
            25.08.2017 22:40
            +1

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


            Кстати, вопрос к знающим Ди. А как там теперь с обработкой ошибок, после того как выкинули на мороз исключения? Потому что C-style коды ошибок и libc в голом виде низводят бОльшую часть преимуществ в ноль.


            1. vintage
              25.08.2017 22:44

              1. TargetSan
                25.08.2017 23:45
                +1

                Тут более каверзный вопрос — а как у stdlib с error handling через него?
                И есть ли сахар "unpack-or-return"?


                1. vintage
                  26.08.2017 00:09

                  Да никак, нужно обёртки писать.


                  1. TargetSan
                    26.08.2017 21:15

                    Это крайне печально.
                    К тому же, я подозреваю, Phobos завязан на исключения. А значит, перевести его на variant-совместимый подход — переписать хорошим куском. Либо руками обёртки над libc. Пока напрашивается вывод — в betterC фактически нет стандартной библиотеки.


                    1. vintage
                      27.08.2017 00:53

                      Ну, эти обёртки написать — довольно тривиальная задача. Я тут не вижу особой проблемы. Особенно в сравнении с собственно С.


  1. Daniil1979
    25.08.2017 16:08

    Хм… Хренею я с обоих языков. На одном языке вывод одной единственной строчки текста — 23Кб, на другом — 194 Кб. Да Вы зажрались!!!
    Надо будет qBasic с компилятором найти на старых дисках и посмотреть, сколько у него готовая прога займёт.
    А потом вспомнить, как это делается на ассемблере. :-)


    1. lorc
      25.08.2017 17:07
      +1

      Интересно чем они собирали. У меня hello world собранный GCC5.4.0 занимает 8 килобайт. Стрипнутый — 6 килобайт. В основном — секции с метаданными и информацией для динамической линковки.

      В секциях кода — в основном инициализация/деинициализация libc.
      Короче, ничего такого страшного. Можно выкинуть всё и дернуть write() руками. Но зачем?

      objdump -x для тех, кому интересно
      Sections:
      Idx Name Size VMA LMA File off Algn
      0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      2 .note.gnu.build-id 00000024 0000000000400274 0000000000400274 00000274 2**2
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      3 .gnu.hash 0000001c 0000000000400298 0000000000400298 00000298 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      4 .dynsym 00000060 00000000004002b8 00000000004002b8 000002b8 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      5 .dynstr 0000003d 0000000000400318 0000000000400318 00000318 2**0
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      6 .gnu.version 00000008 0000000000400356 0000000000400356 00000356 2**1
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      7 .gnu.version_r 00000020 0000000000400360 0000000000400360 00000360 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      8 .rela.dyn 00000018 0000000000400380 0000000000400380 00000380 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      9 .rela.plt 00000030 0000000000400398 0000000000400398 00000398 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      10 .init 0000001a 00000000004003c8 00000000004003c8 000003c8 2**2
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      11 .plt 00000030 00000000004003f0 00000000004003f0 000003f0 2**4
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      12 .plt.got 00000008 0000000000400420 0000000000400420 00000420 2**3
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      13 .text 00000192 0000000000400430 0000000000400430 00000430 2**4
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      14 .fini 00000009 00000000004005c4 00000000004005c4 000005c4 2**2
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      15 .rodata 00000010 00000000004005d0 00000000004005d0 000005d0 2**2
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      16 .eh_frame_hdr 00000034 00000000004005e0 00000000004005e0 000005e0 2**2
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      17 .eh_frame 000000f4 0000000000400618 0000000000400618 00000618 2**3
      CONTENTS, ALLOC, LOAD, READONLY, DATA
      18 .init_array 00000008 0000000000600e10 0000000000600e10 00000e10 2**3
      CONTENTS, ALLOC, LOAD, DATA
      19 .fini_array 00000008 0000000000600e18 0000000000600e18 00000e18 2**3
      CONTENTS, ALLOC, LOAD, DATA
      20 .jcr 00000008 0000000000600e20 0000000000600e20 00000e20 2**3
      CONTENTS, ALLOC, LOAD, DATA
      21 .dynamic 000001d0 0000000000600e28 0000000000600e28 00000e28 2**3
      CONTENTS, ALLOC, LOAD, DATA
      22 .got 00000008 0000000000600ff8 0000000000600ff8 00000ff8 2**3
      CONTENTS, ALLOC, LOAD, DATA
      23 .got.plt 00000028 0000000000601000 0000000000601000 00001000 2**3
      CONTENTS, ALLOC, LOAD, DATA
      24 .data 00000010 0000000000601028 0000000000601028 00001028 2**3
      CONTENTS, ALLOC, LOAD, DATA
      25 .bss 00000008 0000000000601038 0000000000601038 00001038 2**0
      ALLOC
      26 .comment 00000034 0000000000000000 0000000000000000 00001038 2**0
      CONTENTS, READONLY
      SYMBOL TABLE:
      no symbols



      1. Wedmer
        25.08.2017 21:45

        Похоже компилировали этим. Как эта фича будет реализована в GDC, тогда можно будет честно сверять.


    1. Wedmer
      25.08.2017 21:47

      В статье пишется, что оба варианта привета транслируются в одинаковый бинарный код.
      Но если отключить новую фичу — получается 194кб. Да, и дело то не в языках, а компиляторах.


  1. TargetSan
    25.08.2017 16:14
    +1

    В оригинальной статье был ещё небольшой раздельчик, что выкинули. В частности:


    • RAII
    • Полиморфные классы (а значит, весь полиморфизм будет ручками на указателях)

    Вопрос — зачем он теперь такой нужен?


    1. vintage
      25.08.2017 21:20

      Некоторый полиморфизм в D есть и у структур:


      import std.stdio;
      
      void sayA( A a ) {
          writeln( "a = " , a );
      }
      
      void sayB( B b ) {
          writeln( "b = " , b );
      }
      
      struct A {
          int a = 1;
      }
      
      struct B {
          A a = A(2);
          alias a this;
      
          int b = 3;
      }
      
      void main(){
          A().sayA; // a = A(1)
          B().sayA; // a = A(2)
          B().sayB; // b = B(A(2), 3)
      }


      1. TargetSan
        25.08.2017 22:20

        Я вас огорчу, это не полиморфизм. Это, по сути:


        struct A {
            int a = 1;
        };
        
        struct B: public A {
            B()
            {
                a = 2;
            }
        
            b = 3;
        };
        
        void sayA(A const& a)
        {
            std::cout << "a = " << a.a << "\n";
        }
        
        void sayB(B const& b)
        {
            std::cout
                << "a = " << b.a << "\nb = " << b.b << "\n";
        }
        
        int main(int, char**)
        {
            sayA(A()); // a = 1
            sayA(B()); // a = 2
            sayB(B()); // a = 2 b = 3
        }


        1. vintage
          25.08.2017 22:39

          Интересно, что же вы такое вкладываете в понятие полиморфизма?


          1. TargetSan
            25.08.2017 22:55
            +2

            Эмм… оперирование разнородными типами через некий единый интерфейс?


            trait WhoAmI {
              fn say(&self);
            }
            
            struct Cat;
            struct Dog;
            
            impl WhoAmI for Cat {
              fn say(&self) { println!("I'm a cat! I say Meow!"); }
            }
            
            impl WhoAmI for Dog {
              fn say(&self) { println!("I'm a dog! I say Woof!"); }
            }
            
            fn identify_one<T: WhoAmI>(someone: &T) {
              someone.say();
            }
            
            fn main() {
              identify_one(Cat); // cat's phrase
              identify_one(Dog); // dog's phrase
            }

            То, что вы показали — по сути использование объекта-потомка вместо объекта-предка. Только в Ди реализованное через алиасинг. Вот если бы у вас


                B().sayA; // a = B(A(2), 3)

            это был бы полиморфизм


            1. Wedmer
              25.08.2017 22:57
              -3

              Тогда вы должны просто обожать PHP.


              1. TargetSan
                25.08.2017 23:51
                +2

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


                1. Wedmer
                  26.08.2017 00:23
                  +2

                  Да ладно?
                  Освежите ваши знания для начала)

                  • Ad hoc polymorphism: when a function denotes different and potentially heterogeneous implementations depending on a limited range of individually specified types and combinations. Ad hoc polymorphism is supported in many languages using function overloading.
                  • Parametric polymorphism: when code is written without mention of any specific type and thus can be used transparently with any number of new types. In the object-oriented programming community, this is often known as generics or generic programming. In the functional programming community, this is often shortened to polymorphism.
                  • Subtyping (also called subtype polymorphism or inclusion polymorphism): when a name denotes instances of many different classes related by some common superclass.[3] In the object-oriented programming community, this is often referred to as simply Inheritance.



                  Также прошу не забывать, что в PHP есть функционал позволяющий делать нечто вроде перегрузки функций в классах.


            1. vintage
              26.08.2017 00:17
              +1

              Вы, пожалуйста, не выдавайте ваше личное видение полиморфизма, за общепринятое.


              Вот если бы у вас

              Да пожалуйста:


              import std.stdio;
              
              void say( A )( A a ) {
                  writeln( a );
              }
              
              struct A {
                  int a = 1;
              }
              
              struct B {
                  int b = 2;
              }
              
              void main(){
                  A().say; // A(1)
                  B().say; // B(2)
              }


    1. DmitryMry
      26.08.2017 17:10

      По крайней мере RAII будет, сейчас в работе.


  1. dlinyj
    25.08.2017 17:06

    Результаты голосования лучше говорят, чем сама статья.


    1. beduin01 Автор
      25.08.2017 17:20

      Просто 90% проголосовавших на JavaScript пишет..))


      1. Wedmer
        25.08.2017 22:16
        +1

        К примеру я пишу на плюсах.
        Переходить на D не планирую. Может быть буду использовать там, где он будет лучшим инструментом.
        Синтаксис Rust меня внешне не радует — слишком непривычно. Но при наличии свободного времени надо будет поковырять поближе, может и пойдет.


        1. grossws
          25.08.2017 22:25

          Непривычность синтаксиса — минорщина, не стоящая большого внимания. Существенные отличия в семантике и системе типов ломают мозг и производят куда больше wtf/s.


          Тот же borrow checker и lifetimes для многих является эффективно непреодолимым препятствием, хотя в си и плюсах про lifetimes тоже надо думать и держать/проверять их в голове, что куда более трудоёмко, чем поручить это компилятору.


          1. Wedmer
            25.08.2017 22:42

            У меня пока не получилось выделить какое либо время, чтобы углубиться в процесс.
            Был момент, когда что то пробовал, но с тех пор Rust уже изменился. После того как он стабилизировался, вроде как легче должно быть… но времени нет. Как будет разгрузка, так и займусь, ибо в столе лежат некоторые концепции, под которые Rust может оказаться самым подходящим инструментом.


            1. TargetSan
              25.08.2017 23:00
              +1

              Не ради саморекламы (там 300 строчек кода, плюнуть и растереть)
              https://github.com/target-san/httpdl/tree/step-by-step
              Простейший загрузчик файлов по HTTP, конкретно в той ветке что я указал он строится пошагово, в т.ч. с переходом на "идиоматичную" обработку ошибок. Пример не ахти какой, без асинхронки — но маленький, а значит понять должно быть легко.


        1. TargetSan
          25.08.2017 22:26
          +1

          Если не секрет, что именно непривычно? Я, например, в основном тоже на плюсах пишу — и Rust мне вполне даже зашёл. Очень многие вещи выглядят как раз знакомо.


          1. Wedmer
            25.08.2017 22:37

            Как все выглядит. Как я сказал, мне надо погрузиться, все пощупать, но времени пока нет. За языком слежу с момента анонса.


      1. 0xd34df00d
        29.08.2017 22:39
        +1

        Пишу на плюсах и на хаскеле.


        На плюсах пишу то, что должно работать очень быстро. С плюсов особо некуда переходить, потому что для них есть инструменты (vTune), навыки отладки и написания эффективного кода, а также более-менее знающие люди вокруг. Ну, разве что, на Rust интересно посмотреть, у него система типов хорошая и вкусная, и к железу тоже вполне себе близко.


        На хаскеле пишу то, где производительность важна чуть меньше, чем скорость разработки, корректность и стоимость внесения изменений. С него вот вообще некуда уходить, только на какие-нибудь там идрисы, но их знает ещё меньше людей.


  1. Szer
    25.08.2017 17:13
    +3

    Получилось куда более читабельно и коротко.

    По-моему, почти ничем не отличается.


    1. beduin01 Автор
      25.08.2017 17:25

      На hello-world примерах сложно увидеть разницу.


    1. kez
      25.08.2017 18:20
      +5

      Потому что в оригинальной статье речь идёт про похожесть кода («It looks much the same...»), а не о том, о чем пишет автор перевода.


      1. Cryvage
        25.08.2017 19:54
        +2

        В оригинале, автор говорит что код похож, а затем отмечает важные нюансы.

        Оригинал
        It looks much the same, but some things are worthy of note:

        • extern ( C ): means use the C calling convention.
        • D normally puts static data into thread local storage. C sticks them in global storage. __gshared accomplishes that.
        • foreach is a simpler way of doing for loops over known endpoints.
        • flags[] = true; sets all the elements in flags to true in one go.
        • Using const tells the reader that prime never changes once it is initialized.
        • The types of iter, i, prime and k are inferred, preventing inadvertent type coercion errors.
        • The number of elements in flags is given by flags.length, not some independent variable.


        And the last item leads to a very important hidden advantage: accesses to the flags array are bounds checked. No more overflow errors! We didn’t have to do anything
        in particular to get that, either.


  1. Tiendil
    25.08.2017 17:18
    +3

    D это не спасёт.


  1. degs
    25.08.2017 18:01

    iBolit# dmd -h

    -betterC omit generating some runtime information and helper functions

    Все таки хотелось бы в посте побольше информации, хотя бы столько сколько приведено в оригинальной статье.
    С книгой тоже неясно — это перевод или кто-то сам пишет? Чем она лучше чем существующие 2.5 книги?


    1. DmitryMry
      26.08.2017 19:46

      Всё-таки побольше, чем 2.5.
      А книга — да, кто-то пишет, это не перевод.


  1. chabapok
    25.08.2017 18:59
    +2

    Не….если уже в морг — то в морг.


  1. McAaron
    25.08.2017 21:12
    -2

    Этот язык в нише системного программрования. не взлетит никогда. Просто потому, что он не содержит ничего низкоуровневого из того, что есть в C. Системное программирование опирается на абстрактную ISA-архитектуру с одной стороны и конкретную с другой. Все остальное, включая семантику и управление ресурсами — лишнее. Именно поэтому в язык си не вошло ничего из того, что можно безболезненно для производительности и разумности реализовать в виде библиотек. Единственно, чего не хватает в си, так это битовых операций, типа разных сдвигов и прямого управления из языка регистрами — все вычсистемы имеют регистры и кеши. Все это сегодня работает одинаково везде, но отсутствовало тогда, когда создавался язык. Поэтому в язык не вошло. Жаль, что комитет занимается херней, типа немых индексов, вместо того, чтобы как положено распердолить сдвиги во все четыре стороны и обеспечить широкий и полный доступ к состоянию процессора на уровне языка.
    Я не прочь поиемть в языке полнофункциональные аналоги всех мыслимых с точки зрения теории jx/jnx


    1. neit_kas
      26.08.2017 10:32
      +1

      C — это первая (или не первая?) попытка реализации кроссплатформенности. Почитайте его историю. Завязка на регистры убьёт эту его особенность окончательно. И да, платформы могут очень сильно отличаться. Тот же переход не всегда делается по регистрам.


    1. mirypoko
      26.08.2017 11:05
      +1

      Простите, но разве если вам чего-то не хватает в C, разве не лучше сделать ассемблерную вставку? Можно и регистрами процессора управлять, и сдвиги какие хотите делать. Имхо на более высоком уровне абстракции (на уровне C) управление регистрами ненужно.


      1. vintage
        26.08.2017 11:19

        И тут мы приходим к довольно неплохой интеграции низкоуровневого ассемблера и выскоуровнего D: https://dlang.org/spec/iasm.html


        struct Foo   // or class
        {
            int a,b,c;
            int bar()
            {
                asm
                {
                    mov EBX, this   ;
                    mov EAX, b[EBX] ;
                }
            }
        }
        void main()
        {
            Foo f = Foo(0, 2, 0);
            assert(f.bar() == 2);
        }


        1. Gorthauer87
          26.08.2017 13:26

          А чем gcc или clang хуже? А немного макромагии и будет работать и с visual studio.


          1. Kobalt_x
            26.08.2017 14:32

            в visualstudio только в x86, в x64 никакого inline asm.


            1. Gorthauer87
              26.08.2017 17:05

              А как там драйвера пишут тогда? Оо


              1. CodeRush
                26.08.2017 17:51
                +1

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


                1. vintage
                  26.08.2017 19:05

                  В D это делают так:


                  version(A) {
                    // ...
                  }
                  version(B) {
                    // ...
                  }

                  Переключать версии можно при сборке, можно в коде.


          1. vintage
            26.08.2017 14:38

            Я не знаю, как компилятор может быть хуже языка :-)


  1. ziv
    25.08.2017 21:24
    +2

    #define true 1
    #define false 0
    char flags[sizepl];

    Язык C с версии C99 поддерживает тип bool: en.cppreference.com/w/c/types/boolean. const в C тоже есть.
    Код на C и на D практически не отличается, что должен показать этот пример — непонятно.


    1. Wedmer
      25.08.2017 22:54

      собственно разбор в комментариях вы и не заметили:
      #comment_10384058


  1. kmu1990
    26.08.2017 00:20

    Мне немного непонятно, в статье упоминается про системное программирование, но, например, нет ни слова про рантайм. Всякие SIMD и TLS требуют какой-то поддержки, как это запускать на голом железе? Какие функции нужно подложить компилятору, чтобы это взлетело? Особенно, если железо отличается от чего-то очень широко распротранненого? Я не думаю, что причина, по которой некоторые системные программисты не редко работают с C, заключается в его синтаксисе.


    1. Wedmer
      26.08.2017 00:28

      Когда эта фича перетечет в GDC, вопрос сам по себе отпадет.


      1. kmu1990
        26.08.2017 00:31

        С чего бы это? Что gcc для таких вещей вдруг не требует поддержки рантайма? Или магическим образом умеет TLS на всех платформах, для которых он может генерировать код?


        1. Wedmer
          26.08.2017 00:36

          Это значит, что все поддерживаемые архитектуры получат возможность разработки на этом сабсете. В том числе и кросскомпиляцию. И никто не помешает туда включить все расширения для создания кода под конечную платформу.


          1. kmu1990
            26.08.2017 00:46
            +1

            Под рантаймом имеются ввиду библиотеки, которые линкуются с вашей программой (и прочие вспомогательные средства), чтобы помогать компиялтору реализовывать фичи языка (такие как TLS или например код, который вызывает main с нужными argc и argv, или код которые вызывает конструкторы и деструкторы глобальных объектов и тд и тп), для которых компилятор не может просто сгенерировать код.

            Если для распространненых сочетаний архитектура/ОС вы получаете рантайм вместе с компилятором, то для менее распространенных комбинаций это не так. Никто не помешает вам реализовать эти библиотеки, но если ABI не стабилен, то никто не помешает создателям компилятора сломать ваши библиотеки и весь ваш проект вместе с ним.


            1. vintage
              26.08.2017 09:58

              Так D генерирует ABI совместимый с C при использовании extern©.


              1. kmu1990
                26.08.2017 12:35
                +1

                extern вероятно задает конвенцию вызова, а речь не только о ней, а о поддержке рантайма. Например, в статье упоминается лучшая чем у C memory_safety, я полагаю, что это включает среди прочего проверку границ массивов. Что D делает, когда проверка не проходит? Какие функции нужно ему подложить, чтобы это все собралось? Как D представляет массивы в памяти, чтобы можно было настроить передачу данных между D и каким-нибудь firmware?

                Чем больше фич язык включает тем больше таких вопросов возникает. В этом смысле сравнительно небогатый на фичи C просто не создавал таких проблем, и поэтому использовать его было довольно просто.


                1. vintage
                  26.08.2017 14:59

                  В D по умолчанию структуры выравниваются так же как в C. Массивы хранятся так же единым куском. После строк помещается нулевой байт на случай работы с ними из сишных функций. Выход за границы массива приводит к исключению.


                  1. kmu1990
                    26.08.2017 15:07
                    +1

                    Если массивы хранятся так же как в C, то откуда берется размер массива?
                    Исключения могут требовать поддержки рантайма и полезно указать в чем она заключается, а не про синтаксис близкий к C рассказывать. И просто конвенция вызова «как в C» мало что дает.
                    Элементарно, если исключение не поймать, то программа должна по идее завершиться, но как завершать программу зависит от ОС. А что если у вас нет ОС?


                    1. vintage
                      26.08.2017 15:19

                      Если массивы хранятся так же как в C, то откуда берется размер массива?

                      Статические массивы имеют фиксированный размер. Динамический массив — это фактически структура из указателя и длинны.


                      Элементарно, если исключение не поймать, то программа должна по идее завершиться, но как завершать программу зависит от ОС. А что если у вас нет ОС?

                      Как минимум можно всю программу завернуть в try-catch и завершать как считаете нужным. Я не спец в системном программировании, но подозреваю, что в D так же как и в C дёргается abort: https://dlang.org/library/core/stdc/stdlib/abort.html


                      1. kmu1990
                        26.08.2017 15:39
                        +1

                        Как минимум можно всю программу завернуть в try-catch и завершать как считаете нужным.
                        И если я так сделаю, компилятор перестанет втыкать вызовы рантайма в код? Или отсутсвие их реализации перестанет приводить к ошибке линковки?
                        Я не спец в системном программировании, но подозреваю, что в D так же как и в C дёргается abort: dlang.org/library/core/stdc/stdlib/abort.htmll
                        В C нет исключений, так что не также как в C. В C если вы не вызовете abort явно, то компилятор его за вас вызывать не будет только потому, что вы решили работать с массивами, что полезно, если никакой реализации abort у вас нет.

                        Мой поинт был в том, что если разговор зашел о системном программировании, то есть гораздо более актуальные вещи для обсуждения чем синтаксис похожий на C. И выбор языка C в этой области вовсе не продиктован его синтаксисом и не синтаксис оставнавливает от перехода на другие языки. Что вы хотите сказать своими комментариями?


                        1. Kobalt_x
                          26.08.2017 15:59

                          seh на некоторых платформах есть и в C, это не стандарт, но это реализуемо.


                          1. kmu1990
                            26.08.2017 16:06
                            +1

                            И? То что это реализуемо как-то гарантирует мне стабильность рантайма? И что создатели компилятора не сломают его в очередном релизе? Это как-то меняет то обстоятельство, что статья ни слова об всем этом не говорит и с чего собственно обсуждение и началось?


                        1. vintage
                          26.08.2017 17:40

                          А что в C происходит при попытке прочитать данные из нулевого указателя?


                          1. kmu1990
                            26.08.2017 17:43

                            Зависит от архитектуры, ОС, отображения памяти и много чего другого. Но строго говоря с точки зрения стандарта, то это undefined behavior.

                            Но вот чего там не происходит, так это если компилятор не попросить, то он не будет вставлять в код проверки и если эти проверки не проходят вызывать какие-то функции, которые никто не определял. Как это по вашему мнению происходит в D.


    1. grossws
      26.08.2017 01:25

      Всякие SIMD и TLS требуют какой-то поддержки

      А simd-то с какого перепугу требует рантайм? Если, конечно, нет реализации соответствующего intrinsic'а, то будут циклы. Ну так simd-инструкции не везде есть. К сишным libgcc/libimf это относится в той же мере. А если есть sse4/avx/avx2/neon/whatever, то соответствующие simd-инструкции не требуют специфичного рантайма, но только кодогенерации и оптимизаций.


      1. kmu1990
        26.08.2017 01:30

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

        Если компилятор для core фичи генерирует код использующий SIMD (прямо или через intrinsic-и), то это проблема, если это вынесено в библиотеку, использование которой опционально, то проблемы нет.


        1. grossws
          26.08.2017 01:36

          Так никто и не заставляет компилятор генерировать simd инструкции, если не указаны -march/-mtune и подобные вещи. Если dmd целится в системное программирование и ведёт себя не так — то это странно.


          Вспомнить тот же x86_64, до нормальной работы нужно переключиться в защищенный режим, а потом и в long mode. Если компилятор не позволяет сгенерировать бинарник для всех этих режимов, то на мой взгляд он не очень пригоден для системного программирования.


          Меня какое-то время назад пытались убедить, что go и js — языки программирования системного уровня.


          P. S. Почти каждый раз, когда собираюсь поставить плюс в word-must-not-be-named, оказывается, что уже ставил. Что ж это такое xD


          1. kmu1990
            26.08.2017 01:56

            Так никто и не заставляет компилятор генерировать simd инструкции, если не указаны -march/-mtune и подобные вещи. Если dmd целится в системное программирование и ведёт себя не так — то это странно.
            Я не знаю, как себя ведет D, то что я знаю это то, что статья начинается с упоминания системного программирования (и про какое-то мифическое отсутствие выбора), а потом говорит про синтаксис и фичи ни слова не сказав про ABI и рантайм нужный для поддержки этих фич, я молчу об их стабильности.

            Вспомнить тот же x86_64, до нормальной работы нужно переключиться в защищенный режим, а потом и в long mode.
            Если вам хватает Real Mode, то в защищенный режим переключать не надо (но тут у вас могут появиться проблемы при использовании, например, gcc), если вам хватает защищенного режима, то в long mode переключаться необходимости нет. Если компилятор поддерживает нужный вам режим, то он вполне пригоден, даже если он не поддерживает все на свете.

            Меня какое-то время назад пытались убедить, что go и js — языки программирования системного уровня.
            В зависимости от того, что они подразумевали под системным программированием оба языка могут являться таковыми. Мне не известно про какое-то оффициальное стандартизованное законно зафиксированное понятие системного языка программирования. Даже если в контексте данной статьи ограничиться расплывчатым смыслом «близости к железу», то оба языка можно с определенной долей усилий сделать системными создав минимальный рантайм.


            1. grossws
              26.08.2017 03:27

              Если вам хватает Real Mode, то в защищенный режим переключать не надо (но тут у вас могут появиться проблемы при использовании, например, gcc), если вам хватает защищенного режима, то в long mode переключаться необходимости нет.

              Только если вам не надо на bare metal запуститься и потом использовать long mode) Тогда нужны и все предыдущие. Или, например, на старых arm для использования thumb mode нужно было сначала сделать bx для переключения из arm mode в thumb mode, что требует понимания компилятором обоих режимов.


              то оба языка можно с определенной долей усилий сделать системными создав минимальный рантайм.

              Для некоторых портирование рантайма может оказаться сравнимо с написанием ядра ОС (менеджер памяти, процессов, реализация атомиков, api для файлов, сокетов и т. д. и т. п.).


              Если системным называть язык на котором может писаться системное ПО (т. е. не прикладное, не предназначенное для использование пользователем системы), то любой язык, на котором может быть реализован компилятор/транспайлер/вспомогательное ПО для системы, т. е. любой тьюринг-полный окажется системным, что приводит к полной бессмысленности такого определения. Поэтому я склоняюсь к определению системного языка, как такого, на котором может быть реализовано, например, ядро ОС.


              1. kmu1990
                26.08.2017 12:49
                +1

                Для некоторых портирование рантайма может оказаться сравнимо с написанием ядра ОС (менеджер памяти, процессов, реализация атомиков, api для файлов, сокетов и т. д. и т. п.).
                Это очевидно зависит от того, как рантайм определен и от того кто его реализует. Если вы для JS VM определите рантайм из пары функций (например, аллоцировать память и освободить память), то его портирование не должно составить проблем. Отсюда и появился мой вопрос про рантайм.

                Поэтому я склоняюсь к определению системного языка, как такого, на котором может быть реализовано, например, ядро ОС.
                Я уверен, что на JS и Go можно реализовать ядро ОС. Ваше определение не добавляет ясности, отчасти потому что оно не определяет, что может называться ядром ОС, а что нет. Даже приведенный вами список компонентов ядра вызывает вопросы: известны примеры ядер ОС, которые прекрасно жили/живут без потоков и/или без процессов и/или файловых систем и/или сетевого стека в ядре.


      1. 0xd34df00d
        29.08.2017 22:50

        Если, конечно, нет реализации соответствующего intrinsic'а, то будут циклы.

        Почему это? По крайней мере, с gcc/clang и x86/x86_64 в моём опыте, если вы дёргаете _mm_add_blah какой-нибудь, то код просто не соберётся, если вы не указали соответствующий -march при компиляции всего файла или если не пометили функцию как __attribute__ ((target ("avx"))), скажем. Если указали, а потом запускаете на процессоре без поддержки этой фичи, получите какой-нибудь SIGILL.


        1. grossws
          29.08.2017 23:04

          Тогда, вероятно, я не прав. Мне казалось, что icc вполне умеет обращаться с такими вещами.


          Как минимум, оптимизация для простых циклов и при использовании cilkplus активно использовала avx/avx2 при их наличии и сваливалась до sse4 при отсутствии. Но сильно подробно не разглядывал.


          1. 0xd34df00d
            30.08.2017 02:16

            Ну, так то ж автовекторизация, по большому счёту, а не ручное написание интринсиков. В упомянутом вами случае оно именно так и происходит.


  1. Laney1
    26.08.2017 09:32

    6. Аналог borrow checking из Rust через scope pointers (scope T*), scope slices (scope T[]) и scope references (scope ref T)

    в Rust уже активно пилят новую реализацию чекера над графом потока управления — он станет позволять намного больше без потери строгости


    11. Ускорение работы с массивами за счет SIMD

    а вот это в Rust пока не завезли, и непонятно когда завезут



    1. rraderio
      26.08.2017 14:32

      в Rust уже активно пилят новую реализацию чекера над графом потока управления — он станет позволять намного больше без потери строгости

      Где об этом можно почитать?



    1. newpavlov
      26.08.2017 15:45

      >а вот это в Rust пока не завезли, и непонятно когда завезут

      SIMD как и остальные LLVM интринзики можно использовать на найтли через llvmint, плюс есть настойчивое желание получить SIMD на стабильном Расте, так что, думаю, в 2018 мы увидим работу в данном направлении.


      1. Laney1
        26.08.2017 17:11

        SIMD как и остальные LLVM интринзики можно использовать на найтли через llvmint

        проблема в том, что использовать nightly — далеко не всегда вариант. Вот например, разработчик Firefox (основного проекта, ради которого Rust собственно и пилится) еще год назад столкнулся с этим. А воз и ныне там.


        Судя по комментам, SIMD в Rust занимается один человек (BurntSushi), причем в свободное время. Так что я бы не был уверен насчет 2018-го.


  1. Temtaime
    26.08.2017 12:47
    +1

    Как много хейтеров D в комментах, которые даже не разобрались в самой теме вопроса, а посмотрели, что D уже 16 лет, и решили ещё раз его похоронить.
    За всё это время D проделал очень большой путь и уже не похож на то, что было в начале. Даже за последние несколько лет изменений в лучшую сторону очень много, идёт потихоньку отказ от сборщика мусора.
    После недели кодинга на D вы не захотите возвращаться к C++, потому что у D ОЧЕНЬ богатая стандартная библиотека, прекрасные шеблоны, много фишек самого языка(такие как генерация кода в процессе компиляции; constexpr и рядом не стоял), отсутствует UB, размеры всех типов стандартизированы, есть менеджер пакетов и другие удобные вещи, при этом он ближе к C++, чем Rust и Go и вызывает меньший разрыв шаблона при переходе.
    Я говорю это вам как тот, кто написал 3D движок и игру полностью на D.
    Если у кого-то есть вопросы по самому языку — могу развёрнуто ответить.


    1. rogoz
      26.08.2017 13:48
      +1

      отсутствует UB

      dlang.org/dlangspec.pdf «undefined behavior» найдено неоднократно.
      размеры всех типов стандартизированы

      В C++ есть int32_t и остальное из cstdint.


      1. Temtaime
        26.08.2017 14:18

        Все найденные способы связаны с cast'ом immutable в mutable, а также сборщиком мусора. Ни первого, ни второго в C++ нет.
        Оно-то есть, но не «из коробки», а в виде костылей. Как и большинство остального, унаследованного из C.


    1. dataman
      26.08.2017 19:08

      прекрасные шеблоны, много фишек самого языка(такие как генерация кода в процессе компиляции; constexpr и рядом не стоял)

      Nim имеет столько фишек, что D и рядом не стоял. :)


      1. beduin01 Автор
        26.08.2017 19:08

        Можно хоть пару примеров того что в Nim реализовано лучше чем в D?


        1. dataman
          27.08.2017 11:02
          +1

          Я некоторое время экспериментировал с D, сделал пару PR, но затем эти nogc, pure, system, etc. стали просто бесить.

          пару примеров того что в Nim реализовано лучше чем в D?

          1. Макросы. Вы можете создать свой DSL средствами самого языка. Так, например, в Nim реализованы юниттесты. Или макрос scanf, который на этапе компиляции преобразуется в вызовы соответсвующих функций и поэтому парсинг работает очень быстро.
          2. Конвертеры
          3. Концепты

          Для разработчиков игр/графики, думаю, будет интересно взглянуть на opengl-sandbox. Демо.


          1. rraderio
            28.08.2017 09:23

            Конвертеры

            Т.е. если у меня функция принимает bool а я передаю int, то это все будет работать?


          1. pav5000
            29.08.2017 10:39

            Всякие scanf, printf и даже регулярные выражения в D тоже парсятся на этапе компиляции и преобразуются в вызовы. Это как раз сделано за счёт удобной генерации кода в процессе компиляции.


            1. vintage
              29.08.2017 11:20

              Я бы не сказал, что прям удобной. Всё из перечисленного есть как в Nim, так и в D.
              Макросы — mixin() и mixin template, трудно сказать где лучше, они просто разные.
              Конвертеры — opCast(), но в D есть ограничение — перегрузки возможны только "изнутри" типа, но нельзя добавить их "снаружи", как в Nim. Хорошо это или плохо — сложно сказать.
              Концепты — конструкция if в объявлении шаблонов. Тут D куда мощнее, так как позволяет реализовывать самые дикие условия. Например: "скомпилируется ли код, если использовать такой-то тип в таком-то выражении".
              Ну а юниттесты в D являются частью языка, что избавляет от проблем вида "как протестировать приватный метод" и тому подобных.


  1. mkpankov
    26.08.2017 13:37
    +2

    Аналог borrow checking из Rust через scope pointers (scope T*), scope slices (scope T[]) и scope references (scope ref T)

    А что с mutable aliasing? Гонки данных ловит?


  1. lega
    26.08.2017 14:38

    Я считаю что D не плох, просто он попал в цикл непопулярности — «люди туда не идут потому что не популярный, не популярный потому что люди туда не идут», со всеми вытекающими — нет работы, нет развитых тулзов (относительно), нет многих либо от комьюнити.
    Для таких вещей нужен большой хайп на старте.


  1. safinaskar
    26.08.2017 18:16
    +3

    «Нравится ли вам синтаксис Rust?» — не согласен с формулировкой опроса. Синтаксис — одна из последних вещей, которая важна в языке, во всяком случае, если говорить о языках системного программирования. Лучше бы просто спросили «Годится ли Rust как замена C?»


  1. Siemargl
    27.08.2017 19:02
    +1

    Неправильный акцент в статье, зачем появился этот режим компиляции

    Кроме оригинала от Брайта еще могу посоветовать почитать раздел Editorial тут

    +1 к тому что D лучшая ветка из C-подобных. Хотя у него полно своих проблем, betterC режим — как раз попытка решения одной из