Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros...

103

Transcript of Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros...

Page 1: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 2: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Historia del lenguaje. CaracterísticasProcedimientos, funciones y pasajes de parámetros  Sistema de tipos Estructuras de controlManejo de memoria y recolección de basura.Características destacables.Problemas y controversias.Back tracking .

Page 3: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 4: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Historia del Lenguaje

-Creado por Walter Brigth en 1999- Versiones 1.0 (2007) y 2.0 (2010).-Influencias C, C++ , Java, Perl, Phyton y Ruby_ Compiladores DMD, GDC y LDC.

“Parece que la mayoría de los lenguajes de programación “nuevos” caen en 2 categorías: aquellos académicos con nuevos paradigmas radicales y aquellos de grandes corporaciones con el foco en el desarrollo rápido y web. Tal vez es hora de que nazca un nuevo lenguaje de la experiencia práctica implementando compiladores.”

Origen

Page 5: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

CaracterísticasCaracterísticas

-Paradigmas Multiparadigma, Orientado a objetos, Imperativo

-Tipo de Dato Fuerte, Estático

-Sintaxis tipo C Ejemplo:En C char s[8];

strcpy(s, "algo"); printf("string = '%s'\n", s);

En D char[] s; s = "algo"; printf("string = '%.*s'\n", s);

-Compatibilidad binaria.

Page 6: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Características destacadas del lenguaje A continuación se enumeran las principales características de D, agrupadas por unidades funcionales o paradigmas que soporta:

Programación genérica y meta-programación Programación de bajo nivel (system programming) Programación de alto nivel Programación orientada a objetos Programación confiable

Page 7: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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). D provee las siguientes herramientas para realizar programación genérica y meta-programación:

Page 8: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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). Ejemplo:

Page 9: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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ónEjemplo:

Mediante el uso de typeof se puede solicitar el tipo de una expresión arbitrariaEjemplo:

Page 10: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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 foreachEjemplo:

Page 11: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Tanto clases como 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:

Page 12: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Además se pueden definir bloques redeclaraciones 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:

Page 13: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

La utilidad más prominente de los bloques generalizados se da al acompañarse de mixins.Además las templates de D tienen las siguientes características destacables:

Instanciación implícita de funciones generalizadasEl lenguaje es capaz rededucir los parámetros siempre que no hayan ambigüedades.Ejemplo:

Page 14: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Especialización explícita y parcial de templatesLa 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:

Page 15: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Ejemplo de especialización parcial:

Page 16: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Tipos, valores (incluyendo strings) y templates como parámetrosEste 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 metaprogramas.Ejemplo:

Page 17: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Templates

Cantidad de parámetros variables para templatesEsta característica permite implementar tuplas y otros algoritmos que inherentemente deben tomar una cantidad variable de parámetros en tiempo de compilación.Ejemplo:

Page 18: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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 el rendimiento o permitiendo formas avanzadas de meta-programación. Esta característica se vuelve particularmente útil al combinarse con string mixins.Ejemplo:

Esta característica es muy importante para evitar la duplicación de código.

Page 19: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Mixins, incluyendo string mixinsLa 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 introducida por la falta de herencia múltipleEjemplo:

Page 20: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Mixins, incluyendo string mixins

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 elcódigo fuente directamente por el programador. Esto permite hacer manipulaciones arbitrariamente complejas en combinación con funciones ejecutadas en tiempo de compilación.Ejemplo:

Page 21: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Expresiones is

Las expresiones ‘‘is‘‘ permiten la compilación condicional basada en las características de un tipoEjemplo:

Esto provee además una forma simple de reflexión en tiempo de compilación.

Page 22: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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++.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.

Page 23: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Assembly empotrado

Provee 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).gotoAl igual que C y C++, D provee la flexibilidad del uso de goto.

Page 24: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Compatibilidad con C

Soporta todos los tipos de C y es ABI (Interfaz de Aplicación Binaria) 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)Ejemplo:

Page 25: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Manejo de memoria explícitoPermite 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 livianosPor 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 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.

Page 26: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Objetos y arreglos livianos

Ejemplo:

Page 27: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Rendimiento

La Programación genérica y meta-programación permite realizar muchas optimizaciones ya que se resuelven en tiempo de compilación y por lo tanto aumenta el rendimiento en la ejecución.

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).

Page 28: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Control de alineación de miembros de una estructura

Mediante align se puede especificar la alineación a tener en una estructura.Ejemplo:

Page 29: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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 mejor manera en los algoritmos independizándose del hardware o de cómo funciona una computadora. Es exactamente el opuesto a Programación de bajo nivel (system programming).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:

Page 30: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo 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 recolector de basura.

Page 31: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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).

Page 32: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Sistema de paquetes y módulos

Ejemplo:a.d:

b.d:

c.d:

Page 33: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arreglos dinámicos y arreglos asociativosLos 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:

Page 34: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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:

Page 35: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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:

Page 36: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.

Page 37: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Números complejos

D soporta números complejos como ciudadanos de primera clase. Soporta forma literal de números imaginarios y complejos.Ejemplo:

Page 38: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Programación orientada a objetos La orientación a objetos es probablemente el paradigma más utilizado en la 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:

Page 39: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Objetos pesados

Objetos polimórficos como los de cualquier lenguaje con orientación real 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 (el tipo es tratado como si fuera un puntero. Nunca se hacen copias del objeto, siempre se pasa por referencia) .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. 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).

Page 40: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Objetos pesados

Esto sucede porque permite semántica por valor (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).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.Ejemplo:

Page 41: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

ClasesDeclaración de una clase:

class NombredelaClase { class NombredelaClase: Object { } }

class NombredelaClase { enum constante = 0.2; // Una constante static immutable nombreDefault = “Una Clase"; // Algunas variables asignadas a cada objeto NombredelaClasestring nombre = nombreDefault; uint width, height; static double metodo() { // Un método estático return constante; } void cambiarNombre(string otro) { // Un método nombre = otro; } final void tamañoCuadruple() { // Un método que no se delegawidth *= 2; height *= 2; } }

Page 42: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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

Page 43: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

InterfacesEjemplo de Herencia Múltipleinterface Observador { void notificar(Object dato); } interface ElementoVisual { void dibujar(); } interface Actor { void actuar(); } interface ObservadorActor : Observador, Actor { void setActivo(bool activo); } interface Visual : Actor, ElementoVisual { void animar(); } class Sprite : Visual, Observador, ObservadorActor { void dibujar() { ... } void animar() { ... } void actuar() { ... } void setActivo(bool activo); void notificar(Object dato) { ... } }

Page 44: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.

Page 45: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.Ejemplo:

Page 46: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Clases anidadas

Esto tiene un pequeño overhead ya que la clase Anidada debe guardar un puntero a la clase Exterior. Sino 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:

Page 47: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Programación confiable

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:

Page 48: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.Ejemplo:try { throw new Exception("mensaje de error"); } catch(Exception e) { printf("capturada la excepción, mensaje: %.*s\n", e.msg); } finally { printf("este mensaje se mostrará siempre"); }

Page 49: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.Ejemplo:

Page 50: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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 rendimiento o cuando es necesario):

Page 51: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Pre y postcondiciones

Ejemplo:

Page 52: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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:

Page 53: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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().Ejemplo:

Page 54: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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 sino 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 ordenen que el usuario importa los módulos.

Page 55: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.Ejemplo:

Page 56: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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).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 a un bloque de código.

Page 57: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

RAII (Resource Adquisition Is Initialization)

Ejemplo:

Page 58: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

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.

Page 59: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Guardias de bloque (scope guards)Ejemplo:

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.

Page 60: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Primitivas de sincronización de hilos

La programación multi-hilo está directamente soportada por el lenguaje, y se provee una primitiva desincronizació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:

Es equivalente a:

Page 61: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 62: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Punto de entrada de un programaPunto de entrada de un programa

Función main()

void main() { ... }

void main(char[][] args) { ... }

int main() { ... }

int main(char[][] args) { ... }

Page 63: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Declaración anticipada innecesariaDeclaración anticipada innecesaria

- Obligatorio en C y C++- Innecesario en D (al igual que Java)

Ejemplo de C:

void llamaotra(int prueba) { funcionprimera( prueba ); // error, funcionprimera no está definida}void funcionprimera(int param) { return param; }

Page 64: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Retorno de valores de una funcionRetorno de valores de una funcion

vRetorno funcion( … ) { … }

Tipos destacables: •auto Deteccion automatica de tipo•ref Retorno por referencia

Donde vRetorno puede ser cualquier tipo valido del lenguaje

Page 65: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Pasaje de parámetrosPasaje de parámetros

-Pasaje por valor (utilizado por defecto)-Punteros a variables (sintaxis de C)-Pasaje por referencia (utilizando modificador ref. ver ejemplo)

void main( char[][] args ) {int a = 0;test_param(a);writefln( a ); // Resultado: a = 1

}

// Modificador “ref” en parametro “a”void test_param ( ref int a ) {

a++;}

Page 66: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

PropiedadesPropiedades

• Indicada con el atributo @property • Reemplazo elegante a sets y gets• No violan encapsulamiento

struct S{ int m_x; @property { int x() { return m_x; } int x(int newx) { return m_x = newx; } }}

void foo(){ S s; s.x = 3; // Llama a s.x(int) bar(s.x); // Llama a bar(s.x())}

Page 67: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Sobrecarga de funcionesSobrecarga de funciones

-Niveles de comparacion de argumentos:

1.Sin compatibilidad2.Compatibilidad con conversiones implicitas3.Compatibilidad con conversiones explicitas4.Compatibilidad completa

-Eleccion de funcion sobrecargada basada en argumentos

-Preferencia de función mas especializada

Page 68: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Evaluación ‘perezosa’ de un argumento de funciónEvaluación ‘perezosa’ de un argumento de función

No evalúa la expresión hasta que el resultado de estasea requerido

void log(lazy char[] dg){ if (logging)

fwritefln(logfile, dg());}

void foo(int i){ log("Entering foo() with i set to " ~ toString(i));}

Page 69: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Funciones PurasFunciones Puras

-Devuelve siempre el mismo resultado para un mismo conjunto de argumentos

-No lee ni escribe valores mutables globales

-No puede llamar a funciones no puras

-Puede redefinir una función impura, pero una función impura no puede redefinir a una función pura

-No puede realizar operaciones I/O

Page 70: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

DelegadosDelegados

void foo( int a ){ void bar() { writefln( a ); } void delegate() dg; dg = &bar; call( dg );}void call( void delegate() dg ) { dg(); }void main( char[][] args ) { foo( 100 );}

-Similares a los punteros a métodos C++

-Compuesto por referencia a objeto (this) y puntero a función

-Scope en el nivel donde fue creado

Page 71: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

ClausuraClausura

- Implementada para ser utilizada con delegados

- Persistencia del entorno local donde fue creado el delegado

- Variables utilizadas en clausura son copiadas al heap de memoria (heap-based memory)

- El resto de las variables permanece en el stack de la aplicación

(Ver ejemplo clausura.d)

Page 72: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 73: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

void void no contiene ningún dato.

bit Un único bit que representa 0 o 1 (true o false).Se inicializa con un valor default false.

bool (bool es un alias de bit) El tipo bool tiene el tamaño de 1 byte que solo puede tener como valor true ó false. Los unicos operadores que puede aceptar de tipo bool son: & | ^ &= |= ^= ! && || ?:

character char ch; // unsigned 8 bit UTF-8 wchar wch; // unsigned 16 bit UTF-16 dchar dch; // unsigned 32 bit UTF-32

Page 74: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Integer

byte b; // signed 8 bits [-128 .. +127]short s; // signed 16 bits [-32768.. +32767]int i; // signed 32 [-4294967296 .. +4294967295] long l; // signed 64 [-1.8e19 .. +1.8e19] cent c; // signed 128 [-1,7e+38 .. +1,7e+38]ubyte b // unsigned 8 bits [0 .. +255]ushort; uint; ulong; // unsigned 64 [0 .. 18446744073709551616] ucent; // unsigned 128 [0 .. 3,4e+38]

Page 75: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Floatingpoint

float f; // 32 bit floating point double d; // 64 bit floating point real r; // punto flotante mas grande que el hardware implementa ifloat if; // float imaginarioidouble id; // double imaginarioireal ir; // real imaginariocfloat cf; // numero complejo con 2 variables flotantes cdouble cd; // double complejocreal cr; // real complejo

Page 76: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arrays

int[5] b; // B es un array de 5 ints (estático)

int[] a; // Se creó un array a que puede contener integers (no estático)

int* p; int[5] a; int[] b; p = a; // esto funciona como una referencia p = null; // esto ‘destruye' la referencia b = a; // posible. //b = p; //imposible! b[0..2] = 5; // esto también es válido

Page 77: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arrays mucho más manejables y foreach

En D, además de existir una biblioteca de plantillas de clase avanzadas (la DTL, actualmente en desarrollo) los arrays cuentan con una serie de características que los hacen mucho más prácticos y manejables que los de C/C++: Cuentan con comprobación de límites. Pueden redimensionarse dinámicamente cambiando su propiedad "length" o añadiendo al final con el operador "~=". Pueden concatenarse fácilmente dos o más arrays en uno sólo con el operador "~".

Page 78: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arrays mucho más manejables y foreachConcatenación con el operador ~ :

Ejemplo 1:

char[] a = "He"; char[] b = "o world!"; char[] d = "l"; char[] c = a ~ d ~ "l" ~ b; // c == "Hello world!“

Ejemplo 2:

static int[] a = [1,2,3]; static int[] b = [2,3]; int[] c = a ~ b; // c es un array [1,2,3,2,3]

Page 79: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arrays mucho más manejables y foreachPermiten la especificación de subrangos dentro de un array. Por ejemplo, si quisiéramos los elementos 3, 4 y 5 de un array en un subarray podríamos hacer: subarray = miarray[3..5]. Esto además permite copiar de forma sencilla los arrays por valor con la siguiente notación: int array2[] = array1[]; Los rangos también permiten asignaciones automáticas a varios elementos de un array simultaneamente: array[2..6] = 0; Cuentan con propiedades útiles (como size para el tamaño, dup para crear un duplicado, reverse para invertir el orden de los elementos y sort para ordenarlos.)

Page 80: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Arrays mucho más manejables y foreachLos arrays estáticos (en los que en la declaración indicamos el tamaño de cada dimensión como en int[3][4] matriz; se implementan como las matrices de fortran en lugar de como punteros a punteros; esto hace que sean mucho más eficientes a la hora de calcularlos. Los arrays dinámicos (int[ ][ ] matriz;) sin embargo sí que se implementan como en C, como punteros a punteros. Por lo tanto, si necesitamos hacer cálculos de matrices extremadamente rápidos es aconsejable usar los arrays estáticos. En general todas estas características hacen que los arrays en D se manejen de la forma más intuitiva.

Page 81: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

String

Una consecuencia directa de estos arrays mejorados es que las cadenas nativas, a pesar de seguir siendo arrays de caracteres, son ahora infinítamente más manejables. Lo único que tenemos que tener en consideración es que los literales de cadena (caracteres entre comillas) son arrays inmutables, esto es, que no pueden ser modificadas y como D no deja asignar entre objetos mutables e inmutables sin hacer conversiones, no podemos asignar los literales de cadena a arrays de char si no los declaramos mutables. Ejemplos:

char[] cadenaMutable; // Cadena es un array de caracteres mutable; char[] otraCadenaMutable; cadenaMutable = “Hola!"; // ERROR: “Hola!" como literal de cadena es inmutable y no podemos asignarlo a un mutable otraCadenaMutable = “Hola!".dup // Correcto, dup crea una copia mutable del literal

Page 82: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

String

Para asignar literales de cadena sin llamar a .dup podríamos declarar a los arrays de caracteres como invariantes:invariant(char)[] cadenaInmutable = “hola!"; // Correcto, asignamos un inmutable a otro invariant(char)[] otraCadenaInmutable = cadenaMutable; // ERROR, asignando mutable a inmutable invariant(char)[] ultimaCadenaInmutable = cadenaMutable.idup; // Correcto, idup crea una copia inmutable Por practicidad, se ha creado un alias a invariant(char)[] llamado string, de modo que el ejemplo anterior quedaría como:string cadenaInmutable = "hola!"; // Correcto, asignamos un inmutable a otro string otraCadenaInmutable = cadenaMutable; // ERROR, asignando mutable a inmutable string ultimaCadenaInmutable = cadenaMutable.idup; // Correcto, idup crea una copia inmutable

Page 83: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

StringLas cadenas al no ser más que arrays de char en D pueden tienen las mismas operaciones que éstos (y el mismo rendimiento):// Asignación cadena1 = cadena2; // Copia string cadena1 = cadena2.dup; // // Copia de subcadenas string cadena1 = “Hola! Amigos!"; string cadena2 = cadena1[0..4]; // cadena2 = "Hola!" // Concatenación string cadena3 = cadena1 ~ cadena2; // Añadir al final string cadena4 = "Hola! "; cadena4 ~= “ Amigos!"; // Comparación if (cadena1 > cadena2) ...

Page 84: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 85: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

if

if ( /* expresión booleana */ ) sentencia; // Opcional: else sentencia;

Page 86: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Switch switch( /* variable */ ) { // if ( variable == 0) case 0: sentencia; break; // if ( (variable == 1) || (variable == 2) || (variable == 3) || (variable == 4) ) case 1,2,3,4: sentencia; break; // if (! (std.string.strcmp(variable,"hello") || std.string.strcmp(variable,"world")) ) case "hello", "world": sentencia; break; // "else" default: sentencia; break; }

Page 87: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

final swich

enum Estado { listo, ocupado, fallo }

final switch (Estado) { case listo: ...case ocupado:...case fallo...}

Page 88: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

While

while ( /* expresión booleana */ ) sentencia;

ó:

while ( /* expresión booleana */ ) { sentencia1; sentencia2; // ... }

Page 89: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Do-While

do { statement; } while ( /* expresión booleana */ );

Page 90: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

For

for ( /* initializer */ ; /* test */ ; /* increment */ ) statement;

Page 91: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

with import std.math, std.stdio; struct Point { double x, y; double norm() { return sqrt(x * x + y * y); } } void main() { Point p; int z; with (p) { x = 3; // Asigna a p.x p.y = 4; // Asigna a p explícitamente writeln(norm()); // Escribe p.norm, que es 5 z = 1; // z es visible } }

Page 92: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 93: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

-Manejo de memoria explícito, usando operadores new y delete, o bienlas funciones malloc y free.

Memoria manejada por un recolector de basura. Objetos específicospueden ser finalizados al salir del ámbito.

Ejemplo: (códigos equivalentes)C++ void pierdeaceite()

{ Obj *o = new Obj(); } //fuga de memoria al salir del scope

D void nopierdeaceite() { Obj o = new Obj(); } // el recolector libera la memoria

Page 94: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Recolección controlada, los programadores pueden agregar o excluir rangos de memoria de ser observados por el recolector, pueden pausar y reanudar el recolector (gc.disable(), gc.enable()) y forzar un ciclo de recolección generacional o de recolección completa.

-Si se desactiva el recolector, las referencias a los objetos que se hagan con un “new” se seguirán contabilizando, por lo que al re-activar la recolección esos objetos serán igualmente gestionados (no hay necesidad de llamar a delete).

-No genera conflicto con el recolector si se llamamos a delete.

Page 95: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 96: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Sobrecarga de operadores

La sobrecarga de operadores en D a veces son menos poderosas que las de C++. Un ejemplo es el opIndex, que sufre porque D no permite regresar referencias. Esto hace operaciones como obj[i]++; imposibles. La solución parcial de D es el operador opIndexAssign, que solo repara casos donde la expresión indexeada es solo un valor L como obj[i] = 5 pero no los casos originales.

Page 97: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

División en la biblioteca estándarLa biblioteca estándar en D es llamada Phobos. Algunos miembros de la comunidad piensan que Phobos es demasiado simple y que posee numerosos problemas, por lo cual un reemplazo llamado Tango fue escrito. Sin embargo, Tango y Phobos son por el momento incompatibles debido a varias diferencias (soporte de hilos, recolector de basura, etc). La existencia de dos bibliotecas, ambas de uso elevado, puede llevar a problemas significativos donde algunos paquetes usan Phobos y otros usan Tango.

Page 98: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Soporte sin finalizar para bibliotecas compartidas/dinámicasBibliotecas compartidas ELF de Unix son soportadas hasta un punto usando el compilador GDC. En Windows, DLLs son soportadas y permiten a objetos recolectados por el recolector de basura de ser seguramente pasados a funciones de C, ya que el recolector de basura revisa el stack por punteros. Sin embargo, todavía hay limitaciones con DLLs en D incluyendo el hecho de que la información en tiempo de ejecución de clases definidas en la DLL es incompatible con esas definidas en el ejecutable, y que cualquier objeto creado desde la DLL debe ser finalizado antes de que la DLL sea descargada.

Page 99: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Manipulación de String

El lenguaje tiene tres distintos tipos de caracteres (char, wchar y dchar) y tres alias de string (string, wstring y dstring, que son arrays dinámicos). UTF-8, UTF-16 y UTF-32 representan las unidades de código y strings respectivamente. Por razones de rendimientos, dividir strings y la propiedad length operan en unidades de código (caracteres) en lugar de puntos de código (algún valor numérico), que frecuentemente confunde a desarrolladores. Desde que UTF-8 y UTF-16 son codificaciones de caracteres de longitud variable, acceder por el indice de puntos de codigo no es posible sin el mantenimiento de tablas adicionales de búsqueda. El código que necesite rápido acceso a puntos de código debería convertir los strings a UTF-32 primero, o usar tablas de búsqueda. Sin embargo, esto es también sucede en otros lenguajes de programación que soportan Unicode, como Java y C# que usan UTF-16, por lo tanto, es necesario usar sustitutos para representar a algunos puntos de código.

Page 100: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Implementaciones en DImplementaciones en D

-IDE Poseidón -Juegos

- ABA Juegos (Titanion, Torus Troopers,Tumiki Fighters)

-AREA2048-Empire-QonkD-Yagé

Page 101: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.
Page 102: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.

Muchas Muchas Gracias!Gracias!

Page 103: Lenguaje. Historia del lenguaje. Características Procedimientos, funciones y pasajes de parámetros Sistema de tipos Estructuras de control Manejo de memoria.