]> git.llucax.com Git - z.facultad/75.00/informe.git/blobdiff - source/d.rst
Actualizar historia de D y elección del compilador
[z.facultad/75.00/informe.git] / source / d.rst
index 15334bd9a1bdde8b80caf259b7c7981b25303dfa..4b411d8e3b0c4768832da2d6d73b54a94b72c698 100644 (file)
@@ -2,7 +2,7 @@
 .. 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
+   ESTADO: TERMINADO, CORREGIDO (A)
 
 
 .. _d_lang:
@@ -15,27 +15,26 @@ Historia
 ----------------------------------------------------------------------------
 
 D_ es un lenguaje de programación relativamente joven. Nació en 1999 y el
-2 de enero de 2007 salió su `versión 1.0`__. Poco tiempo después se
-continúo el desarrollo del lenguaje en la `versión 2.0`__, aún inestable
-y en la cual se está experimentando principalmente sobre
-multi-procesamiento.
+2 de enero de 2007 salió su `versión 1.0`__. Poco tiempo después se continúo
+el desarrollo del lenguaje en la `versión 2.0`__, que pasó a ser considerada
+estable aproximadamente en junio de 2010 con el lanzamiento del libro "The
+D Programming Language" [ALX10]_, pero aún es un trabajo en progreso.
 
 __ `D 1.0`_
 __ `D 2.0`_
 
 El lenguaje fue diseñado e implementado por `Walter Bright`_, desarrollador
-principal de Zortech C++, uno de los primeros compilador de C++ que
-compilaba a código nativo, y está fuertemente influenciado éste. Sin
-embargo toma muchos conceptos de otros lenguajes de más alto nivel, como
-Java_ o incluso lenguajes dinámicos como Perl_.
+principal de Zortech C++, uno de los primeros compiladores de C++ que
+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:
 
-   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 from large corporations with a focus on RAD and the web. Maybe
-   it's time for a new language born out of practical experience
-   implementing compilers.
+   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
+   from large corporations with a focus on RAD and the web. Maybe it's time
+   for a new language born out of practical experience implementing compilers.
 
 Esto podría traducirse como:
 
@@ -45,79 +44,78 @@ Esto podría traducirse como:
    y web. Tal vez es hora de que nazca un nuevo lenguaje de la experiencia
    práctica implementando compiladores.
 
-La versión 1.0 fue más bien una etiqueta arbitraria que un indicador real
-de estar ante una versión estable y completa. Luego de liberarse se
-siguieron agregando nuevas características al lenguaje hasta que se empezó
-el desarrollo en paralelo de la versión 2.0 al introducirse el concepto de
-inmutabilidad y funciones *puras* [#dpure]_ (a mediados de 2007).
+La versión 1.0 fue más bien una etiqueta arbitraria que un indicador real de
+estabilidad y completitud. Luego de liberarse se siguieron agregando nuevas
+características al lenguaje hasta que se empezó el desarrollo en paralelo de
+la versión 2.0 al introducirse el concepto de inmutabilidad y funciones
+*puras* [#dpure]_ (a mediados de 2007).
 
 .. [#dpure] Por funciones *puras* en D_ se entiende que no tienen efectos
-   colaterales. Es decir, una función pura siempre que se llame con la
-   misma entrada producirá el mismo resultado. Esto es análogo a como
-   funcionan los lenguajes funcionales en general, abríendo la puerta a la
-   programación de estilo funcional en
-   D_.
+   colaterales. Es decir, una función pura siempre que se llame con la misma
+   entrada producirá el mismo resultado. Esto es análogo a como funcionan los
+   lenguajes funcionales en general, abriendo la puerta a la programación de
+   estilo funcional en D_.
 
 A partir de este momento la versión 1.0 quedó *teóricamente* congelada,
-introduciendo solo cambios que arreglen errores (*bug fixes*),
-introduciendo todos las nuevas características solamente en la versión
-2.0 del lenguaje. La realidad es que se hicieron cambios incompatibles a la
-versión 1.0 del lenguaje en reiteradas ocasiones, pero se fue tendiendo
-a cada vez introducir menos cambios incompatibles. Sin embargo al día de
-hoy el compilador de referencia sigue teniendo algunas características
-presentes en la especificación del lenguaje sin implementar, por lo que
-todavía no hay una implementación completa de la versión 1.0 del lenguaje,
-siendo esta etiqueta todavía un poco arbitraria.
+introduciendo solo cambios que arreglen errores (*bug fixes*), agregando
+nuevas características solamente en la versión 2.0 del lenguaje. La realidad
+es que se hicieron cambios incompatibles a la versión 1.0 del lenguaje en
+reiteradas ocasiones, pero se fue tendiendo a cada vez introducir menos
+cambios incompatibles. Sin embargo al día de hoy el compilador de referencia
+sigue teniendo algunas características presentes en la especificación del
+lenguaje sin implementar, por lo que todavía no hay una implementación
+completa de la versión 1.0 del lenguaje.
 
 El lenguaje ha sido, hasta el desarrollo de la versión 2.0 al menos, un
 esfuerzo unipersonal de `Walter Bright`_, dados sus problemas a la hora de
-delegar o aceptar contribuciones. Esto motivó a la comunidad de usuarios de
-D_ a crear bibliotecas base alternativas a la estándar (llamada Phobos_) en
-las cuales se pudiera trabajar sin las trabas impuestas por el autor del
-lenguaje.
+delegar o aceptar contribuciones. Esto motivó a la comunidad de usuarios de D_
+a crear bibliotecas base alternativas a la estándar (llamada Phobos_) en las
+cuales se pudiera trabajar sin las trabas impuestas por el autor del lenguaje.
 
 En este contexto nacen primero Mango_ y luego Ares_. Mango_ fue creada por
 Kris Macleod Bell a principios de 2004 como una biblioteca que provee
-servicios básicos de entrada/salida (o *I/O* de *input/output* en inglés)
-de alto rendimiento.   Siendo estos servicios algo básico lo más natural
-hubiera sido que se encuentren en la biblioteca estándar de D_ pero por las
+servicios básicos de entrada/salida (o *I/O* de *input/output* en inglés) de
+alto rendimiento.   Siendo estos servicios algo básico lo más natural hubiera
+sido que se encuentren en la biblioteca estándar de D_ pero por las
 dificultades para contribuir a ésta, se desarrolla como una biblioteca
 separada.   A mediados de 2004 Sean Kelly crea Ares_ , con las mismas
-motivaciones pero con la intención de crear una biblioteca base (conocida
-en inglés como *runtime*) que incluye los servicios básicos que necesita el
+motivaciones pero con la intención de crear una biblioteca base (conocida en
+inglés como *runtime*) que incluye los servicios básicos que necesita el
 lenguaje (información de tipos, manejo de excepciones e hilos, creación
 y manipulación de objetos, recolector de basura, etc.). Al poco tiempo de
 liberarse Ares_, Mango_ empieza a utilizarla como biblioteca base.
 
-Para comienzos de 2006, se empieza a trabajar en la combinación de
-ambas bibliotecas para lograr una biblioteca estándar alternativa
-con un alto grado de cohesión. Finalmente a principios de 2007,
-coincidiendo por casualidad con la aparición de D_ 1.0, se anuncia el
-resultado de este combinación bajo el nombre de Tango_, proveyendo una
-alternativa completa y madura a la biblioteca estándar de D_ Phobos_.
-A principios de 2008 los principales desarrolladores de Tango_ (Kris Bell,
-Sean Kelly, Lars Ivar Igesund y Michael Parker publican el libro llamado
-`Learn to Tango with D`_.
-
-Esto por un lado fue un gran avance porque dio un impulso muy considerable
-al lenguaje pero por otro un gran retroceso, porque todavía al día de hoy
-D_ 1.0 tiene 2 bibliotecas base, una estándar pero de peor calidad y menos
-mantenida y una alternativa de mayor calidad y apertura a la comunidad
-(pero no estándar). El peor problema es que ambas son **incompatibles**,
-por lo que un programa hecho con Tango_ no funciona con Phobos_ y viceversa
-(a menos que el programador haya invertido una cantidad de tiempo no
-trivial en asegurarse de que funcione con ambas).
+Para comienzos de 2006, se empieza a trabajar en la combinación de ambas
+bibliotecas para lograr una biblioteca estándar alternativa con un alto grado
+de cohesión. Finalmente a principios de 2007, coincidiendo por casualidad con
+la aparición de `D 1.0`_, se anuncia el resultado de este combinación bajo el
+nombre de Tango_, proveyendo una alternativa completa y madura a la biblioteca
+estándar de D_ Phobos_.  A principios de 2008 los principales desarrolladores
+de Tango_ (Kris Bell, Sean Kelly, Lars Ivar Igesund y Michael Parker) publican
+el libro llamado `Learn to Tango with D`_ [BKIP08]_.
+
+Esto por un lado fue un gran avance porque dio un impulso muy considerable al
+lenguaje pero por otro un gran retroceso, porque todavía al día de hoy `D
+1.0`_ tiene dos bibliotecas base, una estándar pero de peor calidad, menos
+mantenida y usada; y una alternativa de mayor calidad y apertura a la
+comunidad (pero no estándar). El peor problema es que ambas son
+**incompatibles**, por lo que un programa hecho con Tango_ no funciona con
+Phobos_ y viceversa (a menos que el programador haya invertido una cantidad de
+tiempo considerable en asegurarse de que funcione con ambas).
 
 Esto hace que la compatibilidad de programas y bibliotecas esté muy
-fragmentada entre las 2 bibliotecas base. Si bien no parece que vaya
-a haber solución alguna a este problema para D 1.0, D 2.0 va en camino
-a solucionar este problema ya que utiliza DRuntime_, un nuevo intento de
-Sean Kelly por proveer una biblioteca *runtime* bien organizada
-y mantenida, que es una adaptación de la biblioteca *runtime* de Tango_
-a D 2.0. Si bien todavía Tango_ no fue adaptada a D 2.0, se espera que
-cuando esto pase compartan la misma biblioteca *runtime* permitiendo que
-bibliotecas y programas hechos para Tango_ y Phobos_ 2.0 puedan coexistir
-sin problemas.
+fragmentada entre las dos bibliotecas base. Si bien no parece que vaya a haber
+solución alguna a este problema para `D 1.0`_, `D 2.0`_ va en camino
+a solucionar este problema ya que utiliza DRuntime_, un nuevo intento de Sean
+Kelly por proveer una biblioteca *runtime* bien organizada y mantenida, que es
+una adaptación de la biblioteca *runtime* de Tango_ a `D 2.0`_. Sin embargo
+Tango_ no fue adaptada a `D 2.0`_ todavía, y no hay muchas perspectivas de que
+sea portada en algún momento, por un lado porque en general la comunidad sigue
+fragmentada entre muchos usuarios de `D 1.0`_ que no están contentos con los
+cambios introducidos en `D 2.0`_, en su mayoría usuarios de Tango_, y que no
+planean migrar a esa versión; y por otro porque el desarrollo de Phobos_ 2.0
+se ha abierto mucho y tiene muchos colaboradores, por lo tanto la mayor parte
+de la gente que utiliza `D 2.0`_ está contenta con el estado de Phobos_ 2.0.
 
 
 Descripción general
@@ -125,29 +123,29 @@ Descripción general
 
 D_ es un lenguaje de programación con sintaxis tipo C, multi-paradigma,
 compilado, con *tipado* fuerte y estático, buenas capacidades tanto de
-programación de bajo nivel (*system programming*) como de alto nivel.   Es
-compatible de forma binaria con C (se puede enlazar código objeto C con
+programación de bajo nivel (*system programming*) como de alto nivel; además
+es compatible de forma binaria con C (se puede enlazar código objeto C con
 código objeto D). Con estas características, D_ logra llenar un vacío
-importante que hay entre lo lenguajes de alto bajo nivel y los de alto
-nivel [BKIP08]_. Si bien tiene herramientas de muy bajo nivel, que por lo
-tanto son muy propensas a errores, da una infinidad de mecanismos para
-evitar el uso de estas herramientas a menos que sea realmente necesario.
-Además pone mucho énfasis en la programación confiable, para lo cual provee
-muchos mecanismos para detectar errores en los programas de forma temprana.
-
-Si puede pensarse en C++ como un "mejor C", podría decirse que D_ es
-un "mejor C++", ya que el objetivo del lenguaje es muy similar a C++,
-pero implementa muchas características que jamás pudieron entrar en
-el estándar de C++ y lo hace de una forma mucho más limpia, ya que
-no debe lidiar con problemas de compatibilidad hacia atrás, y cuenta
-con la experiencia del camino recorrido por C++, pudiendo extraer de
-él los mejores conceptos pero evitando sus mayores problemas también.
+importante que hay entre lo lenguajes de alto bajo nivel y los de alto nivel
+[BKIP08]_. Si bien tiene herramientas de muy bajo nivel, que por lo tanto son
+muy propensas a errores, da una infinidad de mecanismos para evitar el uso de
+estas herramientas a menos que sea realmente necesario.  Además pone mucho
+énfasis en la programación confiable, para lo cual provee muchos mecanismos
+para detectar errores en los programas de forma temprana.
+
+Si puede pensarse en C++ como un "mejor C", podría decirse que D_ es un "mejor
+C++", ya que el objetivo del lenguaje es muy similar a C++, pero implementa
+muchas características que jamás pudieron entrar en el estándar de C++ y lo
+hace de una forma mucho más limpia, ya que no debe lidiar con problemas de
+compatibilidad hacia atrás, y cuenta con la experiencia del camino recorrido
+por C++, pudiendo extraer de él los mejores conceptos pero evitando sus
+mayores problemas.
 
 Otra gran diferencia con C++ es la facilidad para ser analizado
-gramaticalmente (*parsing*), ya fue especialmente diseñado para ser
-sencillo y a diferencia de C y C++ su gramática es independiente del
-contexto (*context-free grammar*). Esto permite que D pueda ser compilado
-en pequeños pasos bien separados:
+sintácticamente (*parsing*), ya que fue especialmente diseñado para ser
+sencillo y a diferencia de C y C++ su gramática es independiente del contexto
+(*context-free grammar*). Esto permite que D pueda ser compilado en pequeños
+pasos bien separados:
 
 1. Análisis léxico.
 2. Análisis sintáctico.
@@ -155,22 +153,21 @@ en pequeños pasos bien separados:
 4. Optimizaciones.
 5. Generación de código.
 
-Esto favorece la creación de herramientas dada la facilidad de usar
-solamente la cantidad de análisis necesario para cada herramienta (por
-ejemplo un editor de textos puede tener hasta análisis sintáctico para
-proveer resaltado o un entorno de desarrollo puede proveer herramientas de
-re-factorización de código haciendo uso del análisis semántico).
+Esto favorece la creación de herramientas dada la facilidad de usar solamente
+la cantidad de análisis necesario para cada una (por ejemplo un editor de
+textos puede tener hasta análisis sintáctico para proveer resaltado o un
+entorno de desarrollo puede proveer herramientas para re-factorizar el código
+haciendo uso del análisis semántico).
 
-
-Una de las características que nunca pudo entrar en el estándar de C++
-es la recolección de basura. D_ no comete el mismo error.
+Una de las características que nunca pudo entrar en el estándar de C++ es la
+recolección de basura. D_ no comete el mismo error.
 
 
 Características del lenguaje
 ----------------------------------------------------------------------------
 
-A continuación se enumeran las principales características de D_,
-agrupadas por unidades funcional o paradigmas que soporta:
+A continuación se enumeran las principales características de D_, agrupadas
+por unidades funcionales o paradigmas que soporta:
 
 
 
@@ -182,25 +179,25 @@ Programación genérica y meta-programación
 La programación genérica se trata de la capacidad de poder desarrollar
 algoritmos y estructuras independientes de los tipos que manipulan (pero de
 forma segura o *type-safe*). Esto fue muy popularizado por C++ gracias a su
-soporte de plantillas (*templates*) y luego otros lenguajes como Java_
-y `C#`_ lo siguieron. Sin embargo otros lenguajes proveen formas más
-avanzadas de programación genérica, gracias a sistemas de tipos más
-complejos (como Haskell_).
-
-La meta-programación se refiere en general a la capacidad de un lenguaje
-para permitir generar código dentro del mismo programa de forma automática.
-Esto permite evitar duplicación de código y fue también muy popularizado
-por el soporte de *templates* de C++, aunque muchos otros lenguajes tienen
-mejor soporte de meta-programación, en especial los lenguajes dinámicos
-(como Python_).
+soporte de plantillas (*templates*) y luego otros lenguajes como Java_ y `C#`_
+lo siguieron. Sin embargo otros lenguajes proveen formas más avanzadas de
+programación genérica, gracias a sistemas de tipos más complejos (como
+Haskell_).
+
+La meta-programación se refiere en general a la capacidad de un lenguaje para
+permitir generar código dentro del mismo programa de forma automática.  Esto
+permite evitar duplicación de código y fue también muy popularizado por el
+soporte de *templates* de C++, aunque muchos otros lenguajes tienen mejor
+soporte de meta-programación, en especial los lenguajes dinámicos (como
+Python_).
 
 D_ provee las siguientes herramientas para realizar programación genérica
 y meta-programación:
 
-``if`` estático (``static if``):
-   puede verse como similar a la directiva del preprocesador de C/C++
-   ``#if``, pero a diferencia de esto, en D_ el ``static if`` tiene acceso
-   a todos los símbolos del compilador (constantes, tipos, variables, etc).
+``if`` estático (``static if``)
+   puede verse como similar a la directiva del preprocesador de C/C++ ``#if``,
+   pero a diferencia de esto, en D_ el ``static if`` tiene acceso a todos los
+   símbolos del compilador (constantes, tipos, variables, etc).
 
    Ejemplo::
 
@@ -209,9 +206,9 @@ y meta-programación:
 
    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 del
-   tipo de su inicializador.
+Inferencia de tipos básica implícita y explícita (mediante ``typeof``)
+   si no se especifica un tipo al declarar una variable, se infiere del tipo
+   de su valor de inicialización.
 
    Ejemplo::
 
@@ -222,8 +219,8 @@ Inferencia de tipos básica implícita y explícita (mediante ``typeof``):
    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.
+   Mediante el uso de ``typeof`` se puede solicitar el tipo de una expresión
+   arbitraria.
 
    Ejemplo::
 
@@ -231,10 +228,10 @@ Inferencia de tipos básica implícita y explícita (mediante ``typeof``):
 
    Más información en http://www.digitalmars.com/d/1.0/declaration.html#typeof
 
-Iteración sobre colecciones (``foreach``):
+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``.
+   asociativos, clases, estructuras o delegados) puede ser iterada mediante la
+   sentencia ``foreach``.
 
    Ejemplo::
 
@@ -243,12 +240,12 @@ Iteración sobre colecciones (``foreach``):
       foreach (i; a)
          total += i;
 
-*Templates*:
-   clases y funciones pueden ser parametrizadas. Esto permite desarrollar
-   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.
+*Templates*
+   clases y funciones pueden ser generalizadas. Esto permite desarrollar
+   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.
 
    Ejemplo::
 
@@ -256,12 +253,11 @@ Iteración sobre colecciones (``foreach``):
       auto i = sumar!(int)(5, 6);    // i == 11
       auto f = sumar!(float)(5, 6); // j == 11.0f
 
-   Además se pueden definir bloques de declaraciones parametrizados (esto
-   no es posible en C++), permitiendo instanciar dicho bloque con
-   parámetros particulares. Esto sirve como un mecanismo para la
-   reutilización de código, ya que puede incluirse un mismo bloque en
-   distintos lugares (por ejemplo clases). Un bloque parametrizado puede
-   verse como una especie de módulo.
+   Además se pueden definir bloques de declaraciones generalizadas (esto no
+   es posible en C++), permitiendo instanciar dicho bloque con parámetros
+   particulares. Esto sirve como un mecanismo para la reutilización de código,
+   ya que puede incluirse un mismo bloque en distintos lugares (por ejemplo
+   clases). Un bloque generalizado puede verse como una especie de módulo.
 
    Ejemplo::
 
@@ -273,26 +269,26 @@ Iteración sobre colecciones (``foreach``):
       bloque!(int, float).x = 5;
       float f = bloque!(int, float).foo(7);
 
-   La utilidad más prominente de los bloques parametrizados se da al
+   La utilidad más prominente de los bloques generalizados se da al
    acompañarse de *mixins*.
 
-Instanciación implícita de funciones parametrizadas:
+Instanciación implícita de funciones generalizadas
    el lenguaje es capaz de deducir los parámetros siempre que no hayan
-   ambigüedades
+   ambigüedades.
 
    Ejemplo::
 
       auto i = sumar(5, 6);          // i == 11
       auto f = sumar(5.0f, 6.0f); // f == 11.0f
 
-Especialización explícita y parcial de *templates*:
-   la especialización de *templates* consiste, al igual que en C++, en
-   proveer una implementación especializada para un tipo de dato (o valor)
-   de los parámetros.   Especialización parcial se refiere a la capacidad
-   de especializar un parámetro a través de un subtipo. Por ejemplo, se
-   puede especializar un *template* para cualquier tipo de puntero, o para
-   cualquier tipo de arreglo dinámico, sin necesidad de especificar el tipo
-   al que apunta dicho puntero o el tipo almacenado por el arreglo.
+Especialización explícita y parcial de *templates*
+   la especialización de *templates* consiste, al igual que en C++, en proveer
+   una implementación especializada para un tipo de dato (o valor) de los
+   parámetros.   Especialización parcial se refiere a la capacidad de
+   especializar un parámetro a través de un subtipo. Por ejemplo, se puede
+   especializar un *template* para cualquier tipo de puntero, o para cualquier
+   tipo de arreglo dinámico, sin necesidad de especificar el tipo al que
+   apunta dicho puntero o el tipo almacenado por el arreglo.
 
    Ejemplo de especialización::
 
@@ -308,25 +304,25 @@ Especialización explícita y parcial de *templates*:
       float v = 5.0f, w = 6.0f;
       auto f = sumar(&v, &w); // f == 11.0f
 
-Tipos, valores (incluyendo *strings*) y *templates* como parámetros:
+Tipos, valores (incluyendo *strings*) y *templates* como parámetros
    esto es otro bloque de construcción importantísimo para la programación
    genérica en D, ya que combinando *templates* que toman *strings* como
-   parámetro en combinación con *string mixins* pueden hacerse toda clase
-   de meta-programas.
+   parámetro en combinación con *string mixins* pueden hacerse toda clase de
+   meta-programas.
 
    Ejemplo::
 
       template hash(string s, uint so_far=0) {
          static if (s.length == 0)
-            const hash = sofar;
+            const hash = so_far;
          else
-            const hash = hash!(s[1 .. length], sofar * 11 + s[0]);
+            const hash = hash!(s[1 .. length], so_far * 11 + s[0]);
       }
       string s = hash!("hola"); // calculado en tiempo de compilación
 
-Cantidad de parámetros variables para *templates*:
-   Esto permite implementar tuplas u otros algoritmos que inherentemente
-   deben tomar parámetros variables en tiempo de compilación.
+Cantidad de parámetros variables para *templates*
+   Esto permite implementar tuplas u otros algoritmos que inherentemente deben
+   tomar una cantidad variable de parámetros en tiempo de compilación.
 
    Ejemplo::
 
@@ -338,14 +334,13 @@ Cantidad de parámetros variables para *templates*:
       }
       double d = sumar(1, 2.0, 3.0f, 4l); // d == 10.0
 
-*CTFE* (*compile-time function execution*):
+*CTFE* (*compile-time function execution*)
    si una función cumple ciertas reglas básicas (como por ejemplo no tener
-   efectos colaterales) puede ser ejecutada en tiempo de compilación en vez
-   de tiempo de ejecución. Esto permite hacer algunos cálculos que no
-   cambian de ejecución en ejecución al momento de compilar, mejorando la
-   performance o permitiendo formas avanzadas de metaprogramación. Esta
-   característica se vuelve particularmente útil al combinarse con *string
-   mixins*.
+   efectos colaterales) puede ser ejecutada en tiempo de compilación en vez de
+   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*.
 
    Ejemplo::
 
@@ -360,12 +355,12 @@ Cantidad de parámetros variables para *templates*:
 
    Esta característica es vital para evitar la duplicación de código.
 
-*Mixins*, incluyendo *string mixins*:
+*Mixins*, incluyendo *string mixins*
    la palabra *mixin* tiene significados distintos en varios lenguajes de
    programación. En D_ *mixin* significa tomar una secuencia arbitraria de
    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
+   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.
 
    Ejemplo::
@@ -386,10 +381,9 @@ Cantidad de parámetros variables para *templates*:
 
    *String mixin* se refiere a la capacidad de *incrustar* un *string* que
    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.
+   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.
 
    Ejemplo::
 
@@ -403,11 +397,9 @@ Cantidad de parámetros variables para *templates*:
 
    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. Esto se realiza en favor a una técnica
-   utilizada en C++ de realizar *pattern matching* sobre los parámetros de
-   las plantillas.
+Expresiones ``is``
+   las *expresiones ``is``* permiten la compilación condicional basada en las
+   características de un tipo.
 
    Ejemplo::
 
@@ -418,8 +410,7 @@ Expresiones ``is``:
             return T.init;
       }
 
-   Esto provee además una forma simple de reflexión en tiempo de
-   compilación.
+   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
@@ -431,29 +422,29 @@ Expresiones ``is``:
 Programación de bajo nivel (*system programming*)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Por programación de bajo nivel nos referimos a la capacidad de un lenguaje
-de manipular el hardware directamente, o al menos la memoria. C es
-probablemente el lenguaje de bajo nivel más popular, seguido por C++.
+Por programación de bajo nivel nos referimos a la capacidad de un lenguaje de
+manipular el hardware directamente, o al menos la memoria. C es probablemente
+el lenguaje de bajo nivel más popular, seguido por C++.
 
 D_ presenta muchas características de bajo nivel:
 
-Compila a código de máquina nativo:
-   no es interpretado ni necesita una máquina virtual como otros lenguajes
-   de más alto nivel como Java_, `C#`_, Python_, etc.
+Compila a código de máquina nativo
+   no es interpretado ni necesita una máquina virtual como otros lenguajes de
+   más alto nivel como Java_, `C#`_, Python_, etc.
 
-Provee acceso a *assembly*:
+Provee acceso a *assembly*
    por lo tanto, acceso directo al *hardware* y la posibilidad de utilizar
    cualquier característica de éste que no esté disponible en el lenguaje.
 
-   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).
+   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).
 
-``goto``:
+``goto``
    al igual que C y C++, D_ provee la flexibilidad del uso de ``goto``.
 
-Compatibilidad con C:
+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)``.
@@ -466,21 +457,20 @@ Compatibilidad con C:
       extern (C) printf(const char* format, ...);
       printf("3 + 5 == %d\n", 3 + 5); // llama al printf de C
 
-Manejo de memoria explícito:
-   permite alocar estructuras en el *stack* o en el *heap*, haciendo uso de
+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.
 
-Objetos y arreglos *livianos*:
+Objetos y arreglos *livianos*
    por objetos *livianos* se entiende no-polimórficos. Es decir, un
-   agrupamiento de variables análogo al ``struct`` de C, sin tabla virtual
-   ni 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 alocarse un arreglo dinámicamente usando
-   ``malloc()`` y utilizar el operador ``[]`` para accederlo.
+   agrupamiento de variables análogo al ``struct`` de C, sin tabla virtual ni
+   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.
 
-   Esto también permite interoperar con C, ya que pueden definirse
-   ``structs`` y arreglos que pueden ser intercambiados con dicho lenguaje
-   sin problemas.
+   Esto también permite interoperar con C, ya que pueden definirse ``structs``
+   y arreglos que pueden ser intercambiados con dicho lenguaje sin problemas.
 
    Ejemplo::
 
@@ -500,16 +490,16 @@ Objetos y arreglos *livianos*:
       timeval tv;
       gettimeofday(&tv, null);
 
-Rendimiento:
+Rendimiento
    la :ref:`d_generic` permite realizar muchas optimizaciones ya que se
-   resuelve en tiempo de compilación y por lo tanto aumentando la
-   *performance* en la ejecución.
+   resuelve en tiempo de compilación y por lo tanto aumenta el rendimiento en
+   la ejecución.
 
-Número de punto flotante de 80 bits:
+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).
 
-Control de alineación de miembros de una estructura:
+Control de alineación de miembros de una estructura
    Mediante ``align`` se puede especificar la alineación a tener en una
    estructura.
 
@@ -529,30 +519,29 @@ Control de alineación de miembros de una estructura:
 Programación de alto nivel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Programa de alto nivel se refiere a construcciones más avanzadas que un
-loop. Expresiones semánticamente más ricas que permiten mayor expresividad
-al programador o le permiten focalizarse de mejora manera en los algoritmos
-independizándose del *hardware* o de como funciona una computadora. Es
-exactamente el opuesto a :ref:`d_low_level`.
+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
+en los algoritmos independizándose del *hardware* o de como funciona una
+computadora. Es exactamente el opuesto a :ref:`d_low_level`.
 
-En general estas características tiene como efecto secundario una mejora de
-la productividad de los programadores. D_ adopta herramientas de muchos
-lenguajes de alto nivel, como Java_ y Python_, por ejemplo:
+En general estas características tienen como efecto secundario una mejora de la
+productividad de los programadores. D_ adopta herramientas de muchos lenguajes
+de alto nivel, como Java_ y Python_, por ejemplo:
 
-Manejo automático de memoria:
+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 *recolección de basura*.
+   lenguajes de bajo nivel, D_ permite manejar el *heap* de manera automática
+   también a través de un *recolector de basura*.
 
-Sistema de paquetes y módulos (similar a Java_ o Python_):
+Sistema de paquetes y módulos (similar a Java_ o Python_)
    un módulo es una unidad que agrupa clases, funciones y cualquier otra
    construcción de lenguaje. Un paquete es una agrupación de módulos. D_
    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).
+   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).
 
    Ejemplo:
 
@@ -575,23 +564,23 @@ Sistema de paquetes y módulos (similar a Java_ o Python_):
          b.f();
          f(); // ejecuta b.f()
 
-Funciones y delegados:
-   las funciones pueden ser sobrecargadas (funciones con el mismo nombre
-   pero distinta cantidad o tipo de parámetros), pueden especificarse
-   argumentos de 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++).
+Funciones y delegados
+   las funciones pueden ser sobrecargadas (funciones con el mismo nombre pero
+   distinta cantidad o tipo de parámetros), pueden especificarse argumentos de
+   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++).
 
    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
    *stack frame* (en cuyo caso la función es una función anidada).
 
    Además de esto los delegados son ciudadanos de primera clase
-   [#1stclasscity]_, disponiendo de forma literal (delegado anónimo), lo
-   que permite construcciones de alto nivel muy conveniente. Los argumentos
-   evaluados de forma perezosa no son más que un delegado que se ejecuta
-   solo cuando es necesario.
+   [#1stclasscity]_, disponiendo de forma literal (delegado anónimo), lo que
+   permite construcciones de alto nivel muy conveniente. Los argumentos
+   evaluados de forma perezosa no son más que un delegado que se ejecuta solo
+   cuando es necesario.
 
    .. [#1stclasscity] Por ciudadano de primera clase se entiende que se trata
       de un tipo soportado por completo por el lenguaje, disponiendo de
@@ -605,7 +594,7 @@ Funciones y delegados:
 
       bool buscar(T[] arreglo, T item, bool delegate(T x, T y) igual) {
          foreach (t, arreglo)
-            if (igual(t, elemento))
+            if (igual(t, item))
                return true;
          return false;
       }
@@ -622,15 +611,14 @@ Funciones y delegados:
                                        }
                                  );
 
-Arreglos *dinámicos* y arreglos asociativos:
+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*).
+   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*).
 
-   Los arreglos asociativos (también conocidos como *hashes*
-   o diccionarios) también son provistos por el lenguaje.
+   Los arreglos asociativos (también conocidos como *hashes* o diccionarios)
+   también son provistos por el lenguaje.
 
    Ambos son ciudadanos de primera clase, disponiendo de forma literal.
 
@@ -642,11 +630,11 @@ Arreglos *dinámicos* y arreglos asociativos:
       int[string] agenda;
       agenda["Pepe"] = 5555_1234;
 
-*Strings*:
+*Strings*
    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``.
+   *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``.
 
    Ejemplo::
 
@@ -659,13 +647,13 @@ Arreglos *dinámicos* y arreglos asociativos:
             s = "";
       }
 
-``typedef`` y ``alias``:
+``typedef`` y ``alias``
    el primero define un nuevo tipo basado en otro. A diferencia de C/C++ el
-   tipo original no puede ser implícitamente convertido al tipo nuevo
-   (excepto 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.
+   tipo original no puede ser implícitamente convertido al tipo nuevo (excepto
+   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.
 
    Ejemplo::
 
@@ -679,15 +667,15 @@ Arreglos *dinámicos* y arreglos asociativos:
       un_alias a = t;
       foo(a);
 
-Documentación embebida:
-   D_ provee un sistema de documentación embebida, análogo a lo que provee
-   Java_ o Python_ en menor medida. Hay comentarios especiales del código
-   que pueden ser utilizados para documentarlo de forma tal que luego el
+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
 
-Números complejos:
+Números complejos
    D_ soporta números complejos como ciudadanos de primera clase. Soporta
    forma literal de números imaginarios y complejos.
 
@@ -707,26 +695,24 @@ actualidad a la hora de diseñar e implementar un programa. D_ provee muchas
 herramientas para soportar este paradigma de forma confiable. Entre las
 características más salientes se encuentran:
 
-Objetos *pesados*:
+Objetos *pesados*
    objetos polimórficos como los de cualquier lenguaje con orientación real
-   a objetos. Estos objetos poseen una tabla virtual para *dispatch*
-   dinámico, todos los métodos son virtuales a menos que se indique lo
-   contrario y tienen semántica de referencia [#drefsem]_. Estos objetos
-   tienen un *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]_.
+   a objetos. Estos objetos poseen una tabla virtual para despacho dinámico,
+   todos los métodos son virtuales a menos que se indique lo contrario
+   y tienen semántica de referencia [#drefsem]_. Estos objetos tienen un
+   *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]_.
 
    .. [#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
       por referencia.
-
    .. [#dslicing] Este problema se da en C++ cuando se pasa una clase derivada
       a una función que acepta una clase base por valor como parámetro. Al
       realizarse una copia de la clase con el constructor de copia de la clase
       base, se pierden (o *rebanan*) los atributos de la clase derivada, y la
       información de tipos en tiempo de ejecución (*RTTI*).
-
    .. [#dvalsem] Semántica de valor significa que el tipo es tratado como si
       fuera un valor concreto. En general se pasa por valor y se hacen copias
       a menos que se utilice explícitamente un puntero.
@@ -751,22 +737,22 @@ Objetos *pesados*:
 
    Más información en http://www.digitalmars.com/d/1.0/function.html
 
-Interfaces:
+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 proveer una clase. Las interfaces no proveen una implementación de
-   dichos métodos, ni pueden tener atributos. Esto simplifica mucho el
-   lenguaje y no 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.
-
-Sobrecarga de operadores:
+   básicamente una tabla virtual, una definición de métodos virtuales que debe
+   proveer una clase. Las interfaces no proveen una implementación de dichos
+   métodos, ni pueden tener atributos. Esto simplifica mucho el lenguaje y no
+   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.
+
+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.
 
-Clases anidadas:
+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.
@@ -782,11 +768,10 @@ Clases anidadas:
          }
       }
 
-   Esto tiene un pequeño *overhead* ya que la clase ``Anidada`` debe
-   guardar un puntero a la clase ``Exterior``. Si no se necesita este
-   comportamiento es posible evitar este *overhead* utilizando ``static``,
-   en cuyo caso solo puede acceder a atributos estáticos de la clase
-   ``Exterior``.
+   Esto tiene un pequeño *overhead* ya que la clase ``Anidada`` debe guardar
+   un puntero a la clase ``Exterior``. Si no se necesita este comportamiento
+   es posible evitar este *overhead* utilizando ``static``, en cuyo caso solo
+   puede acceder a atributos estáticos de la clase ``Exterior``.
 
    Ejemplo::
 
@@ -802,7 +787,7 @@ Clases anidadas:
       }
 
 
-Propiedades (*properties*):
+Propiedades (*properties*)
    en D_ se refiere a funciones miembro que pueden ser tratadas
    sintácticamente como campos de esa clase/estructura.
 
@@ -820,21 +805,21 @@ Propiedades (*properties*):
    Además tipos nativos, clases, estructuras y expresiones tienen
    *properties* predefinidos, por ejemplo:
 
-   ``sizeof``:
+   ``sizeof``
       tamaño ocupado en memoria (ejemplo: ``int.sizeof`` -> 4).
 
-   ``init``:
+   ``init``
       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.
 
-   ``stringof``:
-      representación textual del tipo (ejemplo: ``(1+2).stringof`` -> ``"1
-      + 2"``).
+   ``stringof``
+      representación textual del símbolo o expresión (ejemplo:
+      ``(1+2).stringof`` -> ``"1 + 2"``).
 
-   ``mangleof``:
+   ``mangleof``
       representación textual del tipo *mutilado* [#dmangle]_.
 
    .. [#dmangle] *Name mangling* es el nombre dado comunmente a una técnica
@@ -847,8 +832,8 @@ Propiedades (*properties*):
    ``alignof``
       alineación de una estructura o tipo.
 
-   Estos son solo los *properties* predefinidos para todos los tipos, pero
-   hay una cantidad considerable de *properties* extra para cada tipo.
+   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
@@ -857,47 +842,48 @@ Propiedades (*properties*):
 
 
 
+.. _d_dbc:
+
 Programación confiable
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Programación confiable se refiere a las capacidades o facilidades que
-provee el lenguaje para evitar fallas de manera temprano (o la capacidad de
-evitar que ciertas fallas puedan existir directamente). D_ presta
-particular atención a esto y provee las siguientes herramientas:
+Programación confiable se refiere a las capacidades o facilidades que provee
+el lenguaje para evitar fallas de manera temprana (o la capacidad de evitar
+que ciertas fallas puedan existir directamente). D_ presta particular atención
+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
+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.
 
-``assert``:
-   es una condición que debe cumplirse siempre en un programa, como un
-   chequeo de integridad. Esto es muy utilizado en C/C++, donde
-   ``assert()`` es una *macro* que solo se compila cuando la *macro*
-   ``NDEBUG`` no está definida. Esto permite eliminar los chequeos de
-   integridad del programa, que pueden ser costosos, para versiones que se
-   suponen estables.
+``assert``
+   es una condición que debe cumplirse siempre en un programa, como un chequeo
+   de integridad. Esto es muy utilizado en C/C++, donde ``assert()`` es una
+   *macro* que solo se compila cuando la *macro* ``NDEBUG`` no está definida.
+   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.
+   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::
 
       File f = open("archivo");
       assert (f.ok());
 
-Diseño por contrato:
-   el diseño por contrato es un concepto introducido por el lenguaje
-   Eiffel_ a mediados/finales de los '80. Se trata de incorporar en el
-   lenguaje las herramientas para poder aplicar verificaciones formales
-   a las interfaces de los programas.
+Diseño por contrato
+   el diseño por contrato es un concepto introducido por el lenguaje Eiffel_
+   a mediados/finales de los '80. Se trata de incorporar en el lenguaje las
+   herramientas para poder aplicar verificaciones formales a las interfaces de
+   los programas.
 
    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 *performance* cuando es necesario):
+   ejecutan siempre y cuando no se compile en modo *release*, de manera de no
+   sacrificar rendimiento cuando es necesario):
 
-   Pre y post condiciones:
+   Pre y post condiciones
       Ejemplo::
 
          double raiz_cuadrada(double x)
@@ -917,12 +903,12 @@ Diseño por contrato:
             // implementación
          }
 
-   Invariantes de representación:
-      La invariante de representación es un método de una clase
-      o estructura que es verificada cuando se completa su construcción,
-      antes de la destrucción, antes y después de ejecutar cualquier
-      función miembro pública y cuando se lo requiere de forma explícita
-      utilizando ``assert``.
+   Invariantes de representación
+      La invariante de representación es un método de una clase o estructura
+      que es verificada cuando se completa su construcción, antes de la
+      destrucción, antes y después de ejecutar cualquier función miembro
+      pública y cuando se lo requiere de forma explícita utilizando
+      ``assert``.
 
       Ejemplo::
 
@@ -937,7 +923,7 @@ Diseño por contrato:
 
    Más información en http://www.digitalmars.com/d/1.0/dbc.html
 
-Pruebas unitarias:
+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()``.
@@ -951,41 +937,41 @@ Pruebas unitarias:
          assert (fecha);
       }
 
-Orden de construcción estática:
+Orden de construcción estática
    a diferencia de C++, D_ garantiza el orden de inicialización de los
    módulos. Si bien en C++ no hay módulos si no unidades de compilación, es
    posible que se ejecute código antes del ``main()`` en C++, si hay, por
-   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.
+   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.
 
-Inicialización garantizada:
+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.
+   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::
 
-      double d;         // inicializado a NaN
-      int x;             // inicializado a 0
-      Fecha f;          // inicializado a null
-      byte[5] a;       // inicializados todos los valores a 0
+      double d;      // inicializado a NaN
+      int x;         // inicializado a 0
+      Fecha f;       // inicializado a null
+      byte[5] a;     // inicializados todos los valores a 0
       long l = void; // NO inicializado (explícitamente)
 
-*RAII* (*Resource Adquisition Is Initialization*):
-   es una técnica muy utilizada en C++ que consiste en reservar recursos
-   por medio de la construcción de un objeto y liberarlos cuando se libera
-   éste. Al llamarse al destructor de manera automática cuando se sale del
-   *scope*, se asegura que el recurso será liberado también.
+*RAII* (*Resource Adquisition Is Initialization*)
+   es una técnica muy utilizada en C++ que consiste en reservar recursos por
+   medio de la construcción de un objeto y liberarlos cuando se libera éste.
+   Al llamarse al destructor de manera automática cuando se sale del *scope*,
+   se asegura que el recurso será liberado también.
 
    Esta técnica es la base para desarrollar código seguro en cuanto
    a excepciones (*exception-safe*) [SUTT99]_.
 
-   En D_ no es tan común utilizar *RAII* dada la existencia del recolector
-   de basura (en la mayoría de los casos el recurso a administrar es
+   En D_ no es tan común utilizar *RAII* dada la existencia del recolector de
+   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.
@@ -1001,42 +987,41 @@ Inicialización garantizada:
          // uso de archivo
       } // en este punto se llama al destructor de archivo
 
-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.
+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.
 
    Ejemplo::
 
       int f(Lock lock) {
          lock.lock();
          scope (exit)
-            lock.unlock();                  // ejecutado siempre que salga de f()
+            lock.unlock();              // ejecutado siempre que salga de f()
          auto trans = new Transaccion;
          scope (success)
-            trans.commit();                // ejecutado si sale con "return"
+            trans.commit();             // ejecutado si sale con "return"
          scope (failure)
-            trans.rollback();             // ejecutado si sale por una excepción
+            trans.rollback();           // ejecutado si sale por una excepción
          if (condicion)
-            throw Exception("error"); // ejecuta lock.unlock() y trans.rollback()
+            throw Exception("error");   // lock.unlock() y trans.rollback()
          else if (otra_condicion)
-            return 5;                         // ejecuta lock.unlock() y trans.commit()
-         return 0;                            // ejecuta lock.unlock() y trans.commit()
+            return 5;                   // lock.unlock() y trans.commit()
+         return 0;                      // lock.unlock() y trans.commit()
       }
 
-   Esta es una nueva forma de poder escribir código *exception-safe*,
-   aunque el programador debe tener un poco más de cuidado de especificar
-   las acciones a ejecutar al finalizar el *scope*.
+   Esta es una nueva forma de poder escribir código *exception-safe*, aunque
+   el programador debe tener un poco más de cuidado de especificar las
+   acciones a ejecutar al finalizar el *scope*.
 
-Primitivas de sincronización de hilos:
+Primitivas de sincronización de hilos
    la programación multi-hilo está directamente soportada por el lenguaje,
-   y se provee una primitiva de sincronización al igual que Java_. La
-   palabra reservada ``synchronized`` puede aparecer como modificador de
-   métodos (en 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::
+   y se provee una primitiva de sincronización al igual que Java_. La palabra
+   reservada ``synchronized`` puede aparecer como modificador de métodos (en
+   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::
 
       class Foo {
          synchronized void bar() { /* cuerpo */ }
@@ -1059,9 +1044,9 @@ y LDC_.
 
 DMD_ es el compilador de referencia, escrito por `Walter Bright`_. El
 *front-end* [#frontend]_ de este compilador ha sido liberado bajo licencia
-Artistic_/GPL_ y es utilizado por los otros dos compiladores, por lo
-tanto en realidad hay solo un compilador disponible con 3 *back-ends*
-[#backend]_ diferentes.
+Artistic_/GPL_ y es utilizado por los otros dos compiladores, por lo tanto en
+realidad hay solo un compilador disponible con 3 *back-ends* [#backend]_
+diferentes.
 
 .. [#frontend] *Front-end* es la parte del compilador encargada de hacer el
    análisis léxico, sintáctico y semántico del código fuente, generando una
@@ -1072,41 +1057,55 @@ tanto en realidad hay solo un compilador disponible con 3 *back-ends*
    la representación intermedia generada por el *front-end* a código de
    máquina.
 
-Con `DMD 1.041`__ se publicó el código fuente completo del compilador,
-pero con una licencia muy restrictiva para uso personal, por lo que el
-único efecto logrado por esto es que la gente pueda mandar parches
-o correcciones del compilador pero no lo convierte en `Software Libre`_,
-siendo el único de los 3 compiladores que no tiene esta característica.
+Con `DMD 1.041`__ se publicó el código fuente completo del compilador, pero
+con una licencia muy restrictiva para uso personal, por lo que el único efecto
+logrado por esto es que la gente pueda mandar parches o correcciones del
+compilador pero no lo convierte en `Software Libre`_, siendo el único de los
+3 compiladores que no tiene esta característica.
 
 __ http://www.digitalmars.com/d/1.0/changelog.html#new1_041
 
 El compilador GDC_ es el *front-end* de DMD_ utilizando al compilador GCC_
-como *back-end*. Fue un muy buen compilador pero en la actualidad está
-abandonado. No hay un *release* desde agosto de 2007 y no hay
-actualizaciones serias del código desde mediados de 2008, por lo que no
-parece haber muchas probabilidades de que se siga manteniendo.
-
-LDC_ es lo opuesto; un compilador joven, nacido a mediados de 2007 (aunque
-vio la luz un año después aproximadamente), su primer *release* fue
-a principios de 2009 y tuvo un crecimiento excepcional. En la actualidad
-inclusive pasa más pruebas de estrés que el compilador de referencia DMD_.
-Como *back-end* utiliza LLVM_, otro proyecto joven y con una tasa de
-crecimiento muy alta.
-
-Además de estos compiladores hay varios otros experimentales, pero ninguno
-de ellos de calidad suficiente todavía. Por ejemplo hay un compilador
-experimental que emite *CIL* (*Common Intermediate Language*), el
-*bytecode* de `.NET`_, llamado DNet_. También hay un *fron-end* escrito en
-D_, llamado Dil_
+como *back-end*. Fue un muy buen compilador pero estuvo abandonado por casi
+tres años. A mediados de este año recibió un nuevo impulso y de a poco se está
+poniendo al día con los *front-ends* actuales de DMD_ 1.0 y 2.0, aunque la
+versión 2.0 viene bastante más rezagada y todavía no es una alternativa viable
+a DMD_.
+
+LDC_ sufrió una suerte similar, es un compilador joven que utiliza como
+*back-end* a LLVM_ (una infraestructura modera para construir compiladores),
+nacido a mediados de 2007 como un proyecto personal y privado de Tomas
+Lindquist Olsen, que estuvo trabajando de forma privada en el proyecto hasta
+mediados de 2008, momento en que decide publicar el código mediante una
+licencia libre.  Para ese entonces el compilador era todavía inestable
+y faltaban implementar varias cosas, pero el estado era lo suficientemente
+bueno como para captar varios colaboradores muy capaces, como `Christian
+Kamm`_ y Frits Van Bommel que rápidamente se convirtieron en parte fundamental
+del proyecto. El primer *release* (0.9) de una versión relativamente completa
+y estable fue a principios de 2009 que fue seguido por la versión 0.9.1 que
+como puntos más salientes agregó soporte para x86-64 y assembly embebido. El
+compilador tuvo un crecimiento excepcional pero estuvo muy inactivo por algún
+tiempo y, si bien sigue siendo mantenido, en general los nuevos *front-end* de
+DMD_ llevan tiempo de integrar y no está al día con el *back-end* de LLVM_
+(por ejemplo desde que se actualizó para utilizar LLVM_ 2.7 que perdió la
+capacidad de generar símbolos de depuración).
+
+Además de estos compiladores hay varios otros experimentales, pero ninguno de
+ellos de calidad suficiente todavía. Por ejemplo hay un compilador
+experimental que emite *CIL* (*Common Intermediate Language*), el *bytecode*
+de `.NET`_, llamado DNet_. También hay un *front-end* escrito en D_, llamado
+Dil_.
 
 Originalmente, dado que GDC_ estaba siendo mantenido y que LDC_ no existía,
-este trabajo iba a ser realizado utilizando GDC_ como compilador, dado que
-al ser `Software Libre`_ podía ser modificado de ser necesario. Finalmente,
-gracias a la excepcional tasa de crecimiento de LDC_ y al abandono de GDC_
-se terminó desarrollando el trabajo utilizando LDC_.
-
+este trabajo iba a ser realizado utilizando GDC_ como compilador, dado que al
+ser `Software Libre`_ podía ser modificado de ser necesario. Pero finalmente,
+dada la poca confiabilidad que presenta la continuidad del desarrollo de tanto
+GDC_ como LDC_, y que el código de DMD_ está disponible en su totalidad
+(aunque no sea `Software Libre`_ por completo), se optó por utilizar este
+último, dado que es la implementación de referencia que fue más constantemente
+mantenida y desarrollada.
 
 
 .. include:: links.rst
 
-.. vim: set ts=3 sts=3 sw=3 et tw=78 :
+.. vim: set ts=3 sts=3 sw=3 et tw=78 spelllang=es :