Articulo de referencia

D (lenguaje de programación)

"},"designer":{"wt":"[[Walter Bright]], [[Andrei Alexandrescu]] (since 2007)"},"developer":{"wt":"[[D Language Foundation]]"},"typing":{"wt":"[[Inferred typing|Inferred]], [[sta...

D , también conocido como dlang , es un lenguaje de programación de sistemas multiparadigma creado por Walter Bright en Digital Mars y lanzado en 2001. Andrei Alexandrescu se unió al equipo de diseño y desarrollo en 2007. Aunque se originó como una reingeniería de C++ , D es ahora un lenguaje muy diferente. A medida que ha evolucionado, se ha inspirado en otros lenguajes de programación de alto nivel . En particular, ha recibido influencias de Java , Python , Ruby , C# y Eiffel .

La documentación del lenguaje D lo describe de la siguiente manera:

D es un lenguaje de programación de sistemas de propósito general con una sintaxis similar a la de C que se compila a código nativo. Es de tipado estático y admite tanto la gestión de memoria automática (con recolección de basura) como la manual. Los programas en D se estructuran como módulos que pueden compilarse por separado y enlazarse con bibliotecas externas para crear bibliotecas nativas o ejecutables. [ 11 ]

Características

En general, D no es compatible a nivel de código fuente con C y C++. Sin embargo, cualquier código que sea válido tanto en C/C++ como en D debería comportarse de la misma manera.

Al igual que C++, D cuenta con cierres , funciones anónimas , ejecución de funciones en tiempo de compilación , diseño por contrato , rangos, conceptos integrados de iteración de contenedores e inferencia de tipos . La sintaxis de declaraciones, sentencias y expresiones de D también se asemeja mucho a la de C++.

A diferencia de C++, D también implementa recolección de basura , arreglos de primera clase ( en C++ técnicamente no lo son), segmentación de arreglos , funciones anidadas y evaluación perezosa . D utiliza herencia simple al estilo Java con interfaces y mixins en lugar de herencia múltiple al estilo C++ .std::array

D es un lenguaje de programación de sistemas. Al igual que C++, y a diferencia de lenguajes de aplicación como Java y C# , D admite programación de bajo nivel , incluyendo ensamblador en línea . El ensamblador en línea permite a los programadores insertar código ensamblador específico de la máquina dentro del código D estándar. Los programadores de sistemas utilizan este método para acceder a las funciones de bajo nivel del procesador necesarias para ejecutar programas que interactúan directamente con el hardware subyacente , como sistemas operativos y controladores de dispositivos . La programación de bajo nivel también se utiliza para escribir código de mayor rendimiento que el que produciría un compilador .

D admite la sobrecarga de funciones y la sobrecarga de operadores . Los símbolos ( funciones , variables , clases ) se pueden declarar en cualquier orden; no se necesitan declaraciones anticipadas .

En D, las cadenas de caracteres de texto son arreglos de caracteres, y los arreglos en D se comprueban mediante límites. [ 12 ] D tiene tipos de primera clase para números complejos e imaginarios. [ 13 ]

paradigmas de programación

D admite cinco paradigmas de programación principales :

Imperativo

La programación imperativa en D es casi idéntica a la de C. Las funciones, los datos, las sentencias, las declaraciones y las expresiones funcionan igual que en C, y se puede acceder directamente a la biblioteca de tiempo de ejecución de C. Sin embargo, a diferencia de C, la estructura de bucles de D foreachpermite iterar sobre una colección. D también permite funciones anidadas , que son funciones declaradas dentro de otra función y que pueden acceder a las variables locales de la función contenedora .

import std.stdio ;void main () { int multiplicador = 10 ; int escalado ( int x ) { return x * multiplicador ; }foreach ( i ; 0 .. 10 ) { writefln ( "Hola, mundo %d! escalado = %d" , i , escalado ( i )); } }

Orientado a objetos

La programación orientada a objetos en D se basa en una jerarquía de herencia simple , donde todas las clases derivan de la clase `Object`. D no admite herencia múltiple; en su lugar, utiliza interfaces al estilo Java , comparables a las clases abstractas puras de C++, y mixins , que separan la funcionalidad común de la jerarquía de herencia. D también permite definir métodos estáticos y finales (no virtuales) en las interfaces.

Las interfaces y la herencia en D admiten tipos covariantes para los tipos de retorno de los métodos sobrescritos.

D admite el reenvío de tipos y el despacho dinámico personalizado opcional .

Las clases (e interfaces) en D pueden contener invariantes que se comprueban automáticamente antes y después de acceder a los métodos públicos, de acuerdo con la metodología de diseño por contrato .

Muchos aspectos de las clases (y estructuras) se pueden introspeccionar automáticamente en tiempo de compilación (una forma de programación reflexiva (reflexión) usando type traits) y en tiempo de ejecución (RTTI / TypeInfo), para facilitar el código genérico o la generación automática de código (generalmente usando técnicas de tiempo de compilación).

Funcional

D admite características de programación funcional como literales de función , cierres , objetos recursivamente inmutables y el uso de funciones de orden superior . Hay dos sintaxis para funciones anónimas, incluyendo una forma de múltiples instrucciones y una notación de expresión única "abreviada": [ 14 ]

función entera ( int ) g ; g = ( x ) { return x * x ; }; // forma larga g = ( x ) => x * x ; // forma abreviada

Hay dos tipos integrados para literales de función, function, que es simplemente un puntero a una función asignada en la pila, y delegate, que también incluye un puntero al marco de pila relevante , el 'entorno' circundante, que contiene las variables locales actuales. La inferencia de tipos se puede usar con una función anónima, en cuyo caso el compilador crea un delegatea menos que pueda demostrar que un puntero de entorno no es necesario. Del mismo modo, para implementar un cierre, el compilador coloca las variables locales encerradas en el montón solo si es necesario (por ejemplo, si un cierre es devuelto por otra función y sale del ámbito de esa función). Cuando se usa la inferencia de tipos, el compilador también agregará atributos como purey nothrowal tipo de una función, si puede demostrar que se aplican.

Otras características funcionales, como el currying y las funciones comunes de orden superior, como map , filter y reduce, están disponibles a través de los módulos de la biblioteca estándar std.functionaly std.algorithm.

import std.stdio , std.algorithm , std.range ;void main () { int [] a1 = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]; int [] a2 = [ 6 , 7 , 8 , 9 ];// debe ser inmutable para permitir el acceso desde dentro de una función pura immutable pivot = 5 ;int mySum ( int a , int b ) pure nothrow /* función pura */ { // referencia al ámbito circundante if ( b <= pivot ) { return a + b ; } else { return a ; } }// pasando un delegado (cierre) auto result = reduce ! mySum ( chain ( a1 , a2 )); writeln ( "Resultado: " , result ); // Resultado: 15// pasando un literal delegado result = reduce !(( a , b ) => ( b <= pivot ) ? a + b : a )( chain ( a1 , a2 )); writeln ( "Resultado: " , result ); // Resultado: 15 }

Alternativamente, las composiciones de funciones anteriores se pueden expresar utilizando la sintaxis de llamada a función uniforme (UFCS) para una lectura de izquierda a derecha más natural:

auto resultado = a1 . cadena ( a2 ). reducir ! miSuma (); escribir ( "Resultado: " , resultado );resultado = a1 . cadena ( a2 ). reducir !(( a , b ) => ( b <= pivote ) ? a + b : a )(); escribir ( "Resultado: " , resultado );

Paralelismo

Los conceptos de programación paralela están implementados en la biblioteca y no requieren soporte adicional del compilador. Sin embargo, el sistema de tipos D y el compilador garantizan que el intercambio de datos se pueda detectar y gestionar de forma transparente.

import std.stdio : writeln ; import std.range : iota ; import std.parallelism : parallel ;void main () { foreach ( i ; iota ( 11 ) .parallel ) { // El cuerpo del bucle foreach se ejecuta en paralelo para cada i writeln ( "procesando" , i ); } }

iota(11).paralleles equivalente a std.parallelism.parallel(iota(11))usar UFCS.

El mismo módulo también admite taskPoolla creación dinámica de tareas paralelas y operaciones de map-filter-reduce y fold en rangos (y matrices), lo cual resulta útil al combinarse con operaciones funcionales. std.algorithm.mapDevuelve un rango evaluado de forma diferida en lugar de una matriz. De esta manera, los elementos son calculados automáticamente por cada tarea de trabajo en paralelo.

import std.stdio : writeln ; import std.algorithm : map ; import std.range : iota ; import std.parallelism : taskPool ;/* En Intel i7-3930X y gdc 9.3.0: * 5140ms usando std.algorithm.reduce * 888ms usando std.parallelism.taskPool.reduce * * En AMD Threadripper 2950X y gdc 9.3.0: * 2864ms usando std.algorithm.reduce * 95ms usando std.parallelism.taskPool.reduce */ void main () { auto nums = iota ( 1.0 , 1_000_000_000.0 );auto x = taskPool . reduce ! "a + b" ( 0.0 , map ! "1.0 / (a ​​* a)" ( nums ) );writeln ( "Suma: " , x ); }

Concurrencia

La concurrencia está completamente implementada en la biblioteca y no requiere soporte del compilador. Existen implementaciones y metodologías alternativas para escribir código concurrente. El uso del sistema de tipado D contribuye a garantizar la seguridad de la memoria.

import std.stdio , std.concurrency , std.variant ;void foo () { bool cont = true ;while ( cont ) { // Los delegados se utilizan para hacer coincidir el tipo de mensaje. receive ( ( int msg ) => writeln ( "int recibido: " , msg ), ( Tid sender ) { cont = false ; sender . send (- 1 ); }, ( Variant v ) => writeln ( "¿eh?" ) // Variant coincide con cualquier tipo ); } }void main () { auto tid = spawn (& foo ); // crea un nuevo hilo que ejecuta foo()foreach ( i ; 0 .. 10 ) { tid . send ( i ); // enviar algunos números enteros }tid.send ( 1.0f ); // envía un float tid.send ( " hello" ); // envía una cadena tid.send ( thisTid ); // envía una estructura (Tid )recibir (( int x ) => escribir ( "El hilo principal recibió un mensaje: " , x )); }

Metaprogramación

La metaprogramación se admite mediante plantillas, ejecución de funciones en tiempo de compilación, tuplas y combinaciones de cadenas. Los siguientes ejemplos demuestran algunas de las características de D que se ejecutan en tiempo de compilación.

Las plantillas en D se pueden escribir con un estilo más imperativo en comparación con el estilo funcional de plantillas de C++. Esta es una función regular que calcula el factorial de un número:

factorial ulong ( ulong n ) { si ( n < 2 ) { retorno 1 ; } else { return n * factorial ( n - 1 ); } }

Aquí static ifse demuestra el uso de , la construcción condicional en tiempo de compilación de D, para construir una plantilla que realiza el mismo cálculo utilizando un código similar al de la función anterior:

plantilla Factorial ( ulong n ) { static if ( n < 2 ) { enum Factorial = 1 ; } else { enum Factorial = n * Factorial !( n - 1 ); } }

En los dos ejemplos siguientes, la plantilla y la función definidas anteriormente se utilizan para calcular factoriales. No es necesario especificar explícitamente los tipos de las constantes, ya que el compilador los deduce a partir del lado derecho de las asignaciones:

enum factorial7 = Factorial !( 7 );

Este es un ejemplo de ejecución de funciones en tiempo de compilación (CTFE). Las funciones ordinarias pueden utilizarse en expresiones constantes en tiempo de compilación siempre que cumplan ciertos criterios:

enum factorial9 = factorial ( 9 );

La std.string.formatfunción realiza printfun formato de datos similar a (también en tiempo de compilación, a través de CTFE), y la directiva "msg" muestra el resultado en tiempo de compilación:

import std.string : format ;pragma ( msg , format ( "7! = %s" , fact_7 )); pragma ( msg , format ( "9! = %s" , fact_9 ));

Las funciones mixtas de cadena, combinadas con la ejecución de funciones en tiempo de compilación, permiten generar código D utilizando operaciones de cadena en tiempo de compilación. Esto se puede usar para analizar lenguajes específicos de dominio , que se compilarán como parte del programa:

// Módulo hipotético que contiene una función que analiza el código fuente de Foo // y devuelve el código D equivalente import FooToD ;void main () { mixin ( fooToD ( import ( "example.foo" ))); }

Gestión de la memoria

La memoria generalmente se gestiona mediante la recolección de basura , pero ciertos objetos pueden finalizarse inmediatamente cuando salen del ámbito. Este es el método que utiliza la mayoría de los programas y bibliotecas escritos en D.

Es posible gestionar explícitamente la memoria utilizando el operador sobrecargado `new`, llamando directamente a ` malloc` y `free` de C , o implementando esquemas de asignación personalizados como la asignación en pila con reserva, la asignación de estilo RAII, el conteo de referencias o el conteo de referencias compartidas. La recolección de basura se puede controlar: los programadores pueden agregar y excluir rangos de memoria para que no sean observados por el recolector, pueden deshabilitar y habilitar el recolector y forzar un ciclo de recolección generacional o completo. [ 15 ] La documentación del lenguaje proporciona ejemplos de cómo implementar esquemas alternativos de gestión de memoria para escenarios donde no se prefiere la recolección de basura. [ 16 ]

En las funciones, structlas instancias se asignan por defecto en la pila, mientras que classlas instancias se asignan por defecto en el montón (con solo la referencia a la instancia de la clase en la pila). Sin embargo, esto se puede cambiar para las clases, por ejemplo, usando la plantilla de la biblioteca estándar std.typecons.scoped, o usando newpara las estructuras y asignando a un puntero en lugar de una variable basada en valor. [ 17 ]

En las funciones, los arreglos estáticos (de tamaño conocido) se asignan en la pila. Para los arreglos dinámicos, se puede usar la core.stdc.stdlib.allocafunción (similar a allocaen C) para asignar memoria en la pila. El puntero devuelto se puede usar (reconvertir) en un arreglo dinámico (tipado) mediante una porción (sin embargo, debe evitarse redimensionar el arreglo, incluyendo agregar elementos; y por razones obvias, no deben devolverse desde la función). [ 17 ]

Una scopepalabra clave puede usarse tanto para anotar partes del código como variables y clases/estructuras, para indicar que deben destruirse (llamarse al destructor) inmediatamente al salir del ámbito. La forma en que se libera la memoria también depende de la implementación y de las diferencias entre clases y estructuras. [ 18 ]

std.experimental.allocatorContiene plantillas de asignadores modulares y componibles para crear asignadores personalizados para casos de uso específicos. [ 19 ]

SafeD

SafeD [ 20 ] es el nombre que se le da al subconjunto de D que puede garantizarse como seguro para la memoria . Las funciones marcadas @safese comprueban en tiempo de compilación para asegurar que no utilicen ninguna característica que pueda provocar corrupción de memoria, como aritmética de punteros y conversiones no comprobadas. Cualquier otra función llamada también debe marcarse como @safeo @trusted. Las funciones pueden marcarse @trustedpara los casos en que el compilador no puede distinguir entre el uso seguro de una característica deshabilitada en SafeD y un posible caso de corrupción de memoria. [ 21 ]

Seguridad de por vida del alcance

Inicialmente bajo los estandartes de DIP1000 [ 22 ] y DIP25 [ 23 ] (ahora parte de la especificación del lenguaje [ 24 ] ), D proporciona protecciones contra ciertas construcciones mal formadas que involucran las vidas útiles de los datos.

Los mecanismos actuales en funcionamiento se ocupan principalmente de los parámetros de función y la memoria de pila; sin embargo, la hoja de ruta del diseño del lenguaje incluye planes para ampliar el seguimiento del ciclo de vida dentro del lenguaje de programación D, basándose en conceptos del lenguaje de programación Rust . [ 25 ] (influenciado por ideas del lenguaje de programación Rust ).

Seguridad de por vida en las asignaciones

En el código @safe, se comprueba la duración de una asignación que involucra un tipo de referencia para garantizar que la duración del objeto asignado sea mayor que la del objeto asignado.

Por ejemplo:

@safe void test () { int tmp = 0 ; // #1 int * rad ; // #2 rad = & tmp ; // Si el orden de las declaraciones de #1 y #2 se invierte, esto falla. { int bad = 45 ; // La vida útil de "bad" solo se extiende al ámbito en el que se define. * rad = bad ; // Esto es válido. rad = & bad ; // La vida útil de rad es más larga que la de bad, por lo tanto, esto no es válido. } }

Anotaciones de tiempo de vida de parámetros de función dentro del código @safe

Cuando se aplican a parámetros de función que son de tipo puntero o referencia, las palabras clave return y scope restringen la vida útil y el uso de ese parámetro.

El estándar del lenguaje dicta el siguiente comportamiento: [ 26 ]

A continuación se muestra un ejemplo comentado.

@seguro :int * gp ; void thorin ( scope int *); void gloin ( int *); int * balin ( return scope int * p , scope int * q , int * r ) { gp = p ; // Error, p se escapa a la variable global gp. gp = q ; // Error, q se escapa a la variable global gp. gp = r ; // OK.thorin ( p ); // OK, p no escapa de thorin(). thorin ( q ); // OK. thorin ( r ); // OK.gloino ( p ); // Error, p escapa de gloin(). gloino ( q ); // Error, q escapa de gloin(). gloino ( r ); // Está bien que r escape de gloin().return p ; // OK. return q ; // Error, no se puede devolver 'scope' q. return r ; // OK. }

Interacción con otros sistemas

Se admite la interfaz binaria de aplicación (ABI) de C , así como todos sus tipos fundamentales y derivados, lo que permite el acceso directo al código y las bibliotecas de C existentes. Existen enlaces D para muchas bibliotecas populares de C. Además, la biblioteca estándar de C forma parte del estándar D.

En Microsoft Windows, la tecla D puede acceder al código del Modelo de Objetos Componentes (COM).

Siempre que la gestión de memoria se realice correctamente, se pueden combinar muchos otros lenguajes con D en un solo binario. Por ejemplo, el compilador GDC permite enlazar y mezclar C, C++ y otros códigos de lenguajes compatibles, como Objective-C. El código D (funciones) también se puede marcar para que utilice las ABI de C, C++ y Pascal, y así pasarlo a las bibliotecas escritas en estos lenguajes como funciones de devolución de llamada . De forma similar, se pueden intercambiar datos entre los códigos escritos en estos lenguajes en ambos sentidos. Esto suele limitar su uso a tipos primitivos, punteros, algunos tipos de matrices, uniones , estructuras y solo algunos tipos de punteros a funciones.

Dado que muchos otros lenguajes de programación suelen proporcionar la interfaz de programación de aplicaciones ( API ) de C para escribir extensiones o ejecutar el intérprete de los lenguajes, D también puede interactuar directamente con estos lenguajes, utilizando enlaces C estándar (con un archivo de interfaz D ligero). Por ejemplo, existen enlaces bidireccionales para los lenguajes Python , [ 27 ] Lua , [ 28 ] [ 29 ] y otros, que a menudo utilizan generación de código en tiempo de compilación y métodos de reflexión de tipos en tiempo de compilación.

Interacción con código C++

Para el código D marcado como , se especifican las siguientes características:extern(C++)

  • Las convenciones de modificación de nombres deberán coincidir con las de C++ en el entorno de destino.
  • Para las llamadas a funciones, la ABI deberá ser equivalente.
  • La tabla virtual deberá coincidir con la herencia simple (el único nivel admitido por la especificación del lenguaje D).

Los espacios de nombres de C++ se utilizan a través de la sintaxis

extern ( C ++ , espacio de nombres )

donde namespacees el nombre del espacio de nombres de C++.

Un ejemplo de interoperabilidad de C++

Sobre C++:

importar std ;clase Base { public : virtual void print3i ( int a , int b , int c ) = 0 ; };clase Derivada : pública Base { privada : int campo ; pública : explícita Derivada ( int campo ) : campo ( campo ) {}void print3i ( int a , int b , int c ) { std :: println ( "a = {}" , a ); std :: println ( "b = {}" , b ); std :: println ( "c = {}" , c ); }int mul ( int factor ) { return campo * factor ; } };Derivado * crearInstancia ( int i ) { devolver nuevo Derivado ( i ); }void deleteInstance ( Derived *& d ) { delete d ; d = 0 ; }

En D:

extern ( C ++) { abstract class Base { public : void print3i ( int a , int b , int c ); }clase Derivada : Base { privado : int campo ; público : @disable this (); anular void print3i ( int a , int b , int c ); final int mul ( int factor ); }Derived createInstance ( int i ); void deleteInstance ( ref Derived d ); }void main () { import std . stdio ;auto d1 = createInstance ( 5 ); writeln ( d1 . field ); writeln ( d1 . mul ( 4 ));Base b1 = d1 ; b1.print3i ( 1 , 2 , 3 ) ;eliminarInstancia ( d1 ); afirmar ( d1 es nulo );auto d2 = createInstance ( 42 ); writeln ( d2 . field );deleteInstance ( d2 ); assert ( d2 es nulo ); }

Mejor C

El lenguaje de programación D tiene un subconjunto oficial conocido como " Better C ". [ 30 ] Este subconjunto prohíbe el acceso a características de D que requieren el uso de bibliotecas de tiempo de ejecución distintas a las de C.

Habilitada mediante las opciones del compilador "-betterC" en DMD y LDC, y "-fno-druntime" en GDC, Better C solo puede llamar a código D compilado con la misma opción (y código enlazado distinto de D), pero el código compilado sin la opción Better C puede llamar a código compilado con ella: sin embargo, esto dará lugar a comportamientos ligeramente diferentes debido a las diferencias en la forma en que C y D manejan las aserciones.

Características incluidas en Better C

  • Uso sin restricciones de las características de tiempo de compilación (por ejemplo, las características de asignación dinámica de D se pueden usar en tiempo de compilación para preasignar datos de D).
  • Funcionalidades completas de metaprogramación
  • Funciones anidadas, estructuras anidadas, delegados y expresiones lambda
  • Funciones miembro, constructores, destructores, sobrecarga operativa, etc.
  • El sistema de módulos completo
  • Segmentación de matrices y comprobación de límites de matrices
  • RAII
  • scope(exit)
  • protecciones de seguridad de la memoria
  • Interfaz con C++
  • Clases COM y clases C++
  • assertLos fallos se dirigen a la biblioteca de tiempo de ejecución de C.
  • switchcon cuerdas
  • final switch
  • unittestbloques
  • printf()validación de formato

Características excluidas de Better C

  • Recogida de basura
  • Información de tipo e información de módulo
  • Hilo incorporado (por ejemplo core.thread)
  • Matrices dinámicas (aunque funcionan las porciones de matrices estáticas) y matrices asociativas.
  • Excepciones
  • synchronizedycore.sync
  • Constructores o destructores de módulos estáticos

Historia

Walter Bright comenzó a trabajar en un nuevo lenguaje en 1999. D se lanzó por primera vez en diciembre de 2001 [ 1 ] y alcanzó la versión 1.0 en enero de 2007. [ 31 ] La primera versión del lenguaje (D1) se centró en los paradigmas imperativos, orientados a objetos y de metaprogramación, [ 32 ] similares a C++.

Algunos miembros de la comunidad D crearon una biblioteca estándar y de tiempo de ejecución alternativa llamada Tango, como alternativa a Phobos, la biblioteca estándar y de tiempo de ejecución oficial de D. El primer anuncio público de Tango se produjo pocos días después del lanzamiento de D 1.0. [ 33 ] Tango adoptó un estilo de programación diferente, incorporando la POO y una alta modularidad. Al ser un proyecto liderado por la comunidad, Tango era más abierto a las contribuciones, lo que le permitió progresar más rápido que la biblioteca estándar oficial. En ese momento, Tango y Phobos eran incompatibles debido a las diferentes API de soporte de tiempo de ejecución (el recolector de basura, el soporte de subprocesos, etc.). Esto hacía imposible usar ambas bibliotecas en el mismo proyecto. La existencia de dos bibliotecas ampliamente utilizadas significaba que algunos paquetes usaban Phobos y otros Tango, creando una incompatibilidad entre diferentes proyectos. [ 34 ]

En junio de 2007, se lanzó la primera versión de D2. [ 35 ] El inicio del desarrollo de D2 marcó la estabilización de D1. La primera versión del lenguaje se puso en mantenimiento, recibiendo únicamente correcciones y correcciones de errores de implementación. D2 introdujo cambios incompatibles con versiones anteriores del lenguaje, comenzando con su primer sistema `const` . Posteriormente, D2 añadió numerosas otras características del lenguaje, como cierres , pureza y soporte para los paradigmas de programación funcional y concurrente. D2 también resolvió problemas de la biblioteca estándar al separar el entorno de ejecución de la biblioteca estándar. La finalización de una adaptación de D2 a Tango se anunció en febrero de 2012. [ 36 ]

La publicación del libro de Andrei Alexandrescu , The D Programming Language, el 12 de junio de 2010, marcó la estabilización de D2, que hoy en día se conoce comúnmente simplemente como "D".

En enero de 2011, el desarrollo de D pasó de un sistema de seguimiento de errores y envío de parches a GitHub . Esto ha dado lugar a un aumento significativo de las contribuciones al compilador, el entorno de ejecución y la biblioteca estándar. [ 37 ]

En diciembre de 2011, Andrei Alexandrescu anunció que D1, la primera versión del lenguaje, se descontinuaría el 31 de diciembre de 2012. [ 38 ] El lanzamiento final de D1, D v1.076, fue el 31 de diciembre de 2012. [ 39 ]

El código del compilador oficial de D, el compilador Digital Mars D de Walter Bright, se publicó originalmente bajo una licencia personalizada , calificando como disponible como código fuente pero sin ajustarse a la Definición de Código Abierto . [ 40 ] En 2014, el front-end del compilador se volvió a licenciar como código abierto bajo la Licencia de Software Boost . [ 3 ] Este código re-licenciado excluía el back-end, que había sido desarrollado parcialmente en Symantec . El 7 de abril de 2017, el compilador completo se puso a disposición bajo la licencia Boost después de que Symantec diera permiso para re-licenciar también el back-end. [ 4 ] [ 41 ] [ 42 ] [ 43 ] El 21 de junio de 2017, el lenguaje D fue aceptado para su inclusión en GCC. [ 44 ]

Implementaciones

La mayoría de las implementaciones actuales de D se compilan directamente en código máquina .

Compiladores listos para producción:

  • DMD – El compilador Digital Mars D de Walter Bright es el compilador D oficial; de código abierto bajo la licencia Boost Software License . [ 3 ] [ 4 ] El frontend de DMD es compartido por GDC (ahora en GCC) y LDC, para mejorar la compatibilidad entre compiladores. Inicialmente, el frontend estaba escrito en C++, pero ahora la mayor parte está escrita en D (autoalojada). El backend y los optimizadores de código máquina se basan en el compilador Symantec. Al principio, solo admitía x86 de 32 bits, y Walter Bright añadió soporte para amd64 de 64 bits y PowerPC.
Bright dijo en 2020: "El proyecto más grande es implementar el compilador D en sí mismo en 100% D". [ 45 ] El backend y casi todo el compilador se portaron de C++ a D para un arranque completo .
  • GCC – The GNU Compiler Collection , fusionó GDC [ 46 ] en GCC 9 el 29 de octubre de 2018. [ 47 ] Las primeras versiones funcionales de GDC con GCC, basadas en GCC 3.3 y GCC 3.4 en x86 de 32 bits en Linux y macOS [ 48 ] se publicaron el 22 de marzo de 2004. Desde entonces, GDC ha obtenido soporte para plataformas adicionales, ha mejorado el rendimiento y ha corregido errores, al tiempo que ha seguido el código DMD ascendente para la especificación del frontend y del lenguaje. [ 49 ]
  • LDC – Un compilador basado en el front-end DMD que utiliza LLVM como back-end de compilación. La primera versión con calidad de lanzamiento se publicó el 9 de enero de 2009. [ 50 ] Admite la versión 2.0. [ 51 ]

Compiladores de juguete y de prueba de concepto:

  • Compilador D para .NET : un backend para el compilador del lenguaje de programación D 2.0. [ 52 ] [ 53 ] Compila el código a bytecode de Common Intermediate Language (CIL) en lugar de a código máquina. El CIL se puede ejecutar mediante una máquina virtual de Common Language Infrastructure (CLI) . El proyecto no se ha actualizado en años y el autor indicó que ya no está activo.
  • SDC – El compilador Snazzy D [ 54 ] utiliza un front-end personalizado y LLVM como back-end del compilador. Está escrito en D y utiliza un planificador para gestionar la resolución de símbolos para las características de tiempo de compilación de D. Este compilador actualmente admite un subconjunto limitado del lenguaje. [ 55 ] [ 56 ]

Utilizando los compiladores y cadenas de herramientas mencionados, es posible compilar programas D para diversas arquitecturas, incluyendo IA-32 , amd64 , AArch64 , PowerPC , MIPS64 , DEC Alpha , Motorola m68k , SPARC , s390 y WebAssembly . Los principales sistemas operativos compatibles son Windows y Linux , pero varios compiladores también admiten Mac OS X , FreeBSD , NetBSD , AIX , Solaris/OpenSolaris y Android , ya sea como host, destino o ambos. El destino WebAssembly (compatible mediante LDC y LLVM) puede operar en cualquier entorno WebAssembly, como un navegador web moderno ( Google Chrome , Mozilla Firefox , Microsoft Edge , Apple Safari ) o máquinas virtuales Wasm dedicadas.

Herramientas de desarrollo

Entre los editores y entornos de desarrollo integrados (IDE) que admiten resaltado de sintaxis y autocompletado parcial de código para el lenguaje se incluyen SlickEdit , Emacs , vim , SciTE , Smultron , Zeus, [ 57 ] y Geany, entre otros. [ 58 ]

Existen IDE de código abierto para Windows , algunos escritos en D, como Poseidon, [ 71 ] D-IDE, [ 72 ] y Entice Designer. [ 73 ]

Las aplicaciones D se pueden depurar con cualquier depurador de C/C++, como GNU Debugger (GDB) o WinDbg , aunque la compatibilidad con diversas características específicas del lenguaje D es extremadamente limitada. En Windows, los programas D se pueden depurar con Ddbg o con las herramientas de depuración de Microsoft (WinDBG y Visual Studio), tras convertir la información de depuración con cv2pdb . El depurador ZeroBUGS para Linux (archivado el 23 de diciembre de 2017 en Wayback Machine) ofrece compatibilidad experimental con el lenguaje D. Ddbg se puede usar con varios IDE o desde la línea de comandos; ZeroBUGS tiene su propia interfaz gráfica de usuario (GUI).

DustMite es una herramienta para minimizar el código fuente de D, útil para encontrar problemas de compilación o pruebas. [ 74 ]

dub es un gestor de paquetes y compilación popular para aplicaciones y bibliotecas D, y a menudo está integrado en el soporte del IDE. [ 75 ]

Usos

Entre las organizaciones destacadas que utilizan el lenguaje de programación D para sus proyectos se incluyen Facebook , [ 76 ] eBay , [ 77 ] y Netflix . [ 78 ]

D se ha utilizado con éxito para juegos AAA , [ 79 ] intérpretes de lenguaje, máquinas virtuales, [ 80 ] [ 81 ] un núcleo de sistema operativo , [ 82 ] programación de GPU , [ 83 ] desarrollo web , [ 84 ] [ 85 ] análisis numérico , [ 86 ] aplicaciones GUI , [ 87 ] [ 88 ] un sistema de información para pasajeros , [ 89 ] aprendizaje automático, [ 90 ] procesamiento de texto, servidores web y de aplicaciones e investigación.

El grupo de hackers norcoreano Lazarus explotó la vulnerabilidad CVE-2021-44228, también conocida como " Log4Shell ", para desplegar tres familias de malware escritas en DLang. [ 91 ]

Crítica

La falta de agilidad en el proceso de desarrollo y la dificultad para introducir cambios en el lenguaje D se describen en una entrada de blog [ 92 ] escrita por un antiguo colaborador. La frustración expresada allí dio lugar a la bifurcación de OpenD [ 93 ] el 1 de enero de 2024.

Véase también

Referencias

  1. 1 2 "Registro de cambios de D hasta el 7 de noviembre de 2005" . Lenguaje de programación D 1.0 . Digital Mars . Consultado el 1 de diciembre de 2011 .
  2. "Registro de cambios: 2.112.0" . 7 de enero de 2026.
  3. 1 2 3 "El front-end de dmd ahora usa la licencia Boost" . Consultado el 9 de septiembre de 2014 .
  4. 1 2 3 "dmd Backend convertido a licencia Boost" . 7 de abril de 2017. Consultado el 9 de abril de 2017 .
  5. "Preguntas frecuentes sobre D 2.0" . Consultado el 11 de agosto de 2015 .
  6. "Lenguaje de programación D - Fileinfo.com" . Consultado el 15 de noviembre de 2020 .
  7. "Lenguaje de programación D - dlang.org" . Consultado el 15 de noviembre de 2020 .
  8. "On: Show HN: Una buena API de cadenas de C" . Hacker News . 3 de diciembre de 2022. Consultado el 4 de diciembre de 2022 .
  9. Alexandrescu, Andrei (2010). El lenguaje de programación D (Primera ed.). Upper Saddle River, Nueva Jersey: Addison-Wesley. pág . 314. ISBN   978-0321635365.
  10. "Creando assert() en Swift, Parte 2: __FILE__ y __LINE__" . Archivado del original el 6 de octubre de 2014.
  11. "Introducción - Lenguaje de programación D" . dlang.org . Consultado el 21 de abril de 2024 . Este artículo incorpora texto de esta obra de contenido libre . Licenciado bajo BSL-1.0 ( declaración de licencia/permiso ).
  12. "Cadenas D vs. Cadenas C++" . Digital Mars. 2012.
  13. "Tipos complejos de D y std::complex de C++" . Digital Mars . 2012. Archivado del original el 13 de enero de 2008. Consultado el 4 de noviembre de 2021 .
  14. "Expresiones" . Digital Mars . Consultado el 27 de diciembre de 2012 .
  15. "std.gc" . Lenguaje de programación D 1.0 . Digital Mars . Consultado el 6 de julio de 2010 .
  16. "Gestión de memoria" . Lenguaje de programación D 2.0 . Digital Mars . Consultado el 17 de febrero de 2012 .
  17. 1 2 "Sigue tu propio camino (Parte uno: La pila)" . El blog D. 7 de julio de 2017. Consultado el 7 de mayo de 2020 .
  18. "Atributos - Lenguaje de programación D" . dlang.org . Consultado el 7 de mayo de 2020 .
  19. "std.experimental.allocator - Lenguaje de programación D" . dlang.org . Consultado el 7 de mayo de 2020 .
  20. Bartosz Milewski. "SafeD – Lenguaje de programación D" . Consultado el 17 de julio de 2014 .
  21. Steven Schveighoffer (28 de septiembre de 2016). "Cómo escribir código @trusted en D" . Consultado el 4 de enero de 2018 .
  22. "Punteros con ámbito" . GitHub . 3 de abril de 2020.
  23. "Referencias selladas" .
  24. "Especificación del lenguaje D: Funciones - Parámetros de ámbito de retorno" .
  25. "Propiedad y préstamos en D" . 15 de julio de 2019.
  26. "Especificación del lenguaje D: Funciones – Clases de almacenamiento de parámetros de función" .
  27. "PyD" . GitHub . 7 de mayo de 2020. Consultado el 7 de mayo de 2020 .
  28. Parker, Mike. "Paquete derelict-lua en DUB" . Registro de paquetes DUB . Consultado el 7 de mayo de 2020 .
  29. Parker, Mike. "Paquete bindbc-lua en DUB" . Registro de paquetes DUB . Consultado el 7 de mayo de 2020 .
  30. "Mejor C" .
  31. "Registro de cambios de D" . Lenguaje de programación D 1.0 . Digital Mars . Consultado el 11 de enero de 2012 .
  32. "Introducción" . Lenguaje de programación D 1.0 . Digital Mars . Consultado el 1 de diciembre de 2011 .
  33. "Anuncio de una nueva biblioteca" . Consultado el 15 de febrero de 2012 .
  34. "Wiki4D: Biblioteca estándar" . Consultado el 6 de julio de 2010 .
  35. "Registro de cambios – Lenguaje de programación D" . Lenguaje de programación D 2.0 . Fundación del lenguaje D. Consultado el 22 de noviembre de 2020 .
  36. "Tango para D2: Todos los módulos de usuario portados" . Consultado el 16 de febrero de 2012 .
  37. Walter Bright. "Re: ¿GitHub o dsource?" . Consultado el 15 de febrero de 2012 .
  38. Andrei Alexandrescu. "D1 se descontinuará el 31 de diciembre de 2012" . Consultado el 31 de enero de 2014 .
  39. "Registro de cambios de D" . Lenguaje de programación D 1.0 . Digital Mars . Consultado el 31 de enero de 2014 .
  40. "backendlicense.txt" . Código fuente de DMD . GitHub. Archivado del original el 25 de marzo de 2026. Recuperado el 5 de marzo de 2012 .
  41. "Comentario de Walter Bright en Reddit" . 5 de marzo de 2009. Consultado el 9 de septiembre de 2014 .
  42. D-Compiler-unter-freier-Lizenz en linux-magazin.de (2017, en alemán)
  43. Cambiar el backend a Boost Licencia #6680 de Walter Bright en github.com
  44. Idioma D aceptado para su inclusión en GCC
  45. Bright, Walter (26 de mayo de 2020). "Re: Dispositivo de Duff" . Hacker News . Consultado el 6 de abril de 2025 .
  46. "GDC" .
  47. "Serie de lanzamientos de GCC 9: cambios, nuevas características y correcciones - Proyecto GNU - Fundación del Software Libre (FSF)" . gcc.gnu.org . Consultado el 7 de mayo de 2020 .
  48. "Otro front-end para GCC" . forum.dlang.org . Consultado el 7 de mayo de 2020 .
  49. "Cambios, nuevas características y correcciones de la serie de lanzamientos de GCC 9" .
  50. "Proyecto del compilador LLVM D en GitHub" . GitHub . Consultado el 19 de agosto de 2016 .
  51. "BuildInstructionsPhobosDruntimeTrunk – ldc – D Programming Language – Trac" . Consultado el 11 de agosto de 2015 .
  52. "Proyecto D .NET en CodePlex" . Archivado del original el 26 de enero de 2018. Consultado el 3 de julio de 2010 .
  53. Jonathan Allen (15 de mayo de 2009). "El código fuente del compilador D.NET ya está disponible" . InfoQ . Consultado el 6 de julio de 2010 .
  54. "Convertir SDC en el compilador D elegante" . GitHub . Consultado el 24 de septiembre de 2023 .
  55. DConf 2014: SDC, un compilador D como biblioteca por Amaury Sechet . YouTube . Consultado el 8 de enero de 2014 .Archivado en Ghostarchivey la Wayback Machine
  56. ^ "deadalnix/COSUDE" . GitHub . Consultado el 8 de enero de 2014 .
  57. "Wiki4D: EditorSupport/ZeusForWindows" . Consultado el 11 de agosto de 2015 .
  58. "Wiki4D: Soporte para editores" . Consultado el 3 de julio de 2010 .
  59. "Basile.B / dexed" . GitLab . Consultado el 29 de abril de 2020 .
  60. "Mono-D - D Wiki" . wiki.dlang.org . Consultado el 30 de abril de 2020 .
  61. "Mono-D – Soporte D para MonoDevelop" . Archivado del original el 1 de febrero de 2012. Consultado el 11 de agosto de 2015 .
  62. "Alojamiento de proyectos de Google" . Consultado el 11 de agosto de 2015 .
  63. "descenso" . Consultado el 11 de agosto de 2015 .
  64. "Visual D - Lenguaje de programación D" . Consultado el 11 de agosto de 2015 .
  65. Schuetze, Rainer (17 de abril de 2020). "rainers/visuald: Visual D - Extensión de Visual Studio para el lenguaje de programación D" . github.com . Consultado el 30 de abril de 2020 .
  66. "dlang-vscode" . GitHub . Consultado el 21 de diciembre de 2016 .
  67. "code-d" . GitHub . Consultado el 21 de diciembre de 2016 .
  68. "Michel Fortin – D para Xcode" . Consultado el 11 de agosto de 2015 .
  69. "Dav1dde/lumen" . GitHub . Consultado el 11 de agosto de 2015 .
  70. Michael, Parker (7 de octubre de 2016). "Proyecto destacado: DlangUI" . El blog de D. Recuperado el 12 de septiembre de 2024 .
  71. "poseidón" . Consultado el 11 de agosto de 2015 .
  72. "Mono-D – Soporte D para MonoDevelop" . Consultado el 11 de agosto de 2015 .
  73. "Entice Designer – Dprogramming.com – El lenguaje de programación D" . Consultado el 11 de agosto de 2015 .
  74. "¿Qué es DustMite?" . GitHub . Consultado el 29 de abril de 2020 .
  75. "dlang/dub: Sistema de gestión de paquetes y compilación para D" . GitHub . Consultado el 29 de abril de 2020 .
  76. "Bajo el capó: warp, un preprocesador rápido para C y C++" . 28 de marzo de 2014. Consultado el 4 de enero de 2018 .
  77. "Herramientas de línea de comandos más rápidas en D" . 24 de mayo de 2017. Consultado el 4 de enero de 2018 .
  78. Blog, Netflix Technology (2 de agosto de 2017). "Presentando Vectorflow" . Medium . Consultado el 4 de enero de 2018 .
  79. "Quantum Break: Juegos AAA con algo de código D" . Consultado el 4 de enero de 2018 .
  80. "Máquina virtual JavaScript de Higgs" . GitHub . Consultado el 4 de enero de 2018 .
  81. "Implementación AD del lenguaje de programación ECMA 262 (Javascript)" . GitHub . Consultado el 4 de enero de 2018 .
  82. "Proyecto destacado: El núcleo PowerNex" . 24 de junio de 2016. Consultado el 4 de enero de 2018 .
  83. "DCompute: Ejecutando D en la GPU" . 30 de octubre de 2017. Consultado el 4 de enero de 2018 .
  84. "vibe.d - un conjunto de herramientas de alto rendimiento para E/S asíncrona, concurrencia y aplicaciones web escrito en D" . Consultado el 4 de enero de 2018 .
  85. "Proyecto destacado: Marco de trabajo Diamond MVC" . 20 de noviembre de 2017. Consultado el 4 de enero de 2018 .
  86. "La edad numérica para D: Mir GLAS es más rápida que OpenBLAS y Eigen" . Consultado el 4 de enero de 2018 .
  87. "Sobre Tilix y D: Una entrevista con Gerald Nunn" . 11 de agosto de 2017. Consultado el 4 de enero de 2018 .
  88. "Proyecto destacado: DlangUI" . 7 de octubre de 2016. Consultado el 4 de enero de 2018 .
  89. "Proyecto destacado: Funkwerk" . 28 de julio de 2017. Consultado el 4 de enero de 2018 .
  90. "Netflix/vectorflow" . GitHub.com . Netflix, Inc. 5 de mayo de 2020. Consultado el 7 de mayo de 2020 .
  91. "Los hackers de Lazarus lanzan un nuevo malware RAT utilizando una vulnerabilidad de Log4j de hace dos años" . 11 de diciembre de 2023. Consultado el 11 de diciembre de 2023 .
  92. "Un barco que transportaba cubiertos de plata ha zarpado" . Consultado el 6 de mayo de 2024 .
  93. "El lenguaje de programación OpenD" . Consultado el 14 de mayo de 2024 .

Lecturas adicionales

  • Alexandrescu, Andrei (4 de enero de 2010). El lenguaje de programación D (1.ª  ed.). Addison-Wesley Professional. ISBN 978-0-321-63536-5.
  • Alexandrescu, Andrei (15 de junio de 2009). "El caso de D" . Diario del Dr. Dobb.
  • Bright, Walter (8 de abril de 2014). "Cómo llegué a escribir D" . Dr. Dobb's Journal.
  • Çehreli, Ali (1 de febrero de 2012). "Programación en D" .(Distribuido bajo la licencia CC-BY-NC-SA). Este libro enseña programación a principiantes, pero también abarca muchos temas avanzados de D.
  • Metz, Cade (7 de julio de 2014). "El próximo gran lenguaje de programación del que nunca has oído hablar" . Wired .
  • Ruppe, Adam (mayo de 2014). D Libro de cocina (1  ed.). Editorial PAQUETE. ISBN 978-1-783-28721-5.
  • Sitio web oficialEdita esto en Wikidata
  • Marte digital
  • Foro Turco
  • Dlang en GitHub