From: Leandro Lucarella Date: Mon, 30 May 2005 01:33:09 +0000 (+0000) Subject: Prácticamente terminado, falta redondear detalles. X-Git-Tag: svn_import~7 X-Git-Url: https://git.llucax.com/z.facultad/75.31/presentacion.git/commitdiff_plain/85303ecd2ba1121437ae4cb2581f4bb1bbece4ac Prácticamente terminado, falta redondear detalles. --- diff --git a/ejemplos/invariante_repr.d b/ejemplos/invariante_repr.d new file mode 100644 index 0000000..cca424c --- /dev/null +++ b/ejemplos/invariante_repr.d @@ -0,0 +1,27 @@ + +class Fecha +{ + int dia = 1; + int mes = 1; + invariant + { + assert(1 <= dia && dia <= 31); + assert(1 <= mes && mes <= 12); + } + void p() + { + int d = dia; + dia = 50; + dia = d; + printf("%02d-%02d\n", dia, mes); + } +} + +int main() +{ + Fecha f = new Fecha; + f.p(); + f.dia = 40; + f.p(); + return 0; +} diff --git a/ejemplos/modulo1.d b/ejemplos/modulo1.d new file mode 100644 index 0000000..70774f9 --- /dev/null +++ b/ejemplos/modulo1.d @@ -0,0 +1,10 @@ + +import modulo2; + +class C { float i; } + +void func(modulo2.C c) +{ + printf("c.i = %d\n", c.i); +} + diff --git a/ejemplos/modulo2.d b/ejemplos/modulo2.d new file mode 100644 index 0000000..598d3b0 --- /dev/null +++ b/ejemplos/modulo2.d @@ -0,0 +1,3 @@ + +class C { int i; } + diff --git a/ejemplos/modulos.d b/ejemplos/modulos.d new file mode 100644 index 0000000..d551683 --- /dev/null +++ b/ejemplos/modulos.d @@ -0,0 +1,8 @@ +import modulo1; +import modulo2; + +int main() +{ + func(new modulo2.C); + return 0; +} diff --git a/ejemplos/pre_post.d b/ejemplos/pre_post.d new file mode 100644 index 0000000..920cb60 --- /dev/null +++ b/ejemplos/pre_post.d @@ -0,0 +1,22 @@ + +import std.math; + +long raiz(long x) + in + { + assert(x >= 0); + } + out (result) + { + assert((result * result) == x); + } + body + { + return cast(long) sqrt(cast(float) x); + } + +int main() +{ + raiz(8); + return 0; +} diff --git a/ejemplos/propiedades.d b/ejemplos/propiedades.d new file mode 100644 index 0000000..473f413 --- /dev/null +++ b/ejemplos/propiedades.d @@ -0,0 +1,22 @@ + +class C +{ + int _i; + int read() { return _i; } + int write(int i) { return _i = i; } + int rw() { return _i; } + int rw(int i) { return _i = i; } +} + +int main() +{ + C c = new C; + // c.read = 1; NO COMPILA + c.write = 2; + printf("c.read = %d\n", c.read); + // printf("c.read = %d\n", c.write); NO COMPILA + c.rw = 3; + printf("c.rw = %d\n", c.rw); + return 0; +} + diff --git a/ejemplos/seguridad.d b/ejemplos/seguridad.d new file mode 100644 index 0000000..df984f1 --- /dev/null +++ b/ejemplos/seguridad.d @@ -0,0 +1,24 @@ + +class C +{ + private int i; +} + +struct S +{ + private int i; +} + +int main() +{ + C c = new C; + printf("c.i = %d\n", c.i); + c.i = 1; + printf("c.i = %d\n", c.i); + S s; + printf("s.i = %d\n", s.i); + s.i = 1; + printf("s.i = %d\n", s.i); + return 0; +} + diff --git a/ejemplos/unit_test.d b/ejemplos/unit_test.d new file mode 100644 index 0000000..925e7c6 --- /dev/null +++ b/ejemplos/unit_test.d @@ -0,0 +1,14 @@ + +class C +{ + unittest + { + assert(ok()); + } + static bit ok() { return false; } +} + +int main() +{ + return 0; +} diff --git a/presentacion_d.lyx b/presentacion_d.lyx index 28a50be..4428aa1 100644 --- a/presentacion_d.lyx +++ b/presentacion_d.lyx @@ -35,6 +35,14 @@ Leandro Lucarella (77891) \layout Date 30 de Mayo de 2005 +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + \layout Section Introducción @@ -427,6 +435,11 @@ f.mes = 5; f.print(); \layout Subsubsection + +\begin_inset LatexCommand \label{sub:tipo-class} + +\end_inset + class \layout Standard @@ -435,6 +448,16 @@ Las clases son la forma en la que D implementa la orientaci Por ahora sólo adelantaremos que es muy similar a un struct, sólo que guarda algo más de información de control (como la tabla virtual) para poder implement ar polimorfismo y herencia. +\layout Subsubsection + +interface +\layout Standard + +Las interfaces son un caso particular de clases, que no puede tener atributos, + sólo métodos. + Una clase puede implementar varias interfaces, por lo que esto no e es + más que una forma limitada de implementar herencia múltiple, eliminando + el problema de la representación en memoria de los datos. \layout Section Expresiones @@ -974,12 +997,6 @@ tiene un comportamiento aleatorio. se puede usar memoria no administrada por el recolector. \layout Subsection -Instrucciones -\layout Comment - -por ahora vuela porque no sé a qué se refiere -\layout Subsection - \begin_inset LatexCommand \label{sub:Rutinas} @@ -1116,6 +1133,11 @@ call extra que no figuraban en la declaración de la función. \layout Subsubsection + +\begin_inset LatexCommand \label{sub:Sobrecarga-de-funciones} + +\end_inset + Sobrecarga de funciones \layout Standard @@ -1149,30 +1171,709 @@ name mangling \layout Section Estructura del programa +\layout Standard + +La estructura general de un programa D es muy similar a la de uno en C++. + Simplemente se compone de funciones y tipos definidos por el usuario. + Existe una función especial llamada +\family typewriter +main() +\family default + que es el punto de partida del programa, indispensable a menos que estemos + construyendo una biblioteca. +\layout Subsection + +Módulos +\layout Standard + +D elimina el preprocesador e incorpora el concepto de módulo (a diferencia + de C++ que utiliza espacios de nombre). + El módulo tiene alcance de archivo y tiene correspondencia 1 a 1 con la + ruta y nombre del archivo. + Por ejemplo el módulo +\family typewriter +mi.primer.modulo +\family default + se busca en +\family typewriter +mi/primer/modulo.d +\family default +. + A la ruta representada como módulo se la llama +\emph on +paquete +\emph default +; es decir, el módulo +\family typewriter +modulo +\family default + pertenece al paquete +\family typewriter +mi.primer +\family default +. + El módulo entonces provee un espacio de nombres, cuyos símbolos pueden + ser importados en otros módulos. + Por ejemplo: +\layout Standard + +modulo1.d: +\layout LyX-Code + +import modulo2; +\layout LyX-Code + +class C +\layout LyX-Code + +{ +\layout LyX-Code + + float i; +\layout LyX-Code + +} +\layout LyX-Code + +void func(modulo2.C c) +\layout LyX-Code + +{ +\layout LyX-Code + + printf("c.i = %d +\backslash +n", c.i); +\layout LyX-Code + +} +\layout Standard + +modulo2.d: +\layout LyX-Code + +class C +\layout LyX-Code + +{ +\layout LyX-Code + + int i; +\layout LyX-Code + +} +\layout Standard + +modulos.d +\layout LyX-Code + +import modulo1; +\layout LyX-Code + +import modulo2; +\layout LyX-Code + +int main() +\layout LyX-Code + +{ +\layout LyX-Code + + func(new modulo2.C); +\layout LyX-Code + + return 0; +\layout LyX-Code + +} +\layout Standard + +Como se puede observar, no es imperativo poner el modulo al que pertenece + un símbolo, a menos que se lo quiera desambiguar (si hay 2 símbolos con + el mismo nombre en 2 módulos distintos). \layout Subsection -Módulos, espacios de nombres, Interfaces +Compilación condicional \layout Standard +Al no proveer un precompilador, D provee un mecanismo de compilación condicional + directamente incluída en el lenguaje. + Simplemente se agregan bloques de código que se compilan sólamente si se + le pasa un cierto parámetro al compilador indicando que porción compilar. + Este concepto va un poco más allá, ya que hay compilación condicional incluso + de bloques no son puestos explícitamente como tales, como los bloques de + invariante de representación de una clase o de pre y post condiciones de + funciones. + Ejemplo: +\layout LyX-Code + +version (OPTIMIZE) +\layout LyX-Code + +{ +\layout LyX-Code + + version (DEBUG) printf( +\begin_inset Quotes eld +\end_inset + +entrando a optimización +\begin_inset Quotes erd +\end_inset + +); +\layout LyX-Code + + optimizar(); +\layout LyX-Code + +} +\layout Standard + +D además provee varios identificadores de versión predefinidos, como la + plataforma, +\emph on +endianess +\emph default +, sistema operativo, etc. +\layout Standard + +Además provee otros métodos, como +\family typewriter +static if +\family default +, +\family typewriter +static assert +\family default +, +\family typewriter +iftype +\family default + o +\family typewriter +debug +\family default +, pero son todas vueltas de tuerca sobre el mismo concepto. +\layout Subsection + +Assembly embebido +\layout Standard + +D, al igual que C, permite embeber assembly en el lenguaje. + Esto es útil para hacer código de alta performance para fragmentos críticos, + ya que D está pensando como un lenguaje de alta performance y apto para + el desarrollo de aplicaciones de sistema (como controladores, etc). \layout Section Orientación a objetos +\layout Standard + +Como ya se ha mencionado, D provee orientación a objetos principalmente + a través de el tipo class (ver sección +\begin_inset LatexCommand \vref{sub:tipo-class} + +\end_inset + +), pero provee algunos mecanismos también a través de los módulos o struct. \layout Subsection -TAD's +Abstracción +\layout Standard + +La abstracción de datos puede darse a nivel de class, struct o module. + Ambos proveen mecanismos para poder efectuar operaciones sobre un dato + sin conocerlo. + En el caso de struct y class es exactamente igual en cuanto a abstracción. + El módulo es un poco diferente ya que hay sólo una instancia del mismo + (es decir, todos sus datos son estáticos), pero también puede servir para + abstraer. + D provee sintaxis acoplada ( +\emph on +bundle +\emph default +) a través del operador de +\emph on +scope +\emph default + +\begin_inset Quotes eld +\end_inset + +. +\begin_inset Quotes erd +\end_inset + +, que se utiliza tanto para class como para struct y module. + El module, al no ser un tipo en sí, no soporta sintaxis desacoplada ( +\emph on +unbundle +\emph default +). + Lo mismo pasa con los métodos estáticos de clase. +\layout Standard + +Todos los objetos en D son con estado explícito, aunque pueden +\emph on +emularse +\emph default + objetos +\emph on +inmutables +\emph default + declarándolos +\family typewriter +const +\family default +, pero esto no hace se se resuelvan en tiempo de compilación, en realidad + tienen estado sólo que el compilador no deja que se modifique. + Es decir, no hay forma de tener abstracción declarativa. +\layout Subsubsection + +Propiedades +\layout Standard + +D provee un mecanismo muy interesante y práctico, las propiedades. + Una clase (o estructura) puede tener métodos especiales que pueden ser + llamados como si fueran atributos de la clase. + No es más que azucar sintáctico pero es muy útil y está implementado de + una forma muy simple. + Cualquier método que tenga un sólo argumento y devuelva un valor del mismo + tipo se convierte en una propiedad de escritura y cualquier método que + no tome argumentos y devuelva un valor se convierte en una propiedad de + lectura. + Incluyendo ambos se pueden tener propiedades de lectura/escritura. + Veamos un ejemplo: +\layout LyX-Code + +class C +\layout LyX-Code + +{ +\layout LyX-Code + + int _i; +\layout LyX-Code + + int read() { return _i; } +\layout LyX-Code + + int write(int i) { return _i = i; } +\layout LyX-Code + + int rw() { return _i; } +\layout LyX-Code + + int rw(int i) { return _i = i; } +\layout LyX-Code + +} +\layout LyX-Code + +int main() +\layout LyX-Code + +{ +\layout LyX-Code + + C c = new C; +\layout LyX-Code + + // c.read = 1; NO COMPILA +\layout LyX-Code + + c.write = 2; +\layout LyX-Code + + printf("c.read = %d +\backslash +n", c.read); +\layout LyX-Code + + // printf("c.read = %d +\backslash +n", c.write); NO COMPILA +\layout LyX-Code + + c.rw = 3; +\layout LyX-Code + + printf("c.rw = %d +\backslash +n", c.rw); +\layout LyX-Code + + return 0; +\layout LyX-Code + +} +\layout Standard + +Además todos los tipos básicos poseen propiedades, algunas comunes a todos + (como +\family typewriter +sizeof +\family default +, que devuelve su tamaño, en general estos son todos resueltos en tiempo + de compilación) y otros particulares de cada tipo (como +\family typewriter +length +\family default + para los array, que devuelve la cantidad de elementos que almacena). +\layout Subsubsection + +Sobrecarga de operadores +\layout Standard + +Otro mecanismo importante de abstracción que provee D es la sobrecarga de + operadores. + Se puede sobrecargar los operadores de clases y estructuras, de manera + tal de hacerlos ver sintácticamente como tipos nativos del lenguaje. + También es azucar sintáctico y un caso particular de sobrecarga de funciones + (ver página +\begin_inset LatexCommand \pageref{sub:Sobrecarga-de-funciones} + +\end_inset + +). +\layout Subsection + +Seguridad +\layout Standard + +D provee mecanismos de seguridad, tanto a nivel de módulo como de clase + y estructuras, aunque se ha comprobado empíricamente que el compilador + no lo está chequeando por el momento. + Por ejemplo, el siguiente código compila y corre: +\layout LyX-Code + +class C +\layout LyX-Code + +{ +\layout LyX-Code + + private int i; +\layout LyX-Code + +} +\layout LyX-Code + +int main() +\layout LyX-Code + +{ +\layout LyX-Code + + C c = new C; +\layout LyX-Code + + c.i = 1; +\layout LyX-Code + + return 0; +\layout LyX-Code + +} +\layout Subsection + +Herencia +\layout Standard + +El único tipo que permite herencia es class (y su sub-tipo interface). + D permite herencia simple entre clases comunes y una herencia múltiple + limitada a través de las interfaces. + Es decir, una clase sólo puede heredar de una sola clase, pero puede implementa +r muchas interfaces. \layout Subsection Polimorfismo -\layout Comment +\layout Standard -Si hay orientación a objetos y describir cómo es. +D implementa polimorfismo principalmente (pero no únicamente) a través de + las clases (e interfaces) y sus funciones virtuales, pero también a través + de la sobrecarga de funciones en general. +\layout Subsubsection + +Polimorfismo estático +\layout Standard + +D provee tipos genéricos, también conocidos en el mundo de los lenguajes + compilados como +\emph on +templates +\emph default + o polimorfismo estático, ya que permite que una función o clase se comporte + de distinta manera pero se resuelve en tiempo de compilación. \layout Section Paralelismo / Concurrencia -\layout Section +\layout Standard + +D provee algunas pocas primitivas para el soporte de concurrencia. + En la biblioteca estándar provee una clase para ejecutar múltiples hilos + y provee en el lenguaje la palabra reservada +\family typewriter +synchronized +\family default + para agregar bloqueo y desbloqueo de exclusión mutua ( +\emph on +mutex +\emph default +) automáticamente antes y después (respectivamente) de bloque que encierra. + También puede usarse como clasificador de almacén (es decir, para proteger + una variable) o como modificador de una función (para proteger dicha función) + o de clase o de cualquier otra sentencia. +\layout Standard -¿Para qué no sirve este lenguaje? +Es necesario utilizar la clase +\family typewriter +Thread +\family default + para ejecutar múltiples hilos ya que el recolector de basura tiene que + saber de todos los hilos que están corriendo para poder administrar su + memoria (y frenarlos ante un ciclo de recolección), aunque técnicamente + podría evitarse ya que se puede acceder a cualquier biblioteca de C (incluyendo + la de hilos). \layout Section -¿Para qué sí sirve este lenguaje? +Programación segura +\layout Standard + +Uno de los objetivos principales de D es implementar técnicas de programación + segura, para tratar de evitar (o al menos detectar) la mayor cantidad de + errores de manera simple. + Veamos entonces algunos mecanismos que provee para satisfacer este objetivo. +\layout Subsection + +Programación por contrato +\layout Standard + +La programación por contrato consiste en imponer ciertas reglas que se cumplan + en distintos momentos del programa. + Básicamente provee 3 conceptos para verificar estos +\emph on +contratos +\emph default +: +\emph on +assert +\emph default +, invariantes de representación y pre y post condiciones. + Esto parece contradecir el objetivo de D de ser un lenguaje de alta performance +, ya que si se hacen muchos chequeos, inevitablemente se sacrifica performance. + Pero esto no es necesariamente cierto, ya que todos estos mecanismos pueden + ser desactivados en tiempo de compilación, logrando tener un código para + depuración muy robusto y lleno de chequeos y un código para producción + muy eficiente y rápido. +\layout Subsubsection + +assert +\layout Standard + +Este es el tipo más básico de contrato, provisto también de una forma más + primitiva por C (a través del precompilador). + Simplemente evalua en tiempo de ejecución que una expresión evalue a +\emph on +true +\emph default +. + Si no es así, simplemente el programa lanza una excepción. +\layout Subsubsection + +Invariante de representación +\layout Standard + +Las clases puede incluir un invariante de presentación. + Esto es un fragmento de código que se ejecuta cada vez que se cambia una + instancia de la clase (excepto cuando los cambios se realizan desde una + función miembro. + Esto permite asegurar que los objetos estén siempre en estado consistente, + mientras se ejecute código que no conoce su representación. + Por ejemplo: +\layout LyX-Code + +class Fecha +\layout LyX-Code + +{ +\layout LyX-Code + + int dia = 1; +\layout LyX-Code + + int mes = 1; +\layout LyX-Code + + invariant +\layout LyX-Code + + { +\layout LyX-Code + + assert(1 <= dia && dia <= 31); +\layout LyX-Code + + assert(1 <= mes && mes <= 12); +\layout LyX-Code + + } +\layout LyX-Code + + void p() +\layout LyX-Code + + { +\layout LyX-Code + + int d = dia; +\layout LyX-Code + + dia = 50; // ok, dentro de la clase no se chequea +\layout LyX-Code + + dia = d; +\layout LyX-Code + + printf("%02d-%02d +\backslash +n", dia, mes); +\layout LyX-Code + + } +\layout LyX-Code + +} +\layout LyX-Code + +Fecha f = new Fecha; +\layout LyX-Code + +f.p(); // ok +\layout LyX-Code + +f.dia = 40; // error! +\layout Subsubsection + +Pre y post condiciones +\layout Standard + +Toda función puede tener, además de su cuerpo, un bloque de código de precondici +ones y/o un bloque de código de postcondiciones, que será ejecutado antes + y/o después de ejecutar la función (respectivamente). + Veamos un ejemplo: +\layout LyX-Code + +long raiz(long x) +\layout LyX-Code + + in +\layout LyX-Code + + { +\layout LyX-Code + + assert(x >= 0); +\layout LyX-Code + + } +\layout LyX-Code + + out (result) +\layout LyX-Code + + { +\layout LyX-Code + + assert((result * result) == x); +\layout LyX-Code + + } +\layout LyX-Code + + body +\layout LyX-Code + + { +\layout LyX-Code + + return cast(long) std.math.sqrt(cast(float) x); +\layout LyX-Code + + } +\layout Standard + +El parámetro del bloque +\family typewriter +out +\family default + es el valor devuelto por el cuerpo de la función. + Entonces cuando se llame a +\family typewriter +raiz(8) +\family default +, el compilador (a menos que esté en modo +\emph on +release +\emph default +) lo traducirá a: +\layout LyX-Code + +assert(8 >= 0); // ok +\layout LyX-Code + +long tmp = raiz(8); // devuelve 2 por la conversión a long +\layout LyX-Code + +assert((2 * 2) == 8); // error! +\layout Subsection + +Casos de prueba +\layout Standard + +D provee dentro del lenguaje herramientas para realizar casos de prueba + ( +\emph on +unit tests +\emph default +) para asegurarse que una clase se comporte como debe. + Este código se ejecuta cuando se inicia el programa si se compila con la + opción de +\family typewriter +unittest +\family default +. + Por ejemplo: +\layout LyX-Code + +class C +\layout LyX-Code + +{ +\layout LyX-Code + + unittest +\layout LyX-Code + + { +\layout LyX-Code + + assert(ok()); +\layout LyX-Code + + } +\layout LyX-Code + + static bit ok() { return false; } +\layout LyX-Code + +} +\layout Standard + +Un programa que use esta clase saldrá apenas se inicia con una excepción + por el +\family typewriter +assert +\family default +. \the_end