From 29bffac4720cd850418640db1963ec23690710c9 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Sat, 9 Oct 2010 21:35:17 -0300 Subject: [PATCH] Correcciones sugeridas mayormente por Alb --- source/d.rst | 83 +++++++++++++++++++++++++-------------------------- source/gc.rst | 40 ++++++++++++------------- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/source/d.rst b/source/d.rst index 0dc123d..ddf849d 100644 --- a/source/d.rst +++ b/source/d.rst @@ -23,10 +23,10 @@ __ `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: @@ -44,15 +44,15 @@ Esto podría traducirse como: 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). +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 + 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, @@ -63,8 +63,7 @@ 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. +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 @@ -88,30 +87,30 @@ 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 +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`_. +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 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 considerable en -asegurarse de que funcione con ambas). +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 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. Si bien todavía -Tango_ no fue adaptada a D 2.0, se espera que cuando esto pase compartan la +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. + y Phobos_ 2.0 puedan coexistir sin problemas. Descripción general @@ -119,15 +118,15 @@ 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 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. +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 @@ -135,11 +134,11 @@ 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. +mayores problemas. Otra gran diferencia con C++ es la facilidad para ser analizado -sintácticamente (*parsing*), ya fue especialmente diseñado para ser sencillo -y a diferencia de C y C++ su gramática es independiente del contexto +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: @@ -150,9 +149,9 @@ pasos bien separados: 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 +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 @@ -163,7 +162,7 @@ Características del lenguaje ---------------------------------------------------------------------------- A continuación se enumeran las principales características de D_, agrupadas -por unidades funcional o paradigmas que soporta: +por unidades funcionales o paradigmas que soporta: @@ -395,9 +394,7 @@ Cantidad de parámetros variables para *templates* 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. + características de un tipo. Ejemplo:: @@ -846,7 +843,7 @@ 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 +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: diff --git a/source/gc.rst b/source/gc.rst index 9788fd9..c08c979 100644 --- a/source/gc.rst +++ b/source/gc.rst @@ -183,10 +183,9 @@ lenguajes de programación que requieran un recolector de basura conservativo. Por último, siendo que el recolector de basura es parte del programa de forma indirecta, es común ver en la literatura que se diferencia entre dos partes -del programa, el recolector de basura y el programa en sí. Dado que para el -recolector de basura, lo único que interesa conocer del programa en sí son los -cambios al grafo de conectividad de las celdas, normalmente se lo llama -*mutator*. +del programa, el recolector de basura y el programa en sí. A la primera se la +suele denominar simplemente *recolector* y a la segunda *mutator*, dado que es +la única que modifica (o *muta*) el grafo de conectividad. @@ -318,7 +317,7 @@ Esto es, efectivamente, una partición del *heap* (ver figura Al proceso de visitar los vértices *conectados* desde el *root set* se lo denomina *marcado*, *fase de marcado* o *mark phase* en inglés, debido a que -es necesario marcar los vértices para evitar visitar 2 veces el mismo nodo en +es necesario marcar los vértices para evitar visitar dos veces el mismo nodo en casos de que el grafo contenga ciclos [#gccycle]_. De forma similar a la búsqueda, que puede realizarse *primero a lo ancho* (*breadth-first*) o *primero a lo alto* (*depth-first*) del grafo, el marcado de un grafo @@ -632,9 +631,9 @@ vacíos):: Si bien este algoritmo no es recursivo, tiene un requerimiento de espacio :math:`O(\lvert Live \thickspace set \rvert)`. Un ejemplo donde se aprecia -esto a simple vista es cuando el *live set* resulta una lista simplemente -enlazada, en cuyo caso el :math:`gray_set` deberá almacenar todos los nodos -del *live set*. +esto a simple vista es cuando el *Live set* resulta una lista simplemente +enlazada, en cuyo caso el *gray_set* deberá almacenar todos los nodos del +*Live set*. @@ -703,7 +702,8 @@ Y los servicios básicos proporcionados por el recolector son los siguientes: referencias `. Para otros recolectores puede significar que el usuario asegura que no hay más referencias a esta celda, es decir, análogo a eliminar el conjunto de aristas :math:`\big\lbrace (v, w) \in A , v \in - Live \thickspace set , w \in Live \thickspace set \big/ w = cell`. + Live \thickspace set , w \in Live \thickspace set \big/ w = cell + \big\rbrace`. :math:`collect()` indica al recolector que debe hacer un análisis del grafo de conectividad @@ -722,7 +722,7 @@ aunque en ciertas circunstancias pueden ser utilizados por el usuario también. Algoritmos clásicos ---------------------------------------------------------------------------- -En la literatura se encuentran normalmente referencias a 3 algoritmos +En la literatura se encuentran normalmente referencias a tres algoritmos clásicos, que son utilizados generalmente como bloques básicos para construir recolectores más complejos. Se presentan las versiones históricas más simples a fin de facilitar la comprensión conceptual. @@ -820,19 +820,19 @@ ciclo es un camino :math:`\underset{v \to v}{C}`, es decir, el *vértice inicial* es el mismo que el *vértice final*. Cuando esto sucede, las celdas que participan del ciclo tienen siempre su -contador mayor que 0, sin embargo puede no haber ningún elemento del *root -set* que apunte a una celda dentro del ciclo, por lo tanto el ciclo es -*basura* (al igual que cualquier otra celda para la cual hayan referencias -desde el ciclo pero que no tenga otras referencias externas) y sin embargo los +contador mayor que 0, sin embargo puede suceder que ningún elemento del *root +set* apunte a una celda dentro del ciclo, por lo tanto el ciclo es *basura* +(al igual que cualquier otra celda para la cual hayan referencias desde el +ciclo pero que no tenga otras referencias externas) y sin embargo los contadores no son 0. Los ciclos, por lo tanto, violan la invariante del conteo de referencia. Hay formas de solucionar esto, pero siempre recaen en un esquema que va por fuera del conteo de referencias puro. En general los métodos para solucionar esto son variados y van desde realizar un marcado del sub-grafo para detectar -nodos hasta tener otro recolector completo de *emergencia*, pasando por tratar -los ciclos como un todo contar las referencias al ciclo completo en vez de -a cada celda en particular. +ciclos y liberarlos hasta tener otro recolector completo de *emergencia*; +pasando por tratar los ciclos como un todo para contar las referencias al +ciclo completo en vez de a cada celda en particular. Incluso con este problema, el conteo de referencia sin ningún tipo de solución en cuanto a la detección y recolección de ciclos fue utilizado en muchos @@ -1141,7 +1141,7 @@ contador de ``h2`` que queda en 0, transformándose en *basura* (ver figura Ejemplo de conteo de referencias: actualización de una referencia (parte 1). - Cambio en la referencia ``h2.l`` :math:`\to` ``h2`` a ``h2.l`` :math:`\to` + Cambio en la referencia ``h3.l`` :math:`\to` ``h2`` a ``h3.l`` :math:`\to` ``h5`` (parte 1). .. subfig:: @@ -1199,7 +1199,7 @@ contador de ``h2`` que queda en 0, transformándose en *basura* (ver figura .. subfig:: - Luego se procede a visitar las hijas de ``h3``, comenzando por ``h2``. + Luego se procede a visitar la antigua referencia de ``h3.l`` (``h2``). .. digraph:: g4_2 @@ -1315,7 +1315,7 @@ de actualizar la referencia ``h3.l`` para que apunte a ``h5`` (ver figura Ejemplo de conteo de referencias: actualización de una referencia (parte 2). - Cambio en la referencia ``h2.l`` :math:`\to` ``h2`` a ``h2.l`` :math:`\to` + Cambio en la referencia ``h3.l`` :math:`\to` ``h2`` a ``h3.l`` :math:`\to` ``h5`` (parte 2). .. subfig:: -- 2.43.0