-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:`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:
-
-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*.
-
-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).
-
- Ejemplo:
-
- ``a.d``::
-
- module a;
- void f() {}
-
- ``b.d``::
-
- module b;
- void f() {}
-
- ``c.d``::
-
- module c;
- import a;
- import b: f;
- a.f();
- 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++).
-
- 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.
-
- Ejemplo::
-
- bool buscar(T[] arreglo, T item, bool delegate(T x, T y) igual) {
- foreach (t, arreglo)
- if (igual(t, elemento))
- return true;
- return false;
- }
- struct Persona {
- string nombre;
- }
- Persona[] personas;
- // llenas personas
- Persona p;
- p.nombre = "Carlos";
- bool encontrado = buscar(personas, p,
- (Persona x, Persona y) {
- return x.nombre == y.nombre;
- }
- );
-
-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*).
-
- 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.
-
- Ejemplo::
-
- int[] primos = [ 2, 3, 5, 7, 11, 13, 17, 19 ];
- primos ~= [ 23, 29 ];
- auto menores_que_10 = primos[0..4]; // [ 2, 3, 5, 7 ]
- int[string] agenda;
- agenda["Pepe"] = 5555_1234;
-
-*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``.
-
- Ejemplo::
-
- string s = "árbol";
-
- switch (s) {
- case "árbol":
- s = "tree";
- default:
- s = "";
- }
-
-``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.
-
- Ejemplo::
-
- typedef int tipo;
- int foo(tipo x) {}
- tipo t = 10;
- int i = 10;
- foo(t);
- foo(i); // error, no compila
- alias tipo un_alias;
- 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
- 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:
- D_ soporta números complejos como ciudadanos de primera clase. Soporta
- forma literal de números imaginarios y complejos.
-
- Ejemplo::
-
- ifloat im = 5.0i;
- float re = 1.0;
- cfloat c = re + im; // c == 1.0 + 5.0i
-
-.. [#1stclasscity] Por ciudadano de primera clase se entiende que se
- trata de un tipo soportado por completo por el lenguaje, disponiendo de
- expresiones literales anónimas, pudiendo ser almacenados en variables,
- estructuras de datos, teniendo una identidad intrínseca, más allá
- de un nombre dado, etc. En realidad los arreglos asociativos no pueden
- ser expresados como literales anónimos pero sí tienen una sintaxis
- especial soportada directamente por el lenguaje.
+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 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
+ 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* [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
+ 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) [DWMO]_.
+
+ Ejemplo:
+
+ ``a.d``::
+
+ module a;
+ void f() {}
+
+ ``b.d``::
+
+ module b;
+ void f() {}
+
+ ``c.d``::
+
+ module c;
+ import a;
+ import b: f;
+ a.f();
+ 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++) [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
+ *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] Por ciudadano de primera clase se entiende que se trata
+ de un tipo soportado por completo por el lenguaje, disponiendo de
+ expresiones literales anónimas, pudiendo ser almacenados en variables,
+ estructuras de datos, teniendo una identidad intrínseca, más allá de un
+ nombre dado, etc. En realidad los arreglos asociativos no pueden ser
+ expresados como literales anónimos pero sí tienen una sintaxis especial
+ soportada directamente por el lenguaje.
+
+ Ejemplo::
+
+ bool buscar(T[] arreglo, T item, bool delegate(T x, T y) igual) {
+ foreach (t, arreglo)
+ if (igual(t, item))
+ return true;
+ return false;
+ }
+ struct Persona {
+ string nombre;
+ }
+ Persona[] personas;
+ // llenas personas
+ Persona p;
+ p.nombre = "Carlos";
+ bool encontrado = buscar(personas, p,
+ (Persona x, Persona y) {
+ return x.nombre == y.nombre;
+ }
+ );
+
+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*)
+ [DWAR]_.
+
+ Los arreglos asociativos (también conocidos como *hashes* o diccionarios)
+ también son provistos por el lenguaje [DWAA]_.
+
+ Ambos son ciudadanos de primera clase, disponiendo de forma literal.
+
+ Ejemplo::
+
+ int[] primos = [ 2, 3, 5, 7, 11, 13, 17, 19 ];
+ primos ~= [ 23, 29 ];
+ auto menores_que_10 = primos[0..4]; // [ 2, 3, 5, 7 ]
+ int[string] agenda;
+ agenda["Pepe"] = 5555_1234;
+
+*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`` [DWSR]_.
+
+ Ejemplo::
+
+ string s = "árbol";
+
+ switch (s) {
+ case "árbol":
+ s = "tree";
+ default:
+ s = "";
+ }
+
+``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 [DWDC]_.
+
+ Ejemplo::
+
+ typedef int tipo;
+ int foo(tipo x) {}
+ tipo t = 10;
+ int i = 10;
+ foo(t);
+ foo(i); // error, no compila
+ alias tipo un_alias;
+ un_alias a = t;
+ foo(a);
+
+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 [DWDO]_.
+
+Números complejos
+ D_ soporta números complejos como ciudadanos de primera clase. Soporta
+ forma literal de números imaginarios y complejos [DWTY]_.
+
+ Ejemplo::
+
+ ifloat im = 5.0i;
+ float re = 1.0;
+ cfloat c = re + im; // c == 1.0 + 5.0i