Парадигма | Мультипарадигма : функциональная , императивная , объектно-ориентированная |
---|---|
Разработано | Вальтер Брайт , Андрей Александреску (с 2007 г.) |
Разработчик | D Language Foundation |
Впервые появился | 8 декабря 2001 г . [1] |
Стабильный выпуск | 2.095.1 [2] / 17 февраля 2021 г . |
Печатная дисциплина | Предполагаемый , статический , сильный |
Операционные системы | FreeBSD , Linux , macOS , Windows |
Лицензия | Повышение [3] [4] [5] |
Расширения имени файла | .d [6] [7] |
Интернет сайт | dlang |
Основные реализации | |
DMD ( эталонная реализация ), GCC , GDC , LDC , SDC | |
Под влиянием | |
C , C ++ , C # , Eiffel , [8] Java , Python | |
Под влиянием | |
Genie , MiniD, Qore , Swift , [9] Vala , C ++ 11 , C ++ 14 , C ++ 17 , C ++ 20 , Go , C # и другие. | |
|
D , также известный как Dlang , является многопарадигмальным системным языком программирования, созданным Уолтером Брайтом в Digital Mars и выпущенным в 2001 году. Андрей Александреску присоединился к усилиям по проектированию и разработке в 2007 году. Хотя он возник как реинжиниринг C ++ , D. это отдельный язык. Он переработал некоторые основные функции C ++, а также сохранил характеристики других языков, в частности Java , Python , Ruby , C # и Eiffel .
Цели проектирования языка заключались в попытке объединить производительность и безопасность компилируемых языков с выразительной силой современных динамических языков . Идиоматический код D обычно так же быстр, как эквивалентный код C ++, но при этом короче. [10] Язык в целом небезопасен для памяти [11], но включает дополнительные атрибуты, предназначенные для проверки безопасности памяти. [12]
Тип вывода , автоматическое управление памятью и синтаксический сахар для распространенных типов позволяют быстрее развитие , в то время как проверки границ , дизайн по контракту функциями и параллелизмом -aware системы типа , помогают уменьшить возникновение ошибок . [13]
Особенности [ править ]
D был разработан с учетом уроков, извлеченных из практического использования C ++, а не с чисто теоретической точки зрения. Хотя язык использует многие концепции C и C ++, он также отбрасывает некоторые или использует другие подходы (и синтаксис) для достижения некоторых целей. Таким образом, он несовместим с исходным кодом (и не стремится быть совместимым ) с исходным кодом C и C ++ в целом (некоторые более простые кодовые базы этих языков могут по счастливой случайности работать с D или потребовать некоторого переноса ). D, однако, был ограничен в своем дизайне правилом, согласно которому любой код, разрешенный как для C, так и для D, должен вести себя одинаково. D получил некоторые функции до C ++, такие как закрытие , анонимные функции , выполнение функций во время компиляции., диапазоны, встроенные концепции итерации контейнеров и вывод типов . D расширяет функциональность C ++, также реализуя дизайн по контракту , модульное тестирование , истинные модули , сборку мусора , массивы первого класса , ассоциативные массивы , динамические массивы , нарезку массивов , вложенные функции , ленивую оценку , выполнение кода с ограниченным (отложенным) кодом и переработанный синтаксис шаблона . D сохраняет способность C ++ выполнять низкоуровневое программирование и добавлять встроенный ассемблер . C ++множественное наследование было заменено одиночным наследованием в стиле Java с интерфейсами и миксинами . С другой стороны, синтаксис объявления, оператора и выражения D полностью соответствует синтаксису C ++.
В инлайн ассемблер прообраз различие между D и языками приложений , как Java и C # . Встроенный ассемблер позволяет программистам вводить машинно-зависимый ассемблерный код в стандартный D-код, метод, используемый системными программистами для доступа к низкоуровневым функциям процессора, необходимым для запуска программ, которые взаимодействуют напрямую с базовым оборудованием , таким как операционные системы и устройства. драйверы , а также написание высокопроизводительного кода (например, с использованием векторных расширений, SIMD ), который трудно сгенерировать автоматически компилятором.
D имеет встроенную поддержку комментариев к документации, что позволяет автоматически создавать документацию .
Парадигмы программирования [ править ]
D поддерживает пять основных парадигм программирования : императивное , объектно-ориентированное , метапрограммирование , функциональное и параллельное ( модель акторов ).
Императив [ править ]
Императивное программирование в D почти идентично программированию в C. Функции, данные, операторы, объявления и выражения работают так же, как и в C, и к библиотеке времени выполнения C можно обращаться напрямую. С другой стороны, некоторые заметные различия между D и C в области императивного программирования включают foreachконструкцию цикла D , которая позволяет выполнять цикл по коллекции, и вложенные функции , которые являются функциями, которые объявлены внутри другого и могут обращаться к локальным переменным включающей функции. .
импорт std . stdio ; void main () { int multiplier = 10 ; int scaled ( int x ) { вернуть x * множитель ; } foreach ( i ; 0 .. 10 ) { writefln ( "Привет, мир% d! scaled =% d" , i , scaled ( i )); } }
D также включает динамические массивы и ассоциативные массивы по умолчанию в языке.
Символы (функции, переменные, классы) могут быть объявлены в любом порядке - вперед декларации не требуется. Точно так же импорт может выполняться почти в любом порядке и даже иметь ограниченную область видимости (т.е. импортировать какой-либо модуль или его часть только внутри функции, класса или unittest).
D поддерживает перегрузку функций .
Объектно-ориентированный [ править ]
Объектно-ориентированное программирование в D основано на единой иерархии наследования со всеми классами, производными от класса Object. D не поддерживает множественное наследование; вместо этого он использует интерфейсы в стиле Java , которые сравнимы с чистыми абстрактными классами C ++, и миксины , которые отделяют общие функции от иерархии наследования. D также позволяет определять статические и конечные (не виртуальные) методы в интерфейсах.
Интерфейсы и наследование в D поддерживают ковариантные типы для типов, возвращаемых переопределенными методами.
D поддерживает перегрузку операторов , пересылку типов, а также дополнительную настраиваемую динамическую отправку .
Классы (и интерфейсы) в D могут содержать инварианты, которые автоматически проверяются до и после входа в общедоступные методы. Это часть методологии проектирования по контракту .
Многие аспекты классов (и структуры) могут быть интроспектированы автоматически во время компиляции (форма отражения с использованием type traits
) и во время выполнения (RTII / TypeInfo
), чтобы облегчить общий код или автоматическую генерацию коды ( как правило , с использованием методов во время компиляции).
Метапрограммирование [ править ]
Метапрограммирование поддерживается комбинацией шаблонов, выполнения функций во время компиляции, кортежей и строковых миксинов. Следующие примеры демонстрируют некоторые возможности D во время компиляции.
Шаблоны в D могут быть написаны в более императивном стиле по сравнению с функциональным стилем C ++ для шаблонов. Это обычная функция, которая вычисляет факториал числа:
ulong factorial ( ulong n ) { если ( n < 2 ) вернуть 1 ; иначе верните n * факториал ( n - 1 ); }
Здесь static if
демонстрируется использование условной конструкции D во время компиляции для создания шаблона, который выполняет те же вычисления с использованием кода, аналогичного таковому для функции выше:
шаблон Factorial ( ulong n ) { статический if ( n < 2 ) enum Factorial = 1 ; иначе перечисление Factorial = n * Factorial ! ( n - 1 ); }
В следующих двух примерах шаблон и функция, определенные выше, используются для вычисления факториалов. Типы констант не нужно указывать явно, поскольку компилятор определяет их типы из правых частей присваивания:
enum fact_7 = Факториал ! ( 7 );
Это пример выполнения функции времени компиляции . Обычные функции могут использоваться в постоянных выражениях времени компиляции при условии, что они соответствуют определенным критериям:
перечислимый факт_9 = факториал ( 9 );
В std.string.format
функции выполняет printf-подобное форматирование данных (также во время компиляции, через CTFE ), и «MSG» Pragma отображает результат во время компиляции:
импорт std . строка : формат ; pragma ( msg , format ( "7! =% s" , fact_7 )); pragma ( msg , format ( "9! =% s" , fact_9 ));
Строковые миксины в сочетании с выполнением функций во время компиляции позволяют генерировать D-код с использованием строковых операций во время компиляции. Это можно использовать для синтаксического анализа предметно-ориентированных языков в код D, который будет скомпилирован как часть программы:
import FooToD ; // гипотетический модуль, содержащий функцию, которая анализирует исходный код Foo // и возвращает эквивалентный код D void main () { mixin ( fooToD ( import ( "example.foo" ))); }
Функциональный [ править ]
D поддерживает функции функционального программирования, такие как функциональные литералы , замыкания , рекурсивно-неизменяемые объекты и использование функций высшего порядка . Существует два синтаксиса анонимных функций, включая форму с несколькими операторами и «сокращенную» нотацию с одним выражением: [10]
int function ( int ) g ; г = ( х ) { вернуть х * х ; }; // от руки g = ( x ) => x * x ; // сокращение
Есть два встроенных типа для функциональных литералов, function
который является просто указателем на функцию, выделенную в стеке, и delegate
который также включает указатель на окружающую среду. Вывод типа может использоваться с анонимной функцией, и в этом случае компилятор создает, delegate
если только он не может доказать, что указатель среды не нужен. Аналогичным образом, чтобы реализовать закрытие, компилятор помещает закрытые локальные переменные в кучу только в случае необходимости (например, если закрытие возвращается другой функцией и выходит из области видимости этой функции). При использовании вывода типа компилятор также добавит атрибуты, такие как pure
и, nothrow
к типу функции, если он сможет доказать, что они применимы.
Другие функциональные возможности, такие как каррирование и общие функции высшего порядка, такие как map , filter и reduce , доступны через стандартные библиотечные модули std.functional
и std.algorithm
.
импорт std . stdio , std . алгоритм , std . диапазон ;void main () { int [] a1 = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]; int [] a2 = [ 6 , 7 , 8 , 9 ]; // должно быть неизменным, чтобы разрешить доступ изнутри чистой функции immutable pivot = 5 ; int mySum ( int a , int b ) pure nothrow // чистая функция { if ( b <= pivot ) // ссылка на охватывающую область return a + b ; остальное возвращение ; } // передача делегата (закрытие) auto result = reduce ! mySum ( цепочка ( a1 , a2 )); Writeln ( "Результат:" , результат ); // Результат: 15 // передача литерального делегата result = reduce ! (( a , b ) => ( b <= pivot ) ? a + b : a ) ( chain ( a1 , a2 )); Writeln ( "Результат:" , результат ); // Результат: 15 }
В качестве альтернативы, вышеуказанные функциональные композиции могут быть выражены с использованием единого синтаксиса вызова функций (UFCS) для более естественного чтения слева направо:
автоматический результат = a1 . цепь ( а2 ). уменьшить ! mySum (); Writeln ( "Результат:" , результат ); результат = a1 . цепь ( а2 ). уменьшить ! (( a , b ) => ( b <= pivot ) ? a + b : a ) (); Writeln ( "Результат:" , результат );
Параллельно [ править ]
Концепции параллельного программирования реализованы в библиотеке и не требуют дополнительной поддержки со стороны компилятора. Однако система типа D и компилятор гарантируют, что совместное использование данных может быть обнаружено и управляемо прозрачно.
импорт std . stdio : Writeln ; импорт std . диапазон : йота ; импорт std . параллельность : параллельность ;void main () { foreach ( i ; iota ( 11 ). parallel ) { // Тело цикла foreach выполняется параллельно для каждого i Writeln ( "processing" , i ); } }
iota(11).parallel
эквивалентно std.parallelism.parallel(iota(11))
использованию UFCS.
Этот же модуль также поддерживает функции, taskPool
которые можно использовать для динамического создания параллельных задач, а также операции map-filter-reduce и fold style для диапазонов (и массивов), что полезно в сочетании с функциональными операциями:
импорт std . stdio : Writeln ; импорт std . алгоритм : карта ; импорт std . диапазон : йота ; импорт std . параллелизм : taskPool ;недействительный основной () { авто НУМС = йота ( 1,0 , 1_000_000_000.0 ); авто x = taskPool . уменьшить ! "A + B" ( 0,0 , карта ! "1.0 / (а * а)" ( НУМС ) ); Writeln ( "Сумма:" , x ); // На Intel i7-3930X и gdc 9.3.0: // 5140 мс с использованием std.algorithm.reduce // 888 мс с использованием std.parallelism.taskPool.reduce; // На AMD Threadripper 2950X и gdc 9.3.0: // 2864 мс с использованием std.algorithm.reduce // 95 мс с использованием std.parallelism.taskPool.reduce }
В этом коде используется тот факт, что std.algorithm.map
фактически возвращается не массив, а диапазон ленивой оценки, таким образом фактические элементы карты вычисляются каждой рабочей задачей параллельно автоматически.
Параллельно [ править ]
Параллельное программирование полностью реализовано в библиотеке и не требует специальной поддержки со стороны компилятора. Возможны альтернативные реализации и методологии написания параллельного кода. Использование системы ввода D действительно помогает обеспечить безопасность памяти.
импорт std . stdio , std . параллелизм , StD . вариант ;void foo () { логическое продолжение = истина ; while ( cont ) { receive ( // Делегаты используются для соответствия типу сообщения. ( int msg ) => writereln ( "int Receive:" , msg ), ( Tid sender ) { cont = false ; sender . send (- 1 ); }, ( Variant v ) => Writeln ( "да?" ) // Вариант соответствует любому типу ); } }void main () { автоматический tid = spawn (& foo ); // создаем новый поток, выполняющий foo () foreach ( i ; 0 .. 10 ) tid . отправить ( я ); // отправляем несколько целых чисел tid . отправить ( 1.0f ); // послать поплавок TID . отправить ( "привет" ); // отправляем строку tid . отправить ( thisTid ); // отправляем структуру (Tid) receive (( int x ) => writereln ( "Сообщение получено основным потоком:" , x )); }
Управление памятью [ править ]
Память обычно управляется с помощью сборки мусора , но определенные объекты могут быть завершены немедленно, когда они выходят за пределы области видимости. Это то, что используют большинство программ и библиотек, написанных на D.
В случае , если требуется больше контроль о компоновке памяти и более высокой производительности, явное управление памятью можно с помощью перегруженных операторов new
и delete
, с помощью вызова C «s таНос и свободный непосредственно или реализацию пользовательских схем Allocator (т.е. на стеке с запасным вариантом, распределение RAII стиля, подсчет ссылок, подсчет общих ссылок). Сборкой мусора можно управлять: программисты могут добавлять и исключать диапазоны памяти из-под наблюдения сборщиком, могут отключать и включать сборщик и принудительно запускать цикл сборки или полный цикл сборки. [14] В руководстве приводится много примеров того, как реализовать различные высокооптимизированные схемы управления памятью, когда сборка мусора в программе неадекватна.[15]
В функциях structs
по умолчанию выделяются в стеке, а classes
по умолчанию - в куче (со ссылкой только на экземпляр класса, находящийся в стеке). Однако это можно изменить для классов, например, используя шаблон стандартной библиотеки std.typecons.scoped
или используя new
для структур и назначив указатель вместо переменной на основе значений. [16]
В функции статические массивы (известного размера) размещаются в стеке. Для динамических массивов можно использовать core.stdc.stdlib.alloca
функцию (аналогичную функции C alloca
, для выделения памяти в стеке. Возвращаемый указатель можно использовать (преобразовать) в (типизированный) динамический массив с помощью среза (однако изменение размера массива, включая добавление, должно быть их следует избегать, и по очевидным причинам их нельзя возвращать из функции). [17]
scope
Ключевое слово может быть использовано как для аннотирования частей кода, но также переменных и классов / структур, чтобы указать , что они должны быть уничтожены (деструктор) под названием сразу на выходе области действия. Независимо от того, какая память будет освобождена, также зависит от реализации и различий между классами и структурами. [18]
std.experimental.allocator
содержит модульные и составные шаблоны распределителя для создания настраиваемых высокопроизводительных распределителей для особых случаев использования. [19]
SafeD [ править ]
SafeD [20]
- это имя, присвоенное подмножеству D, которое может быть гарантированно безопасно для памяти (нет операций записи в память, которая не была выделена или была повторно использована). Отмеченные функции @safe
проверяются во время компиляции, чтобы гарантировать, что они не используют какие-либо функции, которые могут привести к повреждению памяти, такие как арифметика указателя и неконтролируемое приведение типов, а любые другие вызываемые функции также должны быть помечены как @safe
или @trusted
. Функции могут быть отмечены @trusted
для случаев, когда компилятор не может различить безопасное использование функции, отключенной в SafeD, и потенциальный случай повреждения памяти. [21]
Scope Lifetime Safety [ править ]
Первоначально под знаменами DIP1000 [22] и DIP25 [23] (теперь часть спецификации языка [24] ), D обеспечивает защиту от некоторых плохо сформированных конструкций, связанных с временем жизни данных.
Существующие в настоящее время механизмы в основном имеют дело с параметрами функций и стековой памятью, однако заявленная цель руководства языка программирования - обеспечить более тщательную обработку времени жизни в языке программирования D. [25] (На основе идей языка программирования Rust ).
Пожизненная безопасность заданий [ править ]
В коде @safe проверяется время жизни присвоения, включающего ссылочный тип, чтобы гарантировать, что время жизни правопреемника больше, чем у назначенного.
Например:
@safe void test () { int tmp = 0 ; // # 1 int * rad ; // # 2 rad = & tmp ; // Если порядок объявлений # 1 и # 2 поменять местами, это не сработает. { int bad = 45 ; // Срок действия «плохого» распространяется только на область, в которой он определен. * рад = плохо ; // Это кошерно. рад = & плохо ; // Срок службы рад больше, чем плохой, поэтому это совсем не кошерно. } }
Аннотации времени жизни параметра функции в коде @safe [ править ]
При применении к параметру функции, который имеет тип указателя или ссылки, ключевые слова return и scope ограничивают время жизни и использование этого параметра.
Стандарт диктует следующее поведение: [26]
Класс хранения | Поведение (и ограничения) параметра с классом хранения |
---|---|
объем | ссылки в параметре не могут быть экранированы. Игнорируется для параметров без ссылок |
возвращаться | Параметр может быть возвращен или скопирован в первый параметр, но в противном случае функция не может выйти из него. Такие копии требуются, чтобы не пережить аргументы, на основании которых они были получены. Игнорируется для параметров без ссылок |
Аннотированный пример приведен ниже.
@safe :int * gp ; недействительные Торины ( сфера INT *); пустота gloin ( int *); int * balin ( возвращаем область действия int * p , область действия int * q , int * r ) { gp = p ; // ошибка, p переходит в глобальный gp gp = q ; // ошибка, q уходит в глобальный gp gp = r ; // Ok торин ( п ); // хорошо, p не выходит из торина () торин ( q ); // хорошо торин ( r ); // Ok gloin ( п ); // ошибка, gloin () ускользает p gloin ( q ); // ошибка, gloin () ускользает q gloin ( r ); // хорошо, что gloin () ускользает от r return p ; // нормально return q ; // ошибка, невозможно вернуть 'scope' q return r ; // ок }
Взаимодействие с другими системами [ править ]
C «s двоичный интерфейс приложения (ABI) поддерживается, а также всех основных и производных типов C, позволяя прямой доступ к существующим кодом C и библиотеки. Привязки D доступны для многих популярных библиотек C. Кроме того, стандартная библиотека C является частью стандарта D.
В Microsoft Windows D может получить доступ к коду модели компонентных объектов (COM).
Если правильно позаботиться об управлении памятью, многие другие языки могут быть смешаны с D в одном двоичном файле. Например, компилятор GDC позволяет связывать коды C, C ++ и других поддерживаемых языков для смешивания. Код D (функции) также можно пометить как использующие C, C ++, Pascal ABI и, таким образом, передать в библиотеки, написанные на этих языках, как обратные вызовы . Точно так же данные можно обменивать между кодами, написанными на этих языках, обоими способами. Обычно это ограничивает использование примитивных типов, указателей, некоторых форм массивов, объединений, структур и только некоторых типов указателей на функции.
Поскольку многие другие языки программирования часто предоставляют C API для написания расширений или запуска интерпретатора языков, D также может напрямую взаимодействовать с этими языками, используя стандартные привязки C (с тонким файлом интерфейса D). Например, есть двунаправленные привязок для таких языков , как Python , [27] Lua [28] [29] и других языках, часто с использованием методов типа отражения времени компиляции генерации кода и времени компиляции.
Взаимодействие с кодом C ++ [ править ]
D использует разрешительный, но реалистичный подход к взаимодействию с кодом C ++. [30]
Для кода D, помеченного как extern (C ++) , указаны следующие функции:
- Соглашения по изменению имен должны совпадать с соглашениями C ++ на целевой машине.
- Для вызовов функций ABI должен быть эквивалентным.
- Таблица vtable должна соответствовать одиночному наследованию (единственный уровень, поддерживаемый спецификацией языка D).
Пространства имен C ++ используются через синтаксис extern (C ++, пространство имен), где пространство имен - это имя пространства имен C ++.
Пример взаимодействия C ++ [ править ]
Сторона C ++
#include <iostream>используя пространство имен std ; class Base { public : virtual void print3i ( int a , int b , int c ) = 0 ; };class Derived : public Base { public : int field ; Производное ( целое поле ) : поле ( поле ) {} void print3i ( int a , int b , int c ) { cout << "a =" << a << endl ; cout << "b =" << b << endl ; cout << "c =" << c << endl ; } int mul ( множитель int ); };int Derived :: mul ( int factor ) { возвращаемое поле * фактор ; }Derived * createInstance ( int i ) { return new Derived ( i ); }void deleteInstance ( Derived * & d ) { delete d ; d = 0 ; }
Сторона D
extern ( C ++) { абстрактный класс Base { void print3i ( int a , int b , int c ); } class Derived : Base { int field ; @ отключить это (); переопределить void print3i ( int a , int b , int c ); final int mul ( множитель int ); } Производный createInstance ( int i ); void deleteInstance ( ref Derived d ); }void main () { import std . stdio ; авто d1 = createInstance ( 5 ); Writeln ( d1 . поле ); Writeln ( d1 . mul ( 4 )); База b1 = d1 ; b1 . print3i ( 1 , 2 , 3 ); deleteInstance ( d1 ); assert ( d1 имеет значение null ); авто d2 = createInstance ( 42 ); Writeln ( d2 . поле ); deleteInstance ( d2 ); assert ( d2 имеет значение null ); }
Лучше C [ править ]
В языке программирования D есть официальное подмножество, известное как « Better C ». [31] Это подмножество запрещает доступ к функциям D, требующим использования библиотек времени выполнения, отличных от C.
Включенный через флаги компилятора «-betterC» на DMD и LDC и «-fno-druntime» на GDC, Better C может вызывать только код D, скомпилированный под тем же флагом (и связанный код, отличный от D), но код, скомпилированный без Лучшая опция C может вызывать код, скомпилированный с ее помощью: это, однако, приведет к немного другому поведению из-за различий в том, как C и D обрабатывают утверждения.
Функции, доступные в подмножестве Better C [ править ]
- Неограниченное использование функций времени компиляции (например, функции динамического распределения D могут использоваться во время компиляции для предварительного выделения данных D)
- Полные средства метапрограммирования
- Вложенные функции, вложенные структуры, делегаты и лямбды
- Функции-члены, конструкторы, деструкторы, операционная перегрузка и т. Д.
- Полная модульная система
- Нарезка массива и проверка границ массива
- RAII
- область действия (выход)
- Защита памяти
- Взаимодействие с C ++
- COM-классы и классы C ++
- сбои assert направляются в библиотеку времени выполнения C
- переключатель со струнами
- последний переключатель
- блоки unittest
[ править ]
- Вывоз мусора
- TypeInfo и ModuleInfo
- Встроенная многопоточность (например
core.thread
) - Динамические массивы (хотя работают срезы статических массивов) и ассоциативные массивы
- Исключения
- синхронизированы и
core.sync
- Конструкторы или деструкторы статических модулей
История [ править ]
Уолтер Брайт начал работу над новым языком в 1999 году. D был впервые выпущен в декабре 2001 года [1] и достиг версии 1.0 в январе 2007 года. [32] Первая версия языка (D1) была сосредоточена на императивном, объектно-ориентированном и метапрограммировании. парадигмы, [33] похожи на C ++.
Некоторые члены сообщества D, недовольные Phobos, официальной средой выполнения и стандартной библиотекой D , создали альтернативную среду выполнения и стандартную библиотеку под названием Tango. Первое публичное объявление о Tango было сделано через несколько дней после выпуска D 1.0. [34]В Tango был принят другой стиль программирования, основанный на ООП и высокой модульности. Tango - это проект, возглавляемый сообществом, поэтому он был более открыт для участия, что позволило ему развиваться быстрее, чем официальная стандартная библиотека. В то время Tango и Phobos были несовместимы из-за разных API-интерфейсов поддержки времени выполнения (сборщик мусора, поддержка потоковой передачи и т. Д.). Это сделало невозможным использование обеих библиотек в одном проекте. Существование двух широко используемых библиотек привело к серьезным спорам из-за того, что одни пакеты используют Phobos, а другие - Tango. [35]
В июне 2007 года была выпущена первая версия D2. [36] Начало развития D2 сигнализировало о стабилизации D1. Первая версия языка была переведена на обслуживание, в нее были внесены только исправления и исправления ошибок реализации. D2 внес критические изменения в язык, начиная со своей первой экспериментальной системы const . Позже D2 добавил множество других языковых функций, таких как закрытие , чистота и поддержка парадигм функционального и параллельного программирования. D2 также решил проблемы стандартной библиотеки, отделив среду выполнения от стандартной библиотеки. О завершении строительства порта D2 Tango было объявлено в феврале 2012 года. [37]
Выпуск книги Андрея Александреску « Язык программирования D» 12 июня 2010 г. ознаменовал стабилизацию D2, который сегодня обычно называют просто «D».
В январе 2011 года разработка D перешла с отслеживания ошибок / патчей на GitHub . Это привело к значительному увеличению вклада в компилятор, среду выполнения и стандартную библиотеку. [38]
В декабре 2011 года Андрей Александреску объявил, что D1, первая версия языка, будет прекращена 31 декабря 2012 года. [39] Последний выпуск D1, D v1.076, состоялся 31 декабря 2012 года. [40]
Код для официального компилятора D, компилятора Digital Mars D Уолтера Брайта, изначально был выпущен по специальной лицензии , которая квалифицируется как доступный исходный код, но не соответствует определению открытого исходного кода . [41] В 2014 году клиентская часть компилятора была повторно лицензирована как открытый исходный код по лицензии Boost Software License . [3] Этот повторно лицензированный код исключал серверную часть, которая частично была разработана в Symantec . 7 апреля 2017 года весь компилятор стал доступен по лицензии Boost после того, как Symantec дала разрешение на повторную лицензию и на серверную часть.[4] [42] [43] [44] 21 июня 2017 г. язык D был принят для включения в GCC. [45]
Начиная с GCC 9, GDC (сокращение от GNU D Compiler или GCC D Compiler), интерфейс языка D, основанный на интерфейсе с открытым исходным кодом DMD, был объединен с GCC. [46]
Реализации [ править ]
Большинство текущих реализаций D компилируются непосредственно в машинный код для эффективного выполнения.
Готовые компиляторы:
- DMD - Компилятор Digital Mars D Уолтера Брайта является официальным компилятором D; с открытым исходным кодом под лицензией Boost Software License . [3] [4] Интерфейс DMD используется GDC (теперь в GCC) и LDC для улучшения совместимости между компиляторами. Изначально интерфейс был написан на C ++, но теперь большая часть его написана на самом D (самостоятельный хостинг). Оптимизаторы внутреннего и машинного кода основаны на компиляторе Symantec. Сначала он поддерживал только 32-разрядную архитектуру x86, но Уолтер Брайт добавил поддержку 64-разрядной версии amd64 и PowerPC. Позже бэкэнд и почти весь компилятор были перенесены с C ++ на D для полноценного самостоятельного размещения.
- GCC - Коллекция компиляторов GNU , объединила GDC [47] с GCC 9 29 октября 2018 года. [48] Первые рабочие версии GDC с GCC, основанные на GCC 3.3 и GCC 3.4 на 32-битной платформе x86 на Linux и MacOS X [49], были выпущены 22 марта 2004 года. С тех пор GDC получил поддержку большего количества платформ, улучшил производительность и исправил ошибки, одновременно отслеживая исходный код DMD для интерфейса и спецификации языка.
- LDC - компилятор, основанный на интерфейсе DMD, который использует LLVM в качестве внутреннего интерфейса компилятора. Первая релизная версия была опубликована 9 января 2009 года. [50] Она поддерживает версию 2.0. [51]
Компиляторы игрушек и доказательств концепции:
- D Compiler for .NET - серверная часть для компилятора языка программирования D. [52] [53] Он компилирует код в байт- код Common Intermediate Language (CIL), а не в машинный код. Затем CIL можно запустить через виртуальную машину Common Language Infrastructure (CLI) . Проект не обновлялся годами, и автор указал, что проект больше не активен.
- SDC - Компилятор Stupid D использует пользовательский интерфейс и LLVM в качестве серверной части компилятора. Он написан на языке D и использует планировщик для обработки разрешения символов, чтобы элегантно обрабатывать функции времени компиляции D. Этот компилятор в настоящее время поддерживает ограниченное подмножество языка. [54] [55]
Используя вышеуказанные компиляторы и инструментальные средства, можно скомпилировать программы D для многих различных архитектур, включая x86 , amd64 , AArch64 , PowerPC , MIPS64 , DEC Alpha , Motorola m68k , Sparc , s390 , WebAssembly . Основными поддерживаемыми операционными системами являются Windows и Linux , но различные компиляторы также поддерживают Mac OS X , FreeBSD , NetBSD , AIX , Solaris / OpenSolaris и Android.либо в качестве хоста, либо в качестве цели, либо в качестве обоих. Целевой объект WebAssembly (поддерживаемый через LDC и LLVM) может работать в любой среде WebAssembly, например в современном веб-браузере ( Google Chrome , Mozilla Firefox , Microsoft Edge , Apple Safari ) или выделенных виртуальных машинах Wasm.
Инструменты разработки [ править ]
Редакторы и интегрированные среды разработки (IDE), поддерживающие D, включают Eclipse , Microsoft Visual Studio , SlickEdit , Emacs , vim , SciTE , Smultron , TextMate , MonoDevelop , Zeus, [56] и Geany среди других. [57]
- Dexed (ранее Coedit) [58] ориентированная на D графическая IDE, написанная на Object Pascal
- Mono-D [59] - многофункциональная кроссплатформенная графическая IDE, ориентированная на D, основанная на MonoDevelop / Xamarin Studio, в основном написанная на C # .
- Подключаемые модули Eclipse для D включают: DDT [60] и Descent (мертвый проект). [61]
- Интеграция с Visual Studio обеспечивается VisualD. [62] [63]
- Интеграция Visual Studio Code с такими расширениями, как Dlang-Vscode [64] или Code-D. [65]
- Vim поддерживает как подсветку синтаксиса, так и автозавершение кода.
- Для TextMate доступен пакет , а IDE Code :: Blocks включает частичную поддержку языка. Однако стандартные функции IDE, такие как завершение кода или рефакторинг , пока недоступны, хотя они частично работают в Code :: Blocks (из-за сходства D с C).
- Доступен плагин для Xcode 3 , D для Xcode, для поддержки проектов и разработки на основе D. [66]
- Доступна надстройка для MonoDevelop с именем Mono-D. [67]
- Доступен плагин автозаполнения KDevelop (а также его бэкэнд текстового редактора Kate). [68]
Кроме того, многие другие редакторы и IDE поддерживают выделение синтаксиса и частичное завершение кода / идентификатора для D.
Существуют IDE D с открытым исходным кодом для Windows , некоторые из них написаны на D, например Poseidon, [69] D-IDE, [70] и Entice Designer. [71]
Приложения D можно отлаживать с помощью любого отладчика C / C ++, например GDB или WinDbg , хотя поддержка различных функций языка D крайне ограничена. В Windows программы D можно отлаживать с помощью Ddbg или инструментов отладки Microsoft (WinDBG и Visual Studio) после преобразования отладочной информации с помощью cv2pdb . ZeroBUGS отладчик для Linux имеет экспериментальную поддержку для языка D. Ddbg можно использовать с различными IDE или из командной строки; ZeroBUGS имеет собственный графический интерфейс пользователя (GUI).
DustMite - это мощный инструмент для минимизации исходного кода D, полезный при поиске проблем с компилятором или тестированием. [72]
dub - популярный менеджер пакетов и сборки для приложений и библиотек D, который часто интегрируется в поддержку IDE. [73]
Примеры [ править ]
Этот раздел, возможно, содержит оригинальные исследования . Сентябрь 2020 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) ( |
Пример 1 [ править ]
Этот пример программы печатает аргументы командной строки. main
Функция является точкой входа программы D, и args
представляет собой массив строк , представляющих аргументы командной строки. A string
в D - это массив символов, представленный immutable(char)[]
.
импорт std . stdio : writefln ;void main ( string [] args ) { foreach ( я , аргумент ; аргументы ) writefln ( "args [% d] = '% s'" , i , arg );}
foreach
Оператор может перебрать любую коллекцию. В этом случае он создает последовательность индексов ( i
) и значений ( arg
) из массива args
. Индекс i
и значение arg
имеют свои типы, выведенные из типа массива args
.
Пример 2 [ править ]
Ниже показано несколько возможностей D и компромиссов D-дизайна в короткой программе. Он перебирает строки текстового файла с именем words.txt
, который содержит разные слова в каждой строке, и печатает все слова, которые являются анаграммами других слов.
импорт std . stdio , std . алгоритм , std . Диапазон , StD . строка ;void main () { dstring [] [ dstring ] signature2words ; foreach ( dchar [] w ; lines ( File ( "words.txt" ))) { ш = ш . чомп (). toLower (); неизменная подпись = w . обман . сортировать (). релиз (). idup ; signature2words [ подпись ] ~ = w . idup ; } foreach ( words ; signature2words ) { if ( words . length > 1 ) { Writeln ( слова . join ( "" )); } }}
signature2words
- это встроенный ассоциативный массив, который отображает ключи dstring (32-битные / символьные) на массивы dstrings. Он похожdefaultdict(list)
на Python .lines(File())
лениво выводит строки с новой строкой. Затем его необходимо скопировать,idup
чтобы получить строку, которая будет использоваться для значений ассоциативного массива (idup
свойство массивов возвращает неизменный дубликат массива, который требуется, посколькуdstring
тип действительно естьimmutable(dchar)[]
). Для встроенных ассоциативных массивов требуются неизменяемые ключи.~=
Оператор добавляет новый dstring к значениям ассоциированного динамического массива.toLower
,join
иchomp
являются строковыми функциями, которые D позволяет использовать с синтаксисом метода. Название таких функций часто похоже на строковые методы Python. ВtoLower
преобразует строку в нижнем регистре,join(" ")
присоединяется массив строк в одну строку с помощью одного пространства в качестве сепаратора, иchomp
удаляет символ новой строки с конца строки , если он присутствует. Этоw.dup.sort().release().idup
более читабельно, но эквивалентно,release(sort(w.dup)).idup
например,. Эта функция называется UFCS (унифицированный синтаксис вызова функций) и позволяет расширять любые встроенные или сторонние типы пакетов с помощью функций, подобных методам. Такой стиль написания кода часто называют конвейером (особенно когда используемые объекты вычисляются лениво, например итераторы / диапазоны) илиСвободный интерфейс .- Это
sort
функция std.algorithm, которая сортирует массив на месте, создавая уникальную подпись для слов, которые являются анаграммами друг друга.release()
Метод на возвращаемом значенииsort()
удобно держать код как единое выражение. - Второй
foreach
выполняет итерацию по значениям ассоциативного массива, он может определить типwords
. signature
присваивается неизменной переменной, определяется ее тип.- UTF-32
dchar[]
используется вместо обычного UTF-8,char[]
иначеsort()
отказывается его сортировать. Есть более эффективные способы написать эту программу, используя только UTF-8.
Использует [ редактировать ]
Известные организации, использующие язык программирования D для проектов, включают Facebook , [74] eBay , [75] и Netflix . [76]
D был успешно использован для AAA игры , [77] языка интерпретаторы, виртуальные машины, [78] [79] операционной системы ядра , [80] GPU программирование, [81] веб - разработки , [82] [83] численный анализ , [84] Приложения с графическим интерфейсом пользователя , [85] [86] информационная система для пассажиров , [87] машинное обучение, [88] обработка текста, веб-серверы и серверы приложений, а также исследования.
См. Также [ править ]
- Ddoc
- D Language Foundation
Ссылки [ править ]
- ^ a b «D Протокол изменений до 7 ноября 2005 г.» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 года .
- ^ «Журнал изменений: 2.095.1» . Проверено 21 февраля 2021 года .
- ^ a b c "Интерфейс dmd теперь переключен на лицензию Boost" . Проверено 9 сентября 2014 года .
- ^ a b c "Серверная часть dmd преобразована в лицензию Boost" . 7 апреля 2017 . Проверено 9 апреля 2017 года .
- ^ "D 2.0 FAQ" . Дата обращения 11 августа 2015 .
- ^ " " Язык программирования D - Fileinfo.com " " . Дата обращения 15 ноября 2020 . [ необходима цитата ]
- ^ " " Язык программирования D - dlang.org " " . Дата обращения 15 ноября 2020 . [ необходима цитата ]
- ^ Александреску, Андрей (2010). Язык программирования D (Первое изд.). Река Аппер Сэдл, Нью-Джерси: Аддисон-Уэсли. п. 314 . ISBN 978-0321635365.
- ^ «Создание assert () в Swift, Часть 2: __FILE__ и __LINE__» . Проверено 25 сентября 2014 года .
- ^ a b «Выражения» . Цифровой Марс . Проверено 27 декабря 2012 года .
- ^ «На: размышления о D: интервью с Уолтером Брайтом» . Хакерские новости . 30 августа 2016 г. «Это близко, и мы работаем над устранением оставшихся пробелов».
- ^ "Память-Safe-D-Spec" . D Language Foundation.
- ↑ Андрей Александреску (2 августа 2010 г.). Три прикольных вещей О D .
- ^ "std.gc" . D Язык программирования 1.0 . Цифровой Марс . Проверено 6 июля 2010 года .
- ^ «Управление памятью» . D Язык программирования 2.0 . Цифровой Марс . Проверено 17 февраля 2012 года .
- ^ «Иди своей дорогой (Часть первая: Стек)» . D Блог . Дата обращения 7 мая 2020 .
- ^ «Иди своей дорогой (Часть первая: Стек)» . D Блог . Дата обращения 7 мая 2020 .
- ^ «Атрибуты - язык программирования D» . dlang.org . Дата обращения 7 мая 2020 .
- ^ "std.experimental.allocator - язык программирования D" . dlang.org . Дата обращения 7 мая 2020 .
- ^ Бартош Милевски. "Язык программирования SafeD - D" . Проверено 17 июля 2014 года .
- ^ Стивен Schveighoffer (28 сентября 2016). «Как написать доверенный код на языке D» . Проверено 4 января 2018 .
- ^ "Указатели с ограничением" . 3 апреля 2020.
- ^ «Запечатанные ссылки» .
- ^ «Спецификация языка D: функции - возвращаемые параметры области действия» .
- ^ «Право собственности и заимствования в D» . 15 июля 2019.
- ^ «Спецификация языка D: функции - классы хранения параметров функций» .
- ^ "PyD" . 7 мая 2020 . Дата обращения 7 мая 2020 .
- ^ Паркер, Майк. «Пакет derelict-lua на DUB» . Реестр пакетов DUB . Дата обращения 7 мая 2020 .
- ^ Паркер, Майк. «Пакет bindbc-lua на DUB» . Реестр пакетов DUB . Дата обращения 7 мая 2020 .
- ^ «Взаимодействие с C ++» .
- ^ "Лучше C" .
- ^ "D Журнал изменений" . D Язык программирования 1.0 . Цифровой Марс . Проверено 11 января 2012 года .
- ^ «Вступление» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 года .
- ^ "Объявление новой библиотеки" . Проверено 15 февраля 2012 года .
- ^ "Wiki4D: Стандартная библиотека" . Проверено 6 июля 2010 года .
- ^ «Журнал изменений - язык программирования D» . D Язык программирования 2.0 . D Language Foundation . Проверено 22 ноября 2020 года .
- ^ "Tango for D2: Все пользовательские модули перенесены" . Проверено 16 февраля 2012 года .
- ^ Уолтер Брайт. "Re: GitHub или dsource?" . Проверено 15 февраля 2012 года .
- ↑ Андрей Александреску. «Производство D1 будет прекращено 31 декабря 2012 года» . Проверено 31 января 2014 года .
- ^ "D Журнал изменений" . D Язык программирования 1.0 . Цифровой Марс . Проверено 31 января 2014 года .
- ^ "backendlicense.txt" . Исходный код DMD . GitHub. Архивировано из оригинального 22 октября 2016 года . Проверено 5 марта 2012 года .
- ^ "Комментарий Reddit Уолтера Брайта" . Проверено 9 сентября 2014 года .
- ^ D-Compiler-unter-freier- Lizenz на linux-magazin.de (2017, на немецком языке)
- ^ переключить бэкэнд на Boost License # 6680 от Walter Bright на github.com
- ^ D Язык принят для включения в GCC
- ^ «GCC 9 Release Series Changes, New Features, and Fixes» .
- ^ "GDC" .
- ^ «Серия выпусков GCC 9 - Изменения, новые функции и исправления - Проект GNU - Фонд свободного программного обеспечения (FSF)» . gcc.gnu.org . Дата обращения 7 мая 2020 .
- ^ "Другой интерфейс для GCC" . forum.dlang.org . Дата обращения 7 мая 2020 .
- ^ "Проект компилятора LLVM D на GitHub" . Проверено 19 августа 2016 .
- ^ "BuildInstructionsPhobosDruntimeTrunk - ldc - D Programming Language - Trac" . Дата обращения 11 августа 2015 .
- ^ "Проект D .NET на CodePlex" . Проверено 3 июля 2010 года .
- ↑ Джонатан Аллен (15 мая 2009 г.). «Теперь доступен исходный код для компилятора D.NET» . InfoQ . Проверено 6 июля 2010 года .
- ^ "DConf 2014: SDC, компилятор D как библиотека Амори Сечет" . Проверено 8 января 2014 года .
- ^ "deadalnix / SDC" . Проверено 8 января 2014 года .
- ^ "Wiki4D: EditorSupport / ZeusForWindows" . Дата обращения 11 августа 2015 .
- ^ "Wiki4D: Поддержка редактора" . Проверено 3 июля 2010 года .
- ^ "Basile.B / dexed" . GitLab . Проверено 29 апреля 2020 .
- ^ "Mono-D - D Wiki" . wiki.dlang.org . Проверено 30 апреля 2020 .
- ^ "Хостинг проектов Google" . Дата обращения 11 августа 2015 .
- ^ "спуск" . Дата обращения 11 августа 2015 .
- ^ "Visual D - D язык программирования" . Дата обращения 11 августа 2015 .
- ^ Шютец, Rainer (17 апреля 2020). "rainers / visuald: Visual D - расширение Visual Studio для языка программирования D" . github.com . Проверено 30 апреля 2020 .
- ^ "dlang-vscode" . Проверено 21 декабря +2016 .
- ^ "код-д" . Проверено 21 декабря +2016 .
- ^ "Мишель Фортин - D для Xcode" . Дата обращения 11 августа 2015 .
- ^ «Поддержка Mono-D - D для MonoDevelop» . Дата обращения 11 августа 2015 .
- ^ "Dav1dde / люмен" . GitHub . Дата обращения 11 августа 2015 .
- ^ "Посейдон" . Дата обращения 11 августа 2015 .
- ^ «Поддержка Mono-D - D для MonoDevelop» . Дата обращения 11 августа 2015 .
- ^ "Entice Designer - Dprogramming.com - язык программирования D" . Дата обращения 11 августа 2015 .
- ^ "Что такое DustMite?" . Проверено 29 апреля 2020 .
- ^ "dlang / dub: Система управления пакетами и сборкой для D" . Проверено 29 апреля 2020 .
- ^ "Под капотом: деформация, быстрый препроцессор C и C ++" . 28 марта 2014 . Проверено 4 января 2018 .
- ^ «Более быстрые инструменты командной строки в D» . 24 мая 2017 . Проверено 4 января 2018 .
- ^ «Знакомство с Vectorflow» . 2 августа 2017 . Проверено 4 января 2018 .
- ^ «Quantum Break: AAA-игры с некоторым кодом D» . Проверено 4 января 2018 .
- ^ "Виртуальная машина JavaScript Хиггса" . Проверено 4 января 2018 .
- ^ "Реализация AD языка программирования ECMA 262 (Javascript)" . Проверено 4 января 2018 .
- ^ «Основные моменты проекта: ядро PowerNex» . Проверено 4 января 2018 .
- ^ «DCompute: запуск D на графическом процессоре» . 30 октября 2017 года . Проверено 4 января 2018 .
- ^ "vibe.d - высокопроизводительный набор инструментов для асинхронного ввода-вывода, параллелизма и веб-приложений, написанный на D" . Проверено 4 января 2018 .
- ^ «Основные моменты проекта: Diamond MVC Framework» . 20 ноября 2017 . Проверено 4 января 2018 .
- ^ «Числовой возраст для D: Mir GLAS быстрее, чем OpenBLAS и Eigen» . Проверено 4 января 2018 .
- ^ «На Тиликс и D: Интервью с Джеральдом Нанном» . 11 августа 2017 . Проверено 4 января 2018 .
- ^ «Основные моменты проекта: DlangUI» . Проверено 4 января 2018 .
- ^ «Основные моменты проекта: Funkwerk» . Проверено 4 января 2018 .
- ^ "Netflix / vectorflow" . GitHub.com . Netflix, Inc. 5 мая 2020 . Дата обращения 7 мая 2020 .
Дальнейшее чтение [ править ]
- Александреску, Андрей (4 января 2010 г.). Язык программирования D (1-е изд.). Эддисон-Уэсли Профессионал. ISBN 978-0-321-63536-5.
- Александреску, Андрей (15 июня 2009 г.). «Дело в пользу D» . Журнал доктора Добба.
- Брайт, Уолтер (8 апреля 2014 г.). «Как я пришел писать D» . Журнал доктора Добба.
- Шехрели, Али (1 февраля 2012 г.). «Программирование в D» .(распространяется по лицензии CC-BY-NC-SA). Эта книга обучает программированию новичков, но также охватывает многие продвинутые темы D.
- Мец, Кейд (7 июля 2014 г.). «Следующий большой язык программирования, о котором вы никогда не слышали» . Проводной .
- Руппе, Адам (май 2014 г.). D Поваренная книга (1-е изд.). PACKT Publishing. ISBN 978-1-783-28721-5.
Внешние ссылки [ править ]
В Викиучебнике есть книга на тему: Руководство для начинающих по D |
В Викиучебнике есть книга на тему: D Программирование. |
- Официальный веб-сайт
- Цифровой Марс
- Турецкий форум
- Dlang на GitHub