X-Git-Url: https://git.llucax.com/z.facultad/75.00/informe.git/blobdiff_plain/6eef2aaa7b3487663baa7e365eadb948ad2f1efd..HEAD:/source/d.rst?ds=inline diff --git a/source/d.rst b/source/d.rst index ceb8a2a..426a800 100644 --- a/source/d.rst +++ b/source/d.rst @@ -1,10 +1,4 @@ -.. Introducción y breve reseña del lenguaje de programación D. También - se presentan las necesidades particulares de D con respecto al - recolector de basura y su estado actual. - ESTADO: TERMINADO, CORREGIDO (A) - - .. highlight:: d .. _d_lang: @@ -31,7 +25,8 @@ compilaba a código nativo, y está fuertemente influenciado por éste. Sin embargo toma muchos conceptos de otros lenguajes de más alto nivel, como Java_ o incluso lenguajes dinámicos como Perl_, Python_ y Ruby_. -El origen del lenguaje está plasmado en su sitio web, en donde se cita: +El origen del lenguaje está plasmado en su sitio web, en donde se cita +[DWEB]_: It seems to me that most of the "new" programming languages fall into one of two categories: Those from academia with radical new paradigms and those @@ -146,7 +141,7 @@ mayores problemas. Una gran diferencia con C++ es que el análisis sintáctico (*parsing*) se puede realizar sin ningún tipo de análisis semántico, dado que a diferencia de éstos su gramática es libre de contexto (*context-free grammar*). Esto acelera -y simplifica considerablemente el proceso de compilación. +y simplifica considerablemente el proceso de compilación [WBB10]_ [DWOV]_. Otra gran diferencia es que D_ decide incluir recolección de basura como parte del lenguaje, mientras que en el comité de estandarización de C++ nunca se @@ -157,7 +152,7 @@ Características del lenguaje ---------------------------------------------------------------------------- A continuación se enumeran las principales características de D_, agrupadas -por unidades funcionales o paradigmas que soporta: +por unidades funcionales o paradigmas que soporta [DWLR]_: @@ -187,18 +182,17 @@ y meta-programación: ``if`` estático (``static if``) Esta construcción es similar a la directiva del preprocesador de C/C++ ``#if``, pero a diferencia de éste, el ``static if`` de D_ tiene acceso - a todos los símbolos del compilador (constantes, tipos, variables, etc). + a todos los símbolos del compilador (constantes, tipos, variables, etc) + [DWSI]_. Ejemplo:: static if ((void*).sizeof == 4) pragma(msg, "32 bits"); - Más información en http://www.digitalmars.com/d/1.0/version.html#staticif - Inferencia de tipos básica implícita y explícita (mediante ``typeof``) Si no se especifica un tipo al declarar una variable, se infiere a partir - del tipo de su valor de inicialización. + del tipo de su valor de inicialización [DWIN]_. Ejemplo:: @@ -206,22 +200,17 @@ Inferencia de tipos básica implícita y explícita (mediante ``typeof``) const d = 6.0; // d es double auto s = "hola"; // s es string (que es un alias de char[]) - Más información en - http://www.digitalmars.com/d/1.0/declaration.html#AutoDeclaration - Mediante el uso de ``typeof`` se puede solicitar el tipo de una expresión - arbitraria. + arbitraria [DWTO]_. Ejemplo:: typeof(5 + 6.0) d; // d es double - Más información en http://www.digitalmars.com/d/1.0/declaration.html#typeof - Iteración sobre colecciones (``foreach``) Cualquier tipo de colección (arreglos estáticos y dinámicos, arreglos asociativos, clases, estructuras o delegados) puede ser iterada mediante la - sentencia ``foreach``. + sentencia ``foreach`` [DWFE]_. Ejemplo:: @@ -235,7 +224,7 @@ Iteración sobre colecciones (``foreach``) algoritmos genéricos sin importar el tipo de los datos de entrada, siempre y cuando todos los tipos tengan una *interfaz* común. Esto también es conocido como *polimorfismo en tiempo de compilación*, y es la forma más - básica de programación genérica. + básica de programación genérica [DWTP]_. Ejemplo:: @@ -285,12 +274,14 @@ Iteración sobre colecciones (``foreach``) Ejemplo de especialización:: + T sumar(T)(T x, T y) { return x + y; } T sumar(T: int)(T x, T y) { return x + y + 1; } auto i = sumar(5, 6); // i == 12 auto f = sumar(5.0f, 6.0f) // f == 11.0f Ejemplo de especialización parcial:: + T sumar(T)(T x, T y) { return x + y; } T sumar(T: T*)(T x, T y) { return *x + *y; } int x = 5, y = 6; auto i = sumar(&x, &y); // i == 11 @@ -334,7 +325,7 @@ Iteración sobre colecciones (``foreach``) tiempo de ejecución. Esto permite hacer algunos cálculos que no cambian de ejecución en ejecución al momento de compilar, mejorando el rendimiento o permitiendo formas avanzadas de meta-programación. Esta característica se - vuelve particularmente útil al combinarse con *string mixins*. + vuelve particularmente útil al combinarse con *string mixins* [DWCF]_. Ejemplo:: @@ -355,7 +346,7 @@ Iteración sobre colecciones (``foreach``) declaraciones e insertarla en el contexto (*scope*) actual. Esto puede realizarse a nivel global, en clases, estructuras o funciones. Esto sirve como un mecanismo para evitar duplicación de código que puede ser - introducida por la falta de herencia múltiple. + introducida por la falta de herencia múltiple [DWMT]_. Ejemplo:: @@ -377,7 +368,7 @@ Iteración sobre colecciones (``foreach``) contenga un fragmento de código en un programa como si este fragmento hubiera sido escrito en el código fuente directamente por el programador. Esto permite hacer manipulaciones arbitrariamente complejas en combinación - con funciones ejecutadas en tiempo de compilación. + con funciones ejecutadas en tiempo de compilación [DWME]_ [DWMX]_. Ejemplo:: @@ -386,14 +377,12 @@ Iteración sobre colecciones (``foreach``) } int sumar(int a, int b) { - mixin(generar_sumar!("a", b")); + mixin(generar_sumar!("a", "b")); } - Más información en http://www.digitalmars.com/d/1.0/mixin.html - Expresiones ``is`` Las *expresiones ``is``* permiten la compilación condicional basada en las - características de un tipo. + características de un tipo [DWIE]_. Ejemplo:: @@ -406,9 +395,6 @@ Expresiones ``is`` Esto provee además una forma simple de reflexión en tiempo de compilación. - Más información en - http://www.digitalmars.com/d/1.0/expression.html#IsExpression - .. _d_low_level: @@ -425,7 +411,7 @@ D_ presenta muchas características de bajo nivel: Compila a código de máquina nativo Los programas generados por D_ no son interpretados ni necesitan una máquina virtual como otros lenguajes de más alto nivel como Java_, `C#`_, - Python_, etc. + Python_, etc [DWOV]_. *Assembly* empotrado Provee acceso directo al *hardware* y la posibilidad de utilizar cualquier @@ -434,15 +420,16 @@ Compila a código de máquina nativo Una ventaja sobre C y C++ es que el lenguaje *assembly* utilizado dentro de D_ está especificado, por lo que se puede mantener la portabilidad entre compiladores incluso cuando se utiliza *assembly* (mientras que no se - cambie de arquitectura, por supuesto). + cambie de arquitectura, por supuesto) [DWIA]_. ``goto`` - Al igual que C y C++, D_ provee la flexibilidad del uso de ``goto``. + Al igual que C y C++, D_ provee la flexibilidad del uso de ``goto`` + [DWGT]_. Compatibilidad con C Soporta todos los tipos de C y es ABI [#abi]_ compatible con éste. Esto permite enlazar archivos objeto estándar de C y D_ en un mismo programa. - Además permite interoperar con C a través de ``extern (C)``. + Además permite interoperar con C a través de ``extern (C)`` [DWCC]_. .. [#abi] Interfaz de Aplicación Binaria (del inglés *Application Binary Interface*). @@ -454,7 +441,7 @@ Compatibilidad con C Manejo de memoria explícito Permite asignar estructuras en el *stack* o en el *heap*, haciendo uso de - los servicios del sistema operativo o la biblioteca estándar de C. + los servicios del sistema operativo o la biblioteca estándar de C [DWMM]_. Objetos y arreglos *livianos* Por objetos *livianos* se entiende no-polimórficos. Es decir, un @@ -462,7 +449,7 @@ Objetos y arreglos *livianos* otro tipo de *overhead*. Los arreglos *livianos* son arreglos estáticos como en C, cuyo tamaño es fijo, también sin ningún tipo de *overhead* como C. Además puede asignarse un arreglo dinámicamente usando ``malloc()`` - y utilizar el operador ``[]`` para accederlo. + y utilizar el operador ``[]`` para accederlo [DWST]_ [DWCL]_. Esto también permite interoperar con C, ya que pueden definirse ``structs`` y arreglos que pueden ser intercambiados con dicho lenguaje sin problemas. @@ -488,15 +475,15 @@ Objetos y arreglos *livianos* Rendimiento La :ref:`d_generic` permite realizar muchas optimizaciones ya que se resuelve en tiempo de compilación y por lo tanto aumenta el rendimiento en - la ejecución. + la ejecución [DWTP]_. Número de punto flotante de 80 bits El tipo ``real`` de D_ tiene precisión de 80 bits si la plataforma lo - soporta (por ejemplo en i386). + soporta (por ejemplo en i386) [DWTY]_. Control de alineación de miembros de una estructura Mediante ``align`` se puede especificar la alineación a tener en una - estructura. + estructura [DWAL]_. Ejemplo:: @@ -516,7 +503,7 @@ Programación de alto nivel Programación de alto nivel se refiere a construcciones más avanzadas que una sentencia para iterar; expresiones con una semántica más ricas que proveen de -mayor expresividad al programador o le permiten focalizarse de mejora manera +mayor expresividad al programador o le permiten focalizarse de mejor manera en los algoritmos independizándose del *hardware* o de como funciona una computadora. Es exactamente el opuesto a :ref:`d_low_level`. @@ -528,7 +515,7 @@ Manejo automático de memoria Al igual que C/C++ y prácticamente cualquier lenguaje imperativo maneja automáticamente el *stack*, pero a diferencia de la mayoría de los lenguajes de bajo nivel, D_ permite manejar el *heap* de manera automática - también a través de un *recolector de basura*. + también a través de un *recolector de basura* [DWGC]_. Sistema de paquetes y módulos (similar a Java_ o Python_) Un módulo es una unidad que agrupa clases, funciones y cualquier otra @@ -536,7 +523,7 @@ Sistema de paquetes y módulos (similar a Java_ o Python_) asocia un módulo a un archivo fuente (y un archivo objeto cuando éste es compilado) y un paquete a un directorio. A diferencia de C/C++ no necesita de un preprocesador para incluir declaraciones de otros *módulos* (en C/C++ - no existe el concepto de módulo, solo de unidades de compilación). + no existe el concepto de módulo, solo de unidades de compilación) [DWMO]_. Ejemplo: @@ -565,7 +552,7 @@ Funciones y delegados entrada, salida o entrada/salida, argumentos por omisión o argumentos evaluados de forma perezosa (*lazy*). Además pueden tener una cantidad de argumentos variables pero manteniendo información de tipos (más seguro que - C/C++). + C/C++) [DWFU]_. Los *delegados* son punteros a función con un contexto asociado. Este contexto puede ser un objeto (en cuyo caso la función es un método) o un @@ -610,10 +597,11 @@ Arreglos *dinámicos* y arreglos asociativos Los arreglos *dinámicos* son arreglos de longitud variable manejados automáticamente por el lenguaje (análogos al ``std::vector`` de C++). Soportan concatenación (a través del operador ``~``), rebanado o *slicing* - (a través del operador ``[x..y]``) y chequeo de límites (*bound checking*). + (a través del operador ``[x..y]``) y chequeo de límites (*bound checking*) + [DWAR]_. Los arreglos asociativos (también conocidos como *hashes* o diccionarios) - también son provistos por el lenguaje. + también son provistos por el lenguaje [DWAA]_. Ambos son ciudadanos de primera clase, disponiendo de forma literal. @@ -629,7 +617,7 @@ Arreglos *dinámicos* y arreglos asociativos Al igual que los delegados y arreglos dinámicos y asociativos, los *strings* son ciudadanos de primera clase, teniendo forma literal y siendo codificados en UTF-8/16/32. Son un caso particular de arreglo dinámico y es - posible utilizarlos en sentencias ``switch``/``case``. + posible utilizarlos en sentencias ``switch``/``case`` [DWSR]_. Ejemplo:: @@ -648,7 +636,7 @@ Arreglos *dinámicos* y arreglos asociativos valores literales), pero la conversión es válida en el otro sentido (similar a los ``enum`` en C++). Por el contrario, ``alias`` es análogo al ``typedef`` de C/C++ y simplemente es una forma de referirse al mismo tipo - con un nombre distinto. + con un nombre distinto [DWDC]_. Ejemplo:: @@ -666,13 +654,11 @@ Documentación embebida D_ provee un sistema de documentación embebida, análogo a lo que proveen Java_ o Python_ en menor medida. Hay comentarios especiales del código que pueden ser utilizados para documentarlo de forma tal que luego el - compilador pueda extraer esa información para generar un documento. - - Más información en http://www.digitalmars.com/d/1.0/ddoc.html + compilador pueda extraer esa información para generar un documento [DWDO]_. Números complejos D_ soporta números complejos como ciudadanos de primera clase. Soporta - forma literal de números imaginarios y complejos. + forma literal de números imaginarios y complejos [DWTY]_. Ejemplo:: @@ -698,7 +684,7 @@ Objetos *pesados* *overhead* comparados a los objetos *livianos* pero aseguran una semántica segura para trabajar con orientación a objetos, evitando problemas con los que se enfrenta C++ (como *slicing* [#dslicing]_) debido a que permite - semántica por valor [#dvalsem]_. + semántica por valor [#dvalsem]_ [DWCL]_. .. [#drefsem] Semántica de referencia significa que el tipo es tratado como si fuera un puntero. Nunca se hacen copias del objeto, siempre se pasa @@ -715,7 +701,7 @@ Objetos *pesados* D_ además soporta tipos de retorno covariantes para funciones virtuales. Esto significa que una función sobreescrita por una clase derivada puede retornar un tipo que sea derivado del tipo retornado por la función - original sobreescrita. + original sobreescrita [DWFU]_. Ejemplo:: @@ -730,8 +716,6 @@ Objetos *pesados* B test() { return null; } // sobreescribe y es covariante con Foo.test() } - Más información en http://www.digitalmars.com/d/1.0/function.html - Interfaces D_ no soporta herencia múltiple pero sí interfaces. Una interfaz es básicamente una tabla virtual, una definición de métodos virtuales que debe @@ -740,17 +724,17 @@ Interfaces se pierde flexibilidad porque puede conseguirse el mismo efecto de tener herencia múltiple a través de interfaces y *mixins* para proveer una implementación o atributos en común a varias clases que implementan la - misma interfaz. + misma interfaz [DWIF]_. Sobrecarga de operadores La sobrecarga de operadores permite que un objeto tenga una sintaxis similar a un tipo de dato nativo. Esto es muy importante además para la - programación genérica. + programación genérica [DWOO]_. Clases anidadas Al igual que C (con respecto a ``struct``) y C++, pueden anidarse clases dentro de clases. D_ sin embargo provee la posibilidad de acceder - a atributos de la instancia exterior desde la anidada. + a atributos de la instancia exterior desde la anidada [DWNC]_. Ejemplo:: @@ -784,7 +768,7 @@ Clases anidadas Propiedades (*properties*) En D_ se refiere a funciones miembro que pueden ser tratadas - sintácticamente como campos de esa clase/estructura. + sintácticamente como campos de esa clase/estructura [DWPR]_. Ejemplo:: @@ -807,17 +791,17 @@ Propiedades (*properties*) Valor de inicialización por omisión (ejemplo: ``float.init`` -> *NaN* [#dnan]_). - .. [#dnan] Del inglés *Not A Number*, es un valor especial que indica que - estamos ante un valor inválido. + .. [#dnan] Del inglés *Not A Number*, es un valor especial codificado según + IEEE 754-2008 [IEEE754]_ que indica que estamos ante un valor inválido. ``stringof`` Representación textual del símbolo o expresión (ejemplo: ``(1+2).stringof`` -> ``"1 + 2"``). ``mangleof`` - Representación textual del tipo *mutilado* [#dmangle]_. + Representación textual del tipo *mutilado* [#dmangle]_ [DWAB]_. - .. [#dmangle] *Name mangling* es el nombre dado comunmente a una técnica + .. [#dmangle] *Name mangling* es el nombre dado comúnmente a una técnica necesaria para poder sobrecargar nombres de símbolos. Consiste en codificar los nombres de las funciones tomando como entrada el nombre de la función y la cantidad y tipo de parámetros, asegurando que dos @@ -830,11 +814,6 @@ Propiedades (*properties*) Estos son solo los *properties* predefinidos para todos los tipos, pero hay una cantidad considerable de *properties* extra para cada tipo. - Más información sobre *properties* de clases en - http://www.digitalmars.com/d/1.0/property.html#classproperties y sobre - *properties* predefinidos en - http://www.digitalmars.com/d/1.0/property.html - .. _d_dbc: @@ -850,7 +829,7 @@ a esto y provee las siguientes herramientas: Excepciones D_ soporta excepciones de manera similar a Java_: provee ``try``, ``catch`` y ``finally``. Esto permite que los errores difícilmente pasen - silenciosamente sin ser detectados. + silenciosamente sin ser detectados [DWEX]_. ``assert`` Es una condición que debe cumplirse siempre en un programa, como un chequeo @@ -859,9 +838,9 @@ Excepciones Esto permite eliminar los chequeos de integridad del programa, que pueden ser costosos, para versiones que se suponen estables. - D_ lleva este concepto más allá y hace al ``assert`` parte del lenguaje. - Si una verificación no se cumple, lanza una excepción. El ``assert`` no es - compilado cuando se utiliza una opción del compilador. + D_ lleva este concepto más allá y hace al ``assert`` parte del lenguaje + [DWCP]_. Si una verificación no se cumple, lanza una excepción. El + ``assert`` no es compilado cuando se utiliza una opción del compilador. Ejemplo:: @@ -876,7 +855,7 @@ Diseño por contrato D_ implementa las siguientes formas de diseño por contrato (todas se ejecutan siempre y cuando no se compile en modo *release*, de manera de no - sacrificar rendimiento cuando es necesario): + sacrificar rendimiento cuando es necesario) [DWCP]_: Pre y post condiciones Ejemplo:: @@ -916,12 +895,10 @@ Diseño por contrato } } - Más información en http://www.digitalmars.com/d/1.0/dbc.html - Pruebas unitarias Es posible incluir pequeñas pruebas unitarias en el lenguaje. Éstas son ejecutadas (cuando no se compila en modo *release*) al comenzar el - programa, antes de que la función ``main()``. + programa, antes de que la función ``main()`` [DWUT]_. Ejemplo:: @@ -939,14 +916,14 @@ Orden de construcción estática ejemplo, instancias globales con un constructor definido. C++ no garantiza un orden de inicialización, lo que trae muchos problemas. En D_ se define el orden de inicialización y es el mismo orden en que el usuario importa - los módulos. + los módulos [DWMO]_. Inicialización garantizada Todas las variables son inicializadas por el lenguaje (a menos que el - usuario pida explícitamente que no lo sean). Siempre que sea posible se - elijen valores de inicialización que permitan saber al programador que la - variable no fue inicializada explícitamente, de manera de poder detectar - errores de manera temprana. + usuario pida explícitamente que no lo sean) [DWTY]_ [DWVI]_. Siempre que + sea posible se elijen valores de inicialización que permitan saber al + programador que la variable no fue inicializada explícitamente, de manera + de poder detectar errores de manera temprana. Ejemplo:: @@ -969,7 +946,7 @@ Inicialización garantizada basura (en la mayoría de los casos el recurso a administrar es sencillamente memoria). Sin embargo en los casos en donde es necesario, puede utilizarse *RAII* mediante la utilización de la palabra reservada - ``scope``, que limita la vida de un objeto un bloque de código. + ``scope``, que limita la vida de un objeto a un bloque de código [DWES]_. Ejemplo:: @@ -985,7 +962,8 @@ Inicialización garantizada Guardias de bloque (*scope guards*) Además de poder limitar la vida de una instancia a un *scope*, es posible especificar un bloque de código arbitrario a ejecutar al abandonar un - *scope*, ya sea cuando se sale del *scope* normalmente o por una falla. + *scope*, ya sea cuando se sale del *scope* normalmente o por una falla + [DWES]_. Ejemplo:: @@ -1016,7 +994,7 @@ Primitivas de sincronización de hilos cuyo caso se utiliza un *lock* por clase para sincronizar) o como una sentencia, en cuyo caso se crea un *lock* global por cada bloque ``synchronized`` a menos que se especifique sobre qué objeto realizar la - sincronización. Por ejemplo:: + sincronización [DWSY]_. Por ejemplo:: class Foo { synchronized void bar() { /* cuerpo */ }