Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

Функции, недоступные в подмножестве Better C [ править ]

  • Вывоз мусора
  • 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]

Примеры [ править ]

Пример 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 ( "" )); } }}
  1. signature2words- это встроенный ассоциативный массив, который отображает ключи dstring (32-битные / символьные) на массивы dstrings. Он похож defaultdict(list)на Python .
  2. lines(File())лениво выводит строки с новой строкой. Затем его необходимо скопировать, idupчтобы получить строку, которая будет использоваться для значений ассоциативного массива ( idupсвойство массивов возвращает неизменный дубликат массива, который требуется, поскольку dstringтип действительно есть immutable(dchar)[]). Для встроенных ассоциативных массивов требуются неизменяемые ключи.
  3. ~=Оператор добавляет новый dstring к значениям ассоциированного динамического массива.
  4. toLower, joinи chompявляются строковыми функциями, которые D позволяет использовать с синтаксисом метода. Название таких функций часто похоже на строковые методы Python. В toLowerпреобразует строку в нижнем регистре, join(" ")присоединяется массив строк в одну строку с помощью одного пространства в качестве сепаратора, и chompудаляет символ новой строки с конца строки , если он присутствует. Это w.dup.sort().release().idupболее читабельно, но эквивалентно, release(sort(w.dup)).idupнапример,. Эта функция называется UFCS (унифицированный синтаксис вызова функций) и позволяет расширять любые встроенные или сторонние типы пакетов с помощью функций, подобных методам. Такой стиль написания кода часто называют конвейером (особенно когда используемые объекты вычисляются лениво, например итераторы / диапазоны) илиСвободный интерфейс .
  5. Это sortфункция std.algorithm, которая сортирует массив на месте, создавая уникальную подпись для слов, которые являются анаграммами друг друга. release()Метод на возвращаемом значении sort()удобно держать код как единое выражение.
  6. Второй foreachвыполняет итерацию по значениям ассоциативного массива, он может определить тип words.
  7. signature присваивается неизменной переменной, определяется ее тип.
  8. 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

Ссылки [ править ]

  1. ^ a b «D Протокол изменений до 7 ноября 2005 г.» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 года .
  2. ^ «Журнал изменений: 2.095.1» . Проверено 21 февраля 2021 года .
  3. ^ a b c "Интерфейс dmd теперь переключен на лицензию Boost" . Проверено 9 сентября 2014 года .
  4. ^ a b c "Серверная часть dmd преобразована в лицензию Boost" . 7 апреля 2017 . Проверено 9 апреля 2017 года .
  5. ^ "D 2.0 FAQ" . Дата обращения 11 августа 2015 .
  6. ^ " " Язык программирования D - Fileinfo.com " " . Дата обращения 15 ноября 2020 . [ необходима цитата ]
  7. ^ " " Язык программирования D - dlang.org " " . Дата обращения 15 ноября 2020 . [ необходима цитата ]
  8. ^ Александреску, Андрей (2010). Язык программирования D (Первое изд.). Река Аппер Сэдл, Нью-Джерси: Аддисон-Уэсли. п. 314 . ISBN 978-0321635365.
  9. ^ «Создание assert () в Swift, Часть 2: __FILE__ и __LINE__» . Проверено 25 сентября 2014 года .
  10. ^ a b «Выражения» . Цифровой Марс . Проверено 27 декабря 2012 года .
  11. ^ «На: размышления о D: интервью с Уолтером Брайтом» . Хакерские новости . 30 августа 2016 г. «Это близко, и мы работаем над устранением оставшихся пробелов».
  12. ^ "Память-Safe-D-Spec" . D Language Foundation.
  13. Андрей Александреску (2 августа 2010 г.). Три прикольных вещей О D .
  14. ^ "std.gc" . D Язык программирования 1.0 . Цифровой Марс . Проверено 6 июля 2010 года .
  15. ^ «Управление памятью» . D Язык программирования 2.0 . Цифровой Марс . Проверено 17 февраля 2012 года .
  16. ^ «Иди своей дорогой (Часть первая: Стек)» . D Блог . Дата обращения 7 мая 2020 .
  17. ^ «Иди своей дорогой (Часть первая: Стек)» . D Блог . Дата обращения 7 мая 2020 .
  18. ^ «Атрибуты - язык программирования D» . dlang.org . Дата обращения 7 мая 2020 .
  19. ^ "std.experimental.allocator - язык программирования D" . dlang.org . Дата обращения 7 мая 2020 .
  20. ^ Бартош Милевски. "Язык программирования SafeD - D" . Проверено 17 июля 2014 года .
  21. ^ Стивен Schveighoffer (28 сентября 2016). «Как написать доверенный код на языке D» . Проверено 4 января 2018 .
  22. ^ "Указатели с ограничением" . 3 апреля 2020.
  23. ^ «Запечатанные ссылки» .
  24. ^ «Спецификация языка D: функции - возвращаемые параметры области действия» .
  25. ^ «Право собственности и заимствования в D» . 15 июля 2019.
  26. ^ «Спецификация языка D: функции - классы хранения параметров функций» .
  27. ^ "PyD" . 7 мая 2020 . Дата обращения 7 мая 2020 .
  28. ^ Паркер, Майк. «Пакет derelict-lua на DUB» . Реестр пакетов DUB . Дата обращения 7 мая 2020 .
  29. ^ Паркер, Майк. «Пакет bindbc-lua на DUB» . Реестр пакетов DUB . Дата обращения 7 мая 2020 .
  30. ^ «Взаимодействие с C ++» .
  31. ^ "Лучше C" .
  32. ^ "D Журнал изменений" . D Язык программирования 1.0 . Цифровой Марс . Проверено 11 января 2012 года .
  33. ^ «Вступление» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 года .
  34. ^ "Объявление новой библиотеки" . Проверено 15 февраля 2012 года .
  35. ^ "Wiki4D: Стандартная библиотека" . Проверено 6 июля 2010 года .
  36. ^ «Журнал изменений - язык программирования D» . D Язык программирования 2.0 . D Language Foundation . Проверено 22 ноября 2020 года .
  37. ^ "Tango for D2: Все пользовательские модули перенесены" . Проверено 16 февраля 2012 года .
  38. ^ Уолтер Брайт. "Re: GitHub или dsource?" . Проверено 15 февраля 2012 года .
  39. Андрей Александреску. «Производство D1 будет прекращено 31 декабря 2012 года» . Проверено 31 января 2014 года .
  40. ^ "D Журнал изменений" . D Язык программирования 1.0 . Цифровой Марс . Проверено 31 января 2014 года .
  41. ^ "backendlicense.txt" . Исходный код DMD . GitHub. Архивировано из оригинального 22 октября 2016 года . Проверено 5 марта 2012 года .
  42. ^ "Комментарий Reddit Уолтера Брайта" . Проверено 9 сентября 2014 года .
  43. ^ D-Compiler-unter-freier- Lizenz на linux-magazin.de (2017, на немецком языке)
  44. ^ переключить бэкэнд на Boost License # 6680 от Walter Bright на github.com
  45. ^ D Язык принят для включения в GCC
  46. ^ «GCC 9 Release Series Changes, New Features, and Fixes» .
  47. ^ "GDC" .
  48. ^ «Серия выпусков GCC 9 - Изменения, новые функции и исправления - Проект GNU - Фонд свободного программного обеспечения (FSF)» . gcc.gnu.org . Дата обращения 7 мая 2020 .
  49. ^ "Другой интерфейс для GCC" . forum.dlang.org . Дата обращения 7 мая 2020 .
  50. ^ "Проект компилятора LLVM D на GitHub" . Проверено 19 августа 2016 .
  51. ^ "BuildInstructionsPhobosDruntimeTrunk - ldc - D Programming Language - Trac" . Дата обращения 11 августа 2015 .
  52. ^ "Проект D .NET на CodePlex" . Проверено 3 июля 2010 года .
  53. Джонатан Аллен (15 мая 2009 г.). «Теперь доступен исходный код для компилятора D.NET» . InfoQ . Проверено 6 июля 2010 года .
  54. ^ "DConf 2014: SDC, компилятор D как библиотека Амори Сечет" . Проверено 8 января 2014 года .
  55. ^ "deadalnix / SDC" . Проверено 8 января 2014 года .
  56. ^ "Wiki4D: EditorSupport / ZeusForWindows" . Дата обращения 11 августа 2015 .
  57. ^ "Wiki4D: Поддержка редактора" . Проверено 3 июля 2010 года .
  58. ^ "Basile.B / dexed" . GitLab . Проверено 29 апреля 2020 .
  59. ^ "Mono-D - D Wiki" . wiki.dlang.org . Проверено 30 апреля 2020 .
  60. ^ "Хостинг проектов Google" . Дата обращения 11 августа 2015 .
  61. ^ "спуск" . Дата обращения 11 августа 2015 .
  62. ^ "Visual D - D язык программирования" . Дата обращения 11 августа 2015 .
  63. ^ Шютец, Rainer (17 апреля 2020). "rainers / visuald: Visual D - расширение Visual Studio для языка программирования D" . github.com . Проверено 30 апреля 2020 .
  64. ^ "dlang-vscode" . Проверено 21 декабря +2016 .
  65. ^ "код-д" . Проверено 21 декабря +2016 .
  66. ^ "Мишель Фортин - D для Xcode" . Дата обращения 11 августа 2015 .
  67. ^ «Поддержка Mono-D - D для MonoDevelop» . Дата обращения 11 августа 2015 .
  68. ^ "Dav1dde / люмен" . GitHub . Дата обращения 11 августа 2015 .
  69. ^ "Посейдон" . Дата обращения 11 августа 2015 .
  70. ^ «Поддержка Mono-D - D для MonoDevelop» . Дата обращения 11 августа 2015 .
  71. ^ "Entice Designer - Dprogramming.com - язык программирования D" . Дата обращения 11 августа 2015 .
  72. ^ "Что такое DustMite?" . Проверено 29 апреля 2020 .
  73. ^ "dlang / dub: Система управления пакетами и сборкой для D" . Проверено 29 апреля 2020 .
  74. ^ "Под капотом: деформация, быстрый препроцессор C и C ++" . 28 марта 2014 . Проверено 4 января 2018 .
  75. ^ «Более быстрые инструменты командной строки в D» . 24 мая 2017 . Проверено 4 января 2018 .
  76. ^ «Знакомство с Vectorflow» . 2 августа 2017 . Проверено 4 января 2018 .
  77. ^ «Quantum Break: AAA-игры с некоторым кодом D» . Проверено 4 января 2018 .
  78. ^ "Виртуальная машина JavaScript Хиггса" . Проверено 4 января 2018 .
  79. ^ "Реализация AD языка программирования ECMA 262 (Javascript)" . Проверено 4 января 2018 .
  80. ^ «Основные моменты проекта: ядро ​​PowerNex» . Проверено 4 января 2018 .
  81. ^ «DCompute: запуск D на графическом процессоре» . 30 октября 2017 года . Проверено 4 января 2018 .
  82. ^ "vibe.d - высокопроизводительный набор инструментов для асинхронного ввода-вывода, параллелизма и веб-приложений, написанный на D" . Проверено 4 января 2018 .
  83. ^ «Основные моменты проекта: Diamond MVC Framework» . 20 ноября 2017 . Проверено 4 января 2018 .
  84. ^ «Числовой возраст для D: Mir GLAS быстрее, чем OpenBLAS и Eigen» . Проверено 4 января 2018 .
  85. ^ «На Тиликс и D: Интервью с Джеральдом Нанном» . 11 августа 2017 . Проверено 4 января 2018 .
  86. ^ «Основные моменты проекта: DlangUI» . Проверено 4 января 2018 .
  87. ^ «Основные моменты проекта: Funkwerk» . Проверено 4 января 2018 .
  88. ^ "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.

Внешние ссылки [ править ]

  • Официальный веб-сайт
  • Цифровой Марс
  • Турецкий форум
  • Dlang на GitHub