Download Capítulo II. Tipos Abstractos de Datos. Estructuras de Datos, su
Document related concepts
Transcript
Capítulo II. Tipos Abstractos de Datos. Estructuras de Datos, su implementación y enseñanza en la carrera de Informática. 1.1 Introducción. Los índices están mal sería II.1 , todo está así El estudio de las estructuras de datos es casi tan antiguo como el nacimiento de la programación, y se convirtió en un tema capital en este ámbito desde finales de la década de los 60. (Badía 2004) Con la aparición de los lenguajes de programación estructurados, surge el concepto de tipo de datos, definido como un conjunto de valores que sirve de dominio de ciertas operaciones. En estos lenguajes (C, Pascal y similares), los tipos de datos se usan sobre todo para clasificar los objetos de los programas - variables, parámetros y constantes - y determinar qué valores pueden tomar y qué operaciones se les pueden aplicar. Esta noción, no obstante, se reveló insuficiente en el desarrollo de software a gran escala, dado que el uso de los datos dentro de los programas no conocía más restricciones que las impuestas por el compilador, a los nuevos tipos de datos definidos por el usuario no se restringía de ninguna manera su ámbito de manipulación. No entiendo esto Para solucionar esta carencia, diversos investigadores introdujeron a mediados de la década de los 70 el concepto de Tipo Abstracto de Datos, abreviadamente, TAD que considera un tipo de datos no sólo como el conjunto de valores que lo caracteriza sino también como las operaciones que sobre él se pueden aplicar, juntamente con las diversas propiedades que determinan inequívocamente su comportamiento. Todos estos autores coincidieron en la necesidad de emplear una notación formal para describir el comportamiento de las operaciones, no sólo para impedir cualquier interpretación ambigua sino para identificar claramente el modelo matemático denotado por el TAD. (Knuth 1973; Lipschutz 1977; Goguen, Thatcher et al. 1978) La abstracción es un mecanismo fundamental para la comprensión de fenómenos o situaciones que implican gran cantidad de detalles. La idea de abstracción es uno de los conceptos más potentes en el proceso de resolución de problemas. Se entiende por abstracción la capacidad de manejar un objeto como un concepto general, sin considerar la enorme cantidad de detalles que pueden estar asociados con dicho objeto. Sin abstracción no sería posible manejar, ni siquiera entender, la gran complejidad de ciertos problemas. (Guttag and Liskov 1986; Blackwell 1998) El proceso de abstracción presenta dos aspectos complementarios: descartar los aspectos relevantes del objeto COMO QUE DESCARTAR LO RELEVANTE ignorar aspectos irrelevantes del mismo (la irrelevancia depende del nivel de abstracción, ya que si se pasa a niveles más concretos, es posible que ciertos aspectos pasen a ser relevantes). Uno de los puntos más cruciales asociados con el diseño de un nuevo sistema involucra la gestión de la complejidad del proceso de diseño. Habitualmente los buenos diseñadores emplean alguna forma de abstracción como herramienta para tratar esta complejidad. En este momento puede ser utilizado un tipo especial de abstracción conocido como abstracción de datos. Esto implica una descripción abstracta o lógica, tanto de los datos requeridos por el sistema informático como de las operaciones que pueden ser ejecutadas con esos datos. El uso de la abstracción de datos durante el desarrollo del software permite al diseñador concentrase en cómo son usados los datos en el sistema para resolver el problema que le ocupa, sin tener que preocuparse por la representación y tratamiento de los datos en la memoria del computador, de ahí que se plantee que la verdadera utilidad de los Tipos Abstractos de Datos aparece en el diseño de nuevos tipos de datos. (Heileman 2003) La extrapolación de esta técnica a sistemas de gran tamaño conduce al llamado diseño modular de las aplicaciones y se caracteriza por el hecho de dividir el problema original en varios subproblemas más pequeños, cada uno de ellos con una misión bien determinada dentro del marco general del proyecto, que interaccionan de manera clara y mínima, de tal forma que todos ellos juntos solucionan el problema inicial; si algunos subproblemas siguen siendo demasiado complicados, se les aplica el mismo proceso, y así sucesivamente hasta llegar al estado en que todos los subproblemas son lo bastante sencillos como para detener el proceso. El resultado es una estructura jerárquica que refleja las descomposiciones efectuadas; cada descomposición es el resultado de abstraer las características más relevantes del problema que se está tratando de los detalles irrelevantes en el nivel de razonamiento actual, los cuales adquieren importancia en descomposiciones sucesivas. Desde el punto de vista de su gestión, cada subproblema es un Tipo Abstracto de Datos que se encapsula en lo que se denomina un módulo; 1 precisamente, la mejora respecto al diseño descendente proviene de la ocultación de la representación de los datos y de la limitación de su manipulación al ámbito del módulo que define el tipo. A primera vista, puede parecer costoso, e incluso absurdo, dividir una aplicación en módulos y escribir procedimientos y funciones para controlar el acceso a la estructura que implementa un Tipo Abstracto de Datos, sin embargo esta metodología abunda en diversas propiedades interesantes: Abstracción. Los usuarios de un Tipo Abstracto de Datos no necesitan conocer detalles de implementación (tanto en lo que se refiere a la representación del tipo como a los algoritmos y a las técnicas de codificación de las operaciones), por lo que pueden trabajar en un grado muy alto de abstracción. Como resultado, la complejidad de un programa queda diluida entre sus diversos componentes. Corrección. Un TAD puede servir como unidad indivisible en las pruebas de programas, de manera que en una aplicación que conste de diversos tipos abstractos no tengan que probarse todos a la vez, sino que es factible y recomendable probarlos por separado e integrarlos más adelante. Evidentemente, es mucho más fácil detectar los errores de esta segunda manera, porque las entidades a probar son más pequeñas y las pruebas pueden ser más exhaustivas. Eficiencia. La separación clara entre un programa y los TAD que usa favorece la eficiencia, ya que la implementación de un tipo se retrasa hasta conocer las restricciones de eficiencia sobre sus operaciones, y así se pueden elegir los algoritmos óptimos. La implementación de un Tipo Abstracto de Datos supone una traducción de su especificación en la sintaxis de un lenguaje de programación particular. Esta traducción se compone de las declaraciones de variables apropiadas, que sean necesarias para definir los datos y un procedimiento o rutina de acceso que implemente cada una de las operaciones requeridas por el TAD. El término Estructura de Datos se refiere a una colección de variables que están relacionadas de alguna forma específica. 1.2 Tipos Abstractos de Datos, Estructuras de Datos y tipos de datos. Se puede decir que la abstracción permite estudiar los fenómenos complejos siguiendo un método jerárquico, es decir, por sucesivos niveles de detalle. Generalmente, se sigue un sentido descendente, desde los niveles más generales a los niveles más concretos. 2 Los programas son objetos complejos que pueden contener varios miles de instrucciones, cada una de las cuales puede dar lugar a un error del programa y que, por lo tanto, necesitan mecanismos de definición que eviten en la medida de lo posible que el programador cometa errores. En el proceso de programación se puede extender el concepto de abstracción tanto a las acciones, mediante la llamada abstracción procedural (uso de procedimientos), como a los datos, mediante los llamados tipos abstractos de datos. La aplicación a los datos de las ideas de abstracción y de ocultación de información ha tardado más tiempo en producirse. El concepto de tipo abstracto de datos, propuesto hacia 1974 por John Guttag, vino a desarrollar este aspecto. Análogamente a los procedimientos, los llamados tipos abstractos de datos constituyen un mecanismo que permite generalizar y encapsular los aspectos relevantes sobre la información (datos) que maneja el programa. (Liskov and Guttag 2001) No se deben confundir los conceptos de tipo de datos, estructura de datos y tipo abstracto de datos. Todos ellos constituyen diferentes niveles en el proceso de abstracción referida a los datos. Los datos son las propiedades o atributos (cualidades o cantidades) sobre hechos u objetos que procesa el ordenador. El tipo de datos, en un lenguaje de programación, define el conjunto de valores que una determinada variable puede tomar, así como las operaciones básicas sobre dicho conjunto. Los tipos de datos pueden variar de un lenguaje a otro, tanto los tipos simples como los mecanismos para crear tipos compuestos. Para el usuario, el proceso de representación es invisible. El programador no manipula directamente las cadenas de bits que constituyen los datos, sino que hace uso de las operaciones previstas para cada tipo de datos. Entre el nivel de los tipos de datos y el nivel de los tipos abstractos nos encontramos con las llamadas estructuras de datos. Las estructuras de datos son conjuntos de variables, quizás de tipos distintos, relacionadas (conectadas) entre sí de diversas formas y las operaciones definidas sobre esa agrupación. Ejemplos de estructuras de datos las podemos encontrar en muchos ámbitos, desde las matemáticas (estructuras algebraicas: grupo, anillo) hasta el mundo de los negocios (estructura de una empresa). Los elementos de una estructura de datos dependen del lenguaje de programación a través de los tipos de datos que los definen. Sin embargo, la estructura en sí, que está definida por el tipo de relación entre los elementos, no depende del lenguaje de programación empleado. Las estructuras de datos se caracterizan por el tipo de los elementos de la estructura, las 3 relaciones definidas sobre los elementos y las operaciones permitidas sobre la estructura. Operaciones típicas sobre estructuras de datos suelen ser: acceder a los elementos (por la posición que ocupan o por la información que contienen), buscar elementos, insertar o borrar elementos, modificar las relaciones entre los elementos. Al nivel de las estructuras de datos, ya no tienen relevancia las operaciones que se puedan realizar sobre los componentes individuales de la misma, solamente la tienen las operaciones que implican a la estructura globalmente. En el nivel más alto de abstracción estarían los tipos abstractos de datos, estos se pueden ver como modelos matemáticos sobre los que se definen una serie de operaciones. El tipo abstracto de datos es una colección de valores y operaciones que se definen mediante una especificación que es independiente de cualquier representación. Para representar el modelo matemático básico de un TAD se emplean estructuras de datos y las operaciones definidas en el modelo se representan mediante procedimientos. Por ejemplo, se podría definir el TAD número complejo como un objeto con dos componentes que son números reales y sobre el que se definen las operaciones suma y producto de números complejos. En una definición de este tipo no importa si en un programa concreto se utiliza una estructura tipo registro con dos campos para representar los datos o bien una estructura tipo arreglo con dos elementos. Desde el punto de vista formal ese tipo de información es irrelevante. Así mismo, no es necesario conocer cómo se realizan las operaciones definidas formalmente, sólo importa qué hacen para poder usarlas correctamente. 1.3 Diferentes paradigmas de programación para implementar las Estructuras de Datos. El modelo general de las computadoras, desde que fue esbozado por von Neumann, no ha cambiado mucho, mientras que la invención humana para proponerse nuevos problemas a resolver, usando la computadora, parece no tener límites. (Aspray 2000) En consecuencia, los lenguajes de programación tienen que adaptarse a éstas crecientes necesidades y aumentar la expresividad para poder resolver problemas muy diversos y cada vez más complejos. Además, tienen que ofrecer cierta eficiencia en la ejecución. Es un logro difícil de alcanzar y un reto la selección adecuada, tanto de las Estructuras de Datos como de los Lenguajes de programación para implementarlas. 4 1.3.1 Lenguajes funcionales. Tradicionalmente los matemáticos han resuelto problemas usando el concepto de función, la cual convierte ciertos datos en resultados. Si se conoce cómo evaluar una función usando la computadora, se pueden resolver automáticamente muchos problemas. Este análisis fue realizado por algunos matemáticos que consideraron la computadora una herramienta importante para su trabajo, creando los lenguajes de programación funcionales, los que aprovechan la posibilidad que tienen las funciones para manipular datos simbólicos, y no solamente numéricos, y la propiedad que les permite componer, creando de esta manera, la oportunidad para resolver problemas complejos a partir de las soluciones a otros más sencillos. También se incluyó la posibilidad de definir funciones recursivamente. (Steele and Sussman 1979) Un lenguaje funcional ofrece conceptos que son muy entendibles y relativamente fáciles de manejar. El lenguaje funcional más antiguo, y seguramente el más popular hasta la fecha, es LISP, diseñado por McCarthy en la segunda mitad de los años 50. Su área de aplicación es principalmente la Inteligencia Artificial. En la década de los 80 hubo una nueva ola de interés por los lenguajes funcionales, añadiendo la tipificación y algunos conceptos modernos de modularización y polimorfismo. (Mcarthy 1965) Programar en un lenguaje funcional significa construir funciones a partir de las ya existentes. Por lo tanto es importante conocer y comprender bien las funciones que conforman la base del lenguaje, así como las que ya fueron definidas previamente. De esta manera se pueden ir construyendo aplicaciones cada vez más complejas. El uso del LISP en la implementación de Listas, como Estructura de Datos, hace sencilla y elegante la programación de las operaciones básicas y las aplicaciones a problemas concretos, como el cálculo de la derivada de funciones, trabajo con polinomios, etc. 1.3.2 Lenguajes Lógicos. Otra forma de razonar para resolver problemas en matemáticas se fundamenta en la lógica de primer orden. El conocimiento básico de las matemáticas se puede representar en la lógica en forma de axiomas, a los cuales se añaden reglas formales para deducir aspectos verdaderos (teoremas) a partir de los axiomas. Gracias al trabajo de algunos matemáticos, de finales de siglo pasado y principios de éste, se encontró la manera de automatizar computacionalmente el razonamiento lógico -particularmente para un subconjunto 5 significativo de la lógica de primer orden- que permitió que la lógica matemática diera origen a otro tipo de lenguajes de programación, conocidos como lenguajes lógicos. (Colmeraure and Roussel 1993; Lezcano, Lobato et al. 2000) En la programación lógica el proceso de descripción de un dominio de aplicación se lleva a cabo mediante la conceptualización de los objetos y las relaciones que hipotéticamente existen, lo cual se expresa a través de un lenguaje formal apropiado. La noción de un objeto puede ser amplia. Pueden ser objetos concretos (un circuito específico, una persona especifica) o abstractos (el número dos, el conjunto de todos los enteros, el concepto de justicia). Por otra parte, pueden ser primitivos o compuestos, como es el caso de un circuito que consta de muchos componentes. (Lezcano 1998; Lezcano, Lobato et al. 2000) Una relación, es una cualidad o atributo de un grupo de objetos con respecto a otros. Por supuesto, una relación en particular puede mantenerse para más de un grupo de objetos. La característica esencial de la programación lógica es su semántica declarativa, de ahí la forma simple de determinar la veracidad o falsedad de cada una de las sentencias. La mayoría de los sistemas de programación lógica usan una forma clausal (variante del cálculo de predicados). Esta forma es extremadamente expresiva por la existencia de operadores lógicos y variables, lo que hace posible codificar información parcial acerca de un dominio determinado. En lenguajes más restringidos como los marcos, se deben escribir procedimientos para codificar información parcial. El tipo más simple de expresión, en la forma clausal, es el átomo. Un átomo expresa una relación específica, válida para un grupo determinado de objetos. Dentro de los lenguajes orientados a la lógica tiene significativa importancia el Prolog, que ofrece la ventaja de que él mismo constituye un motor de inferencia para sistemas expertos, con lógica de primer orden en cuyo caso el programa es realmente la base de conocimiento más un conjunto de datos de partida. Es el primer lenguaje lógico y el más conocido y utilizado. Sus orígenes se remontan a los inicios de la década de los 70 con los trabajos del grupo de A. Colmerauer en Marsella, Francia. (Colmeraure and Roussel 1993) También en este caso, las aplicaciones a la Inteligencia Artificial mantienen el lenguaje vivo y útil. 6 En el caso de la programación lógica, el trabajo del programador se restringe a la buena descripción del problema en forma de hechos y reglas. A partir de ésta se pueden encontrar muchas soluciones dependiendo de como se formulen las preguntas (metas), que tienen sentido para el problema. Si el programa está bien definido, el sistema encuentra automáticamente las respuestas a las preguntas formuladas. En este caso ya no es necesario definir el algoritmo de solución, como en la programación imperativa, en cambio, lo fundamental aquí es expresar bien el conocimiento sobre el problema mismo. En programación lógica, al igual que en programación funcional, el programa, en este caso los hechos y las reglas, están muy alejados del modelo von Neumann que posee la máquina en la que tienen que ser interpretados; por lo tanto, la eficiencia de la ejecución no puede ser comparable con la de un programa equivalente escrito en un lenguaje imperativo. Sin embargo, para cierto tipo de problemas, la formulación del programa mismo puede ser mucho más sencilla y natural. Una de las limitaciones claves de la mayoría de los sistemas de programación lógica, es que sus métodos deductivos son inadecuados. La resolución es completa, desde el punto de vista que ella puede probar cualquier conclusión lógicamente implicada por su base de conocimiento. Sin embargo, un buen sistema debería ser capaz de arribar a conclusiones a partir de datos inciertos, razonar analógicamente y generalizar su conocimiento apropiadamente si se quiere ser realmente efectivo. En un inicio se construyeron muchos sistemas inteligentes que utilizaban como base el cálculo de predicado de primer orden, dado su fuerte y general poder expresivo y su semántica bien definida. Sin embargo, debido a que las construcciones del lenguaje son muy refinadas y no brindan facilidades para describir estructuras más complejas, los expertos del dominio presentaban dificultades en el uso del cálculo de predicados y la comprensión del conocimiento expresado en éste. Además, la generalidad del cálculo de predicados ha puesto un límite significativo para el desarrollo de facilidades de deducción efectiva usando el conocimiento expresado en él. Estas dificultades motivaron el desarrollo de redes semánticas y lenguajes de representación orientados a objetos basados en marcos. (Lezcano, Lobato et al. 2000) 7 1.3.3 Paradigma de la Programación Orientada a Objeto. A mediados de los años 60 se empezó a vislumbrar el uso de las computadoras en la simulación de problemas del mundo real. Pero el mundo real está lleno de objetos, en la mayoría de los casos complejos, los cuales difícilmente son representados por los tipos de datos primitivos de los lenguajes imperativos. Así es que a dos noruegos, Dahl y Nygaard, se les ocurrió el concepto de objeto y sus colecciones, llamadas clases de objetos, que permitieron introducir abstracciones de datos a los lenguajes de programación. La posibilidad de reutilización del código y sus indispensables modificaciones, se reflejaron en la idea de las jerarquías de herencia de clases. Ellos introducen el concepto de polimorfismo. Todos estos conceptos fueron presentados en el lenguaje Simula 67. Aunque diseñado como lenguaje de propósito general, Simula tuvo su mayor éxito en las aplicaciones de simulación discreta, gracias a la clase SIMULATION que facilitaba considerablemente la programación. (Dahl, Myhrhaug et al. 1970) La Programación Orientada a Objetos (POO), que por todo lo anterior varios han dado en llamar la Programación Estructurada de los 90's, encuentra en este contexto un terreno fértil. Lo relevante de la Programación Orientada a Objetos está dado porque en lugar de tratar de modelar un problema en algo familiar a la computadora se trata ahora de acercar la computadora al problema. Es decir, modelar la realidad del problema a través de entidades independientes pero que interactúan entre sí y cuyas fronteras no estén determinadas por su instrumentación computacional sino por la naturaleza del problema. Estas entidades serán denominadas objetos por analogía con el concepto de objeto en el mundo real. (Heileman 2003) Programar en un lenguaje de programación orientado a objetos es definir clases (nuevos tipos de datos) que expresan una determinada funcionalidad la cual es común a todos los individuos de una clase. A través de esta funcionalidad los objetos o instancias concretas de una clase dan respuesta a las solicitudes (mensajes) que les envían otros objetos. Las clases deben ser lo suficientemente cerradas como para que cada objeto pueda ocultar la información (datos) que lo caracteriza como individuo. Es un problema interno del objeto cómo llevar a cabo la funcionalidad descrita en la clase. Esto es, tal vez, lo más elegante de la POO, la sencillez de sus conceptos. 8 Visto en la óptica de las arquitecturas convencionales de computadoras, en la POO los datos no circulan abiertamente por todo el sistema como en la programación tradicional. Los programas no se dividen en declaraciones pasivas de estructuras de datos y funciones (que tal vez actúen sobre algunas de las estructuras de datos). Los datos están ahora encerrados dentro de cada objeto y éste es quien decide internamente cómo trabajar con ellos para dar respuesta a una solicitud de otro objeto. Por otra parte estas clases deben ser lo suficientemente abiertas para permitir la reutilización, adaptación y extensión de las mismas a nuevas funcionalidades, sin correr el riesgo de afectar el funcionamiento de lo que ya está correcto. Esta aparente contradicción, de lo que se conoce como principio abierto-cerrado, es la piedra angular de la POO. En ausencia de una definición formal de qué es la POO, algunos prefieren identificarla por sus objetivos. (Sedgewick 1992; Horstmann 1995; Heileman 2003) Tres objetivos fundamentales persigue la POO para facilitar la experimentación: o La robustez de las partes, que garantiza su integridad y funcionamiento propio (lo cual a su vez facilita disminuir las fallas). Esto es posible a través de recursos como el encapsulamiento y el manejo de excepciones. o La reusabilidad y la extensibilidad. Que se puedan derivar, más que definir, nuevas clases de objetos a partir de las ya existentes, facilitándole con ello al programador el desarrollo de prototipos y una rápida exploración en las nuevas ideas. Esto se facilita en los Lenguajes Orientados a Objetos mediante la redefinición de operadores y funciones, la genericidad, la herencia y el polimorfismo. Esta búsqueda de aprovechar lo existente es una de las características básicas de la POO. Algunos de estos recursos como el polimorfismo y la jerarquía de clases a través de la herencia dotan de recursos para clasificar lógicamente a los objetos, evitando las redundancias y obviando restricciones que otros paradigmas de programación imponen. Otros conceptos como la genericidad, la manipulación de excepciones no son inherentes al modelo de objeto pero encuentran en este paradigma una mejor forma de expresión. La concepción de Programación Orientada a Objeto ha originado nuevos lenguajes para expresarla, los Lenguajes Orientados a Objeto (LOO). Algunos de los más importantes son 9 SMALLTALK, Eiffel, Actor, Modular. (Reenskaug, Wold et al. 1996; Group 2003; Meyer 2005) Sin embargo la dificultad para algunos de hacer el tránsito de las viejas a las nuevas técnicas y la gran carga instalada (mental y electrónicamente) de software viejo, ha provocado el surgimiento de extensiones de lenguajes tradicionales (de los mejores entre los tradicionales como LISP, Pascal, C) que pretenden establecer un compromiso con sus viejos programadores y las nuevas ideas. (Koschmann 2001; Zarko Gajic 2006) En un TAD se especifican las propiedades funcionales de una estructura de datos y sus operaciones, y éstas se implementan en términos de las construcciones existentes en el lenguaje. Este concepto tuvo su primera materialización en el concepto de clase del lenguaje SIMULA 67. (Dahl, Myhrhaug et al. 1970; Hennessy 1993; Jonnan 2000) Junto con las clases aparecen en este lenguaje el concepto de herencia, mediante la cual las subclases heredan las propiedades declaradas en la interfaz de las superclases y pueden definir operaciones y datos adicionales que especializan el comportamiento de la subclase. SIMULA tuvo un gran impacto en muchos de los lenguajes de programación modernos. MODULA-2 ofrece un excelente mecanismo de abstracción de datos, el cual incluye un cierto grado de protección ya que no permite acceder directamente al estado interno del TAD. Pero presenta algunas limitaciones como que los nombres de los procedimientos usados en un módulo tienen que ser únicos y que los TAD pueden operar un solo tipo de dato. MODULA-2 es uno de los primeros lenguajes de programación ampliamente difundidos en usar la modularidad como un principio fundamental de estructuración. La última versión conocida como Modula-3 fue diseñada por Luca Cardelli. (Cardelli, Donahue et al. 1989) ADA resuelve parcialmente ambos problemas mediante la sobrecarga de operadores (operator overloading) y las unidades de programas genéricas (generic program unit). La primera se refiere a permitir a un programador usar múltiples operadores con el mismo nemotécnico. La distinción entre los operadores puede ser determinada en tiempo de compilación examinando los tipos y el número de parámetros. El segundo término se refiere a la posibilidad de definir un módulo para ser usado con tipos de datos diferentes, esta 10 unidad genérica es un procedimiento modelo (patrón) que puede ser parametrizado con tipos reales durante la compilación de programas. En general, la abstracción de datos en ADA se realiza usando tres herramientas principales. El package es usado para encapsular un conjunto de definiciones relacionadas. El type determina el dominio de una variable (o estructura de datos) y como ésta puede ser manipulada. La definición de generic permite generar varias abstracciones similares desde un patrón. (ANTARESX 2004) El estado alcanzado hasta aquí en el proceso evolutivo de los tipos de datos en los lenguajes de programación, el cual se pretende sintetizar, presenta algunas limitaciones. En SIMULA falta el mecanismo de información oculta. En ADA los packages son objetos de segunda clase. La sobrecarga de operadores en ADA se resuelve en tiempo de compilación. En ADA no aparece el concepto de clase. Los desarrollos posteriores llevan al concepto actual de Programación Orientada a Objetos (POO). Sobre el cual hay diversidad de opiniones y está lejos de estar formalizado, pero realmente ha despertado un entusiasmo considerable a partir de la década del 80 y se ha convertido en una palabra de uso frecuente. En este tipo de programación, los programas están basados en objetos (entidades que combinan las propiedades de los datos y de los procedimientos que actúan sobre ellos), los cuales son instancias de un tipo o clase de objeto (descripción intencional del dato). Por eso, un objeto puede verse y usarse en una forma completamente análoga a un TAD en los lenguajes de programación tradicionales. Realmente tanto los TAD como la POO emergieron del lenguaje SIMULA. (Zalamanca 2004) Si los TAD son similares a los objetos, se puede considerar a la POO simplemente como un modelo de programación en el cual todos los datos son abstractos y toda la manipulación de la información se implementa a través de las operaciones con los TAD, pero esto no es posible, ante todo porque los objetos tienen un tipo (dado en la mayoría de los casos por su clase) lo cual permite que sean valores de primera clase (pueden ser manipulados como una estructura de datos dentro del lenguaje) y ser usados directamente en expresiones. Además a la POO la caracterizan otros conceptos como herencia, polimorfismo y enlace dinámico o tardío (late binding). (Zalamanca 2004) En resumen, los diferentes paradigmas de programación, los lenguajes, métodos y herramientas asociados a ellas son un reto para el Proceso Docente Educativo de las 11 disciplinas de programación de las carreras de perfil informático, esto ha influido en la forma en que se plantean los planes de estudio de estas carreras. 1.4 Evolución del currículo de las carreras de ciencia de la computación. Los esfuerzos para diseñar el modelo curricular de los programas de Ciencia de la Computación e Ingeniero en Computación comenzaron en 1960, poco tiempo después se estableció el primer departamento que involucraba estas áreas. En 1968 la Association for Computing Machinery (ACM) publica el Curriculum´68, el cual ofrece detalladas recomendaciones sobre los programas académicos de Ciencias de la Computación. (ACM/IEEE 2001) En la próxima década, las carreras de computación se desarrollan rápidamente, en la década del 70, la ACM y la Sociedad de Computación del Instituto de Eléctrica e Ingeniería Electrónica (IEEE-CS) se unen para revisar el currículo de estas carreras. En 1977 el Comité de Educación de la IEEE-CS publicó un reporte para los programas de Ciencia de la Computación e Ingeniería de Software. (ACM/IEEE 2001) Al final de la década de los 80, la Sociedad de Computación y la ACM desarrollan la revisión de un currículo más ambicioso, el cual fue publicado en 1991, como Currículum de Computación ´91 (CC1991), la cual divide el cuerpo del conocimiento asociado con la ciencia de la computación en unidades de conocimiento individuales, lo que conocemos como disciplinas, dándole flexibilidad a las instituciones de enseñanza para estructurar estas unidades de conocimiento en cursos, en dependencia de sus necesidades particulares. El CC1991 incluye 11 ejemplos de implementación que muestran cómo las unidades de conocimiento pueden combinarse para formar cursos y programas que satisfagan una gran variedad de necesidades. (ACM/IEEE 2001) En 1993, la ACM produjo cinco reportes para dos años de los programas de las carreras de computación, uno para Ciencia de la Computación, Ingeniero en Computación, Sistemas de Información, servicios que apoyan la computación y la computación para otras carreras. (ACM/IEEE 2001) 12 Al entrar en el Nuevo Milenio, la ciencia de la computación es un campo enormemente dinámico, la rápida evolución de la computación tiene un profundo efecto en la educación de las ciencias de la computación, afectando, tanto el sistema de contenidos como la pedagogía de la ciencia en sí. Se han incluido otras unidades del conocimiento relacionadas con las redes, al mismo tiempo, la existencia de la web ha cambiado la naturaleza de los procesos de educación en sí mismos. La moderna tecnología de redes provee ambientes idóneos para la comunicación y un acceso sin precedentes a la información. En la mayoría de los programas académicos actualmente, no solo en las carreras de computación, sino en otros campos también, la tecnología de redes de computadoras se ha convertido en un instrumento pedagógico esencial. Estos cambios se dividen en dos categorías, técnica y cultural, cada una de ellas tiene un efecto significativo sobre el proceso de enseñanza-aprendizaje de las carreras de computación. En el año 2001, la ACM y el IEEE, publican el reporte CC2001, donde proponen el currículo de las principales carreras de computación, incluyendo, Ingeniería en Computación, Ciencias de la Computación, Sistema de Información e Ingeniería de software. Los cambios en la rama de la computación son tan rápidos que no permiten diseñar currículos para una década, como hasta este momento se diseñaban. (ACM/IEEE 2001) Los avances técnicos que han influido en la inclusión de nuevos tópicos en el currículo de estas carreras son: La World Wide Web y sus aplicaciones. Tecnología de redes, particularmente aquellas basadas sobre TCP/IP Gráficos y multimedia Bases de Datos Relacionales Interoperabilidad Programación Orientada a Objeto El uso de sofisticadas Interfaces de Programación de Aplicaciones (APIs) (Application Programmer Interfaces) Interacción Hombre-Computadora Seguridad y Criptografía Dominios de Aplicación 1.4.1 La carrera de Ingeniero en software En 1998 la ACM y el IEEE-CS crean el Proyecto de Educación del Ingeniero en Software Software Engineering Education Project (SWEEP) – para rediseñar el currículo del 13 Ingeniero en Software, el cual queda plasmado en el reporte SE2004, participan muchos países e instituciones interesadas en la calidad del graduado de este perfil, este reporte centró su atención en los conocimientos y la pedagogía para impartirlos asociada al perfil del ingeniero en software y de este trabajo se derivó la incorporación de nuevas disciplinas. (ACM/IEEE 2005) Los graduados de esta carrera influyen en muchas áreas de la computación por su base teórico conceptual, pero también se requiere que los estudiantes utilicen conceptos de otros campos, como las matemáticas, las ingenierías, la administración de proyectos y de otros muchos dominios de aplicación. Los estudiantes deben aprender a integrar teoría y práctica, reconocer la importancia de la abstracción y el modelado para adquirir un dominio eficiente del conocimiento que se requiere para apoyar el desarrollo de software en múltiples campos y para apreciar el valor de un buen diseño. Este por ende no encaja aquí, no tiene que ver con lo que se viene diciendo Por ende, la Informática Educativa no es una disciplina puramente técnica; sicólogos, educadores y sociólogos discuten con relación a su valor pedagógico real. Hoy en día los avances en la sicología, combinados con la explosión tecnológica, han dado lugar a una serie de sistemas educativos que permiten resolver algunas limitaciones de la educación tradicional (Cabrera 2000; Lynch 2003; Señas and Moroni 2003). Este capítulo debería ser mas extenso, al menos 5 hojas mas. El último acápite de cada capítulo debe ser un resumen del capítulo que le de pie al siguiente 14