PROGRAMACIÓN ORIENTADA A OBJETOS EDUCATIVA

Anuncio
PROGRAMACIÓN ORIENTADA A OBJETOS EDUCATIVA EN UNA MÁQUINA
VIRTUAL BASADA EN PROTOTIPOS
J. Baltasar García Perez-Schofield1, Emilio García Roselló1, David Martínez Torres2,
Manuel Perez Cota1
1
Departamento de Informática, Edif. Fundición, s/n, Campus As Lagoas-Marcosende, 36201 Vigo, España.
{jbgarcia | mpcota | erosello}@uvigo.es
2
Mixteca. Huajuapan de León. 69000 Oaxaca - México.
[email protected]
La programación orientada a objetos es una las especialidades más importantes a estudiar dentro del campo de las
ciencias computacionales. El paradigma de orientación a objetos está ya absolutamente asentado en nuestros planes
de estudio, de manera que hoy en día se enseña antes incluso que el paradigma estructurado. De una manera
generalizada, el lenguaje que se está adoptando para la enseñanza es Java. Si bien este lenguaje es perfectamente
válido, existen otros lenguajes, que siguen otros modelos de orientación a objetos que podrían también ser aplicables
e incluso presentar algunas ventajas. En este artículo, se presenta precisamente una máquina virtual diseñada con el
objetivo de servir especialmente para la enseñanza, que presenta una naturaleza distinta a la de aquellos lenguajes
basados en clases (C++, Java), y con sus propias ventajas para la enseñanza.
1.
Introducción
A lo largo de los últimos años, ha habido varios intentos de crear plataformas de aprendizaje
para la correcta asimilación de los conceptos de programación. Uno de los más llamativos y
con más éxito, es probablemente, BlueJ (Kölling et al., 2003). Si bien BlueJ hace más énfasis
en un entorno de programación que en un lenguaje de programación, este proyecto supuso en
el pasado el desarrollo, efectivamente, de un lenguaje que aportara buena parte de las
características que presenta Java (si bien Java es descartado en un principio, aunque
favorablemente evaluado en (Kölling, 1999a)). Este lenguaje era Blue (Kölling, 1999b). El
proyecto Blue supuso en su momento un estudio de varias características que un lenguaje de
programación debería tener para ser considerado adecuado para educación (Kölling, 1999a).
Es obvio que este estudio está motivado respecto al aprendizaje temprano (primeros cursos)
del paradigma de programación orientada a objetos. Si bien los autores encuentran muy
razonables algunas de las características pedidas por Kölling y su equipo para un lenguaje
orientado a objetos educativo (por ejemplo "pequeño y simple", "alto nivel", "sintaxis
legible", "no redundancia de conceptos", "pureza" ...), con uno especialmente los autores de
este trabajo muestran su desacuerdo: "seguridad respecto al tipo". Con este último, los autores
del proyecto BLUE tratan de proporcionar mayores ventajas al programador novato. Si bien la
corrección estática y el fuerte tipado (aplicables a los lenguajes que pueden considerarse
estáticos, como C++ (Stroustrup, 1991) y Java (Naughton, 1996)) pueden ser características
deseables, y tener importantes ventajas, la dinamicidad (cuando las comprobaciones se hacen
VII Congresso Iberoamericano de Informática Educativa
1347
tiempo de ejecución, como en Self, por ejemplo) puede tener también interesantes
características.
Los lenguajes dinámicos comienzan su andadura con Smalltalk (Goldberg & Robson,
1989). Pero todavía más relacionado con el sistema presentado aquí es Self (Smith & Ungar,
1987). Presentaba un modelo de orientación a objetos realmente nuevo en aquel momento: el
denominado basado en prototipos. Su característica más destacada era la ausencia de clases.
En realidad, este modelo estaba diseñado como un superconjunto del modelo de orientación a
objetos basado en clases, mediante la definición de objetos prototípicos, que actuarían como
modelos para la creación de nuevos objetos, mediante su clonación.
Desgraciadamente, los lenguajes que implementan este modelo no son fácilmente
accesibles. Algunos de ellos son dependientes de plataforma (como el mismo Self, de Sun);
Smalltalk y también Self presentan una sintaxis que no es sencilla para muchos
programadores (novatos y con experiencia, Kölling, 1999a); de hecho, el aprendizaje de este
estilo de sintaxis es un tema merecedor de artículos dedicados. como (LaLonde, 2000). Otros
lenguajes, como Kevo (que supone una curiosa mezcla entre un lenguaje basado en prototipos
(dinámico por naturaleza), y un lenguaje estático, Tailvaisaari, 1992), han sido abandonados.
Además de la simplicidad y la dinamicidad, los autores han identificado un tercer
punto importante, como es el soporte de persistencia. El interés en esta característica, todavía
no soportado totalmente en la máquina, se justifica en que suaviza muchísimo la curva de
aprendizaje del paradigma de pogramación orientada a objetos, al no precisar que el
programador distinga entre memoria secundaria y primaria (Kölling, 1999a), consistiendo en
una capacidad natural de los objetos (como se perfila en García Perez-Schofield & Pérez
Cota, 1998).
De hecho, en este artículo se presenta una máquina virtual pequeña y simple (lo cual
redunda en beneficios para la educación (Smith & Ungar, 1987)), sin soporte para tipos,
orientada a objetos pura y basada en prototipos, llamada Zero1. Si bien los autores no pueden
todavía presentar un lenguaje de programación de alto nivel sobre esta máquina, hay ya
disponible un macroensamblador, correcto, gracias al alto nivel de abstracción inherente de la
máquina, para programación de proyectos de tamaño medio.
2.
Programación de la máquina virtual
2.1.
Arquitectura de la máquina virtual
Las características básicas de esta máquina virtual son las siguientes:
1Disponible en http://trevinca.ei.uvigo.es/~jgarcia/TO/zero/, con sus manuales correspondientes.
VII Congresso Iberoamericano de Informática Educativa
1348
•
herencia simple, dinámica (implementada mediante delegación)
•
creación y clonación de objetos (y prototipos, indistinguibles de los primeros)
•
paso de mensajes
•
manejo de excepciones
•
persistencia (no implementada todavía).
La máquina virtual está basada en registros (que guardan referencias a objetos),
estructurándose en dos grandes grupos: el acumulador (__acc), que guarda la referencia
resultado de la instrucción anterior, el registro que guarda el objeto que está ejecutando el
método, conocido como self en Java (__this), y el registro que guarda la excepción que se
haya producido (__exc); y en un segundo grupo los registros generales que pueden ser
utilizado para cualquier propósito (__gpn).
2.2.
Compilación de objetos y paso de mensajes
Los objetos se crean empleando object y endObject para marcar el comienzo y el fín del
objeto, pudiendo crear en su interior atributos (attribute) y métodos (definidos entre
method y endMethod). Los mensajes a métodos se realizan, básicamente, utilizando el mismo
formato que Java, <nombreObjeto>.<nombreMétodo>. Es posible (de hecho, muy habitual)
que entre el nombre del objeto y el nombre del método se sitúen varios nombres de atributos,
que devuelven una referencia a un nuevo objeto, como en System.console.write(), donde
console es un atributo de System.
Un listado del típico programa (objeto) HolaMundo, que muestra por consola la cadena
"¡Hola, Mundo!", se muestra a continuación. El objeto HolaMundo envía un mensaje
(write()) al objeto de consola (_Zero_Console, accesible desde System) para enviar una
cadena a la consola del sistema.
object HolaMundo : ConsoleApplication
method + doIt()
parent.prepare() ! Preparar la e/s
System.console.write("¡Hola, Mundo!")
System.console.lf()
return
endMethod
endObject
El programa macroensamblador (zm, al que se le pasaría un listado como el anterior),
traduce código fuente en macro enamblador para la máquina virtual Zero en su propio
bytecode. La máquina virtual (zvm) ejecuta objetos que pueden, como en este caso, residir en
un archivo con extensión ".zbj".
VII Congresso Iberoamericano de Informática Educativa
1349
2.3.
Encapsulación y creación de objetos
No existe una división especial entre objetos y prototipos. Normalmente, si bien no tiene por
qué ser así, los prototipos son objetos definidos en tiempo de compilación, mientras que los
objetos son aquellos que se crean mediante la clonación de los primeros, en tiempo de
ejecución. Sin embargo, existen otras posibilidades en tiempo de compilación, como clonar
un objeto, eliminar o añadir atributos y métodos y emplearlo como prototipo, o incluso, existe
la alternativa de crear un objeto vacío (sin métodos ni atributos), heredando de uno dado,
pasandole el mensaje createChild(), y añadiendo los métodos y atributos necesarios.
Los métodos y atributos, que se marcan con las palabras clave method y attribute,
respectivamente, llevan un signo '+', si son públicos, o un signo '-' si son privados. En el caso
concreto de los atributos, ni siquiera en el caso de ser públicos, estos pueden ser modificados
desde un objeto que no sea el mismo que los posee.
El clonado se realiza pasando el mensaje copy() a un objeto. Este mensaje conlleva
un argumento que es el nombre del nuevo objeto, si bien puede pasarse una cadena vacío,
delegando en el sistema la creación de un nombre para él.
En un método pueden existir referencias locales a ese método (frente a las referencias
que son locales a un objeto, los atributos), que se crean mediante la palabra clave reference.
Las apariciones de enteros, flotantes y cadenas en el código fuente son convertidas, mediante
el compilador, a objetos, clonados de LiteralInt, LiteralFloat y LiteralString,
respectivamente.
La creación del prototipo Punto, su clonado, y la manera de indicar la encapsulación
se muestran a continuación:
object Punto
! Nótese que el prototipo Punto ya es un objeto, por lo
! que es necesario dar valores a sus atributos.
attribute + x = 0
attribute + y = 0
method + ponCoordenadas(a, b)
x = a
y = b
return
endMethod
method + toString()
reference toret = "("
toret = toret.concat(x.toString())
toret = toret.concat(", ")
VII Congresso Iberoamericano de Informática Educativa
1350
toret = toret.concat(y.toString())
toret = toret.concat(")")
return toret
endMethod
endObject
object PruebaPunto : ConsoleAplication
method + doIt()
! Crea un objeto
reference miPunto = Punto.copy("")
miPunto.ponCoordenadas(100, 150)
! Muéstralo por pantalla
__this.prepare() ! Preparar la e/s
System.console.write(miPunto)
System.console.lf()
return
endMethod
endObject
La compilación y ejecución de PruebaPunto mostraría por pantalla:
(100, 150)
2.4.
Herencia
La herencia soportada, es, como se ha visto, del tipo simple. Concretamente, existe un atributo
especial (todos los objetos lo poseen, denominándose parent) que es aquel que denota al
objeto padre de un objeto dado. Así, en el ejemplo anterior, PruebaPunto hereda de
ConsoleApplication, lo que le provee automáticamente de la inicialización y el acceso a la
consola, por ejemplo.
Todos los objetos derivan del objeto Object, la raíz de la jerarquía de herencia. Este
objeto provee de las operaciones básicas al resto de objetos, como son, por ejemplo, copy(),
createChild(), isTheSameAs(), getName(), ... y otros.
2.5.
Polimorfismo
La propia naturaleza del lenguaje hace que cualquier paso de mensajes sea
necesariamente polimórfico. Concretamente, la herencia se implementa mediante delegación
(Smith & Ungar, 1987), y, así, cuando un objeto es incapaz de satisfacer un mensaje, lo
reenvía a (delega en) su padre. Mientras un programador de Java lo encontraría natural (si
bien en Java la herencia no se implementa mediante delegación), el programador de C++
encontrará que no es necesario indicar virtual delante de cada método que podría ser
VII Congresso Iberoamericano de Informática Educativa
1351
necesario que soportara una llamada polimórfica.
2.6.
Herencia dinámica
La herencia dinámica es una ventaja que viene dada gratis por la propia simplicidad y
naturaleza dinámica del sistema. Como ya se ha explicado, la herencia viene marcada por un
atributo parent. Este atributo, como cualquier otro, puede ser cambiado por el propio objeto.
La modificación controlada de este atributo proporciona la característica conocida como
"herencia dinámica".
En el siguiente ejemplo, un objeto contenedor (concretamente, un vector asociativo)
cambia su padre según se cumpla una condición. El primero de ellos es el prototipo
EmptyMap, empleado cuando no contiene elementos. Existe, así, el prototipo NonEmptyMap
(no mostrado), que es el padre cuando se introducen elementos en el mismo. Este cambio de
padre permite simplificar enormemente los métodos lookUp(), add() y delete() del objeto
(respectivamente, buscar, añadir y borrar), puesto que no es necesario comprobar si existen
elementos o no.
object EmptyMap : Map
method + lookUp(name)
throw EObjectNotFound
return
endMethod
method + delete(name)
throw EObjectNotFound
return
endMethod
method + add(name, obj)
! Lanzar un mensaje al padre, como "super" en Java
__this.^add(name, obj)
parent = NonEmptyMap
return
endMethod
endObject
Esta técnica no está exenta de problemas. La modificación, sin control, del atributo
parent, puede llevar a un programa caótico. En el diseño del lenguaje de alto nivel, se
contempla la creación de un mecanismo que permita controlar estas modificaciones.
3.
Trabajo relacionado
La particularidad que más desmarca a este sistema de programación de los demás es su futuro
soporte de persistencia. Un sistema que presenta esta característica de una forma similar a la
VII Congresso Iberoamericano de Informática Educativa
1352
deseada es PJama (Persistent Java) (Atkinson & Jordan, 2000). Sin embargo, este sistema
implementa persistencia ortogonal (Atkinson & Morrison, 1995), mientras que, como se
explica a continuación, la diseñada para Zero es sólo un subconjunto de esta última. De
hecho, será implementada siguiendo el modelo de persistencia basado en contenedores
(García Perez-Schofield et al., 2001), tal y como se empleó en Barbados (García PerezSchofield, 2002a). Este modelo es vagamente parecido al que presenta el middleware PerDis
(Shapiro et al., 1997). Se trata, básicamente, de un particionamiento del almacenamiento
persistente visible por el usuario, de manera que puede elegir en qué cluster desea guardar sus
objetos. Por supuesto, ésto se recubre con una pequeña capa de abstracción, como un sistema
de directorios en el caso de Barbados (García Perez-Schofield, 2002b).
El resto de sistemas símplemente no poseen esta capacidad (como BlueJ, que empla
Java), o su soporte de persistencia es muy primitivo, como en Self, que directamente guarda
una imagen (el fichero es denominado image) de la memoria que permite que los objetos
persistan en el entorno de trabajo (workspace) actual entre una ejecución y otra. Será
necesario cambiar el fichero de imagen desde fuera de Self para disponer de varios
workspaces o realizar todas las aplicaciones en un solo worksapce.
Self (Smith & Ungar, 1987), es el sistema, en cuanto a dinamicidad, en el que se
inspira Zero. Sin embargo, tanto el macro ensamblador como el lenguaje que se implemente
en un futuro cercano no seguirán la sintaxis empleada por Self. Sí es posible que a más largo
plazo se realice un compilador de Self como prueba del sistema.
En términos de sistema orientado al aprendizaje, los sistemas más parecidos son el
lenguaje de programación Blue, con su entorno, de mismo nombre (Kölling, 1999b), y BlueJ,
sistema posterior, basado en Java pero de muy similares características (Kölling, 2003). La
mayor diferencia entre Zero y este sistema, reside en la natural dinamicidad de Zero (basado
en prototipos) en contra de la rigidez estática de Java y Blue (ambos basados en clases), como
ya se ha comentado. Cada una tiene sus ventajas e inconvenientes, pero los autores
defendemos que la dinamicidad puede presentar características muy positivas. Por otra parte,
el sistema presentado aquí no posee ningún entorno integrado de programación que refuerce
los aspectos educativos, al contrario que Blue y BlueJ. Su entorno es considerado por los
autores de este artículo como ideal para el aprendizaje, y en el futuro se considerará la
implementación de uno similar.
Oviedo3 (Ortín Soler et al., 2000), es una máquina virtual parecida también a Zero,
puesto que, a su vez, está inspirada parcialmente en Self. Sin embargo, Oviedo3 está basada
en clases, como Smalltalk, lo cuál no cumple con los objetivos planteados por nosotros los
autores.
VII Congresso Iberoamericano de Informática Educativa
1353
4.
Conclusiones
Zero es una máquina virtual orientada a objetos pura, multiplataforma, basada en prototipos,
y, por tanto, especialmente diseñada para soportar lenguajes dinámicos.
El sistema presenta una manera de programar clara, con una sintaxis (incluso
empleando un macro esamblador) simple, y soportando de manera sencilla los conceptos de
programación orientada a objetos. Su modelo de orientación a objetos es también simple y
muy sencillo de entender y aprender, ya que el número de elementos a tratar es muy
pequeño2. No soporta tipos de forma natural (si bien sería posible crear un lenguaje de
programación que sea un subconjunto de Java o C++ que sí lo haga, puesto que se engloba el
modelo basado en clases), pero esto los autores lo defienden como una ventaja, y no como un
inconveniente.
Pese a estar en un momento de desarrollo bastante inicial, el sistema ya ha sido
empleado con éxito en un curso de doctorado, y en una asignatura de la carrera de Ingeniería
en Informática. Gracias al empleo de encuestas, se ha obtenido bastante información que
esperamos poder procesar y publicar en breve. Sí está claro, al menos, por parte de los
usuarios del sistema, que ven como punto de desarrollo futuro más importante la
implementación de un lenguaje de alto nivel, lo cuál será la más alta prioridad de los autores.
5.
Trabajo futuro
El soporte de persistencia es uno de los puntos más importantes del proyecto, ya
implementada parcialmente. De hecho, sólo es necesario proveer a Zero de un
almacenamiento persistente (persistent store, Balch et al., 1989). Otros proyectos incluídos en
el futuro inmediato de Zero son la creación de un lenguaje de alto nivel y de un entorno
integrado, como ya se ha comentado.
6.
Bibliografía
Atkinson M.P., Morrison R. (1995). "Orthogonality Persistent Object System", VLDB
Journal 4(3), 319-401, ISSN: 1066-8888
Atkinson, M., Jordan, M. (2000). A Review of the Rationale and Architectures of Pjama: A
Durable, Flexible, Evolvable, and Scalable Orthogonaly Persistent Programming Platform.
Sun Microsystems Technical Report SMLI TR-2000-90
Balch, P., Cockshott, W.P., Foulk, P.W. (1989). Layered Implementations of persistent
object stores. Software Engineering Journal, 4(2), 123-131.
2De ahí su nombre, Zero, como cero, lo más pequeño y mínimo.
VII Congresso Iberoamericano de Informática Educativa
1354
Black A. (2003). Post Javaism. Proceedings of the First Workshop on Object-Oriented
Language Engineering for the Post-Java Era: Back to Dynamicity. European Conference on
Object-Oriented Programming.
García Perez-Schofield, B., Pérez Cota, M. (1998). Problemática del uso de ficheros en
C++: un enfoque educativo. Revista de Enseñanza y Tecnología. 1(12), 10-20.
García Perez-Schofield B., Cooper, T.B., Pérez Cota, M., García Roselló E. (2001).
Extending Containers to Address the Main Problems of Persistent Object Oriented Operating
Systems: Clustering, Memory Protection and Schema Evolution. Proceedings of the Fourth
Workshop on Object-Orientation and Operating Systems. European Conference on ObjectOriented Programming.
García Perez-Schofield, J., Cooper, T., Roselló, E., Pérez Cota, M. (2002a). Persistencia,
evolución del esquema y rendimiento en los sistemas basados en contenedores. Tesis
Doctoral. Departamento de Informática. Universidad de Vigo.
García Perez-Schofield B., Cooper, T.B., Pérez Cota, M., García Roselló E. (2002b). First
Impressions about Executing Real Applications in Barbados. Proceedings of the Fifth
Workshop on Object-Orientation and Operating Systems. European Conference on ObjectOriented Programming
Goldberg A., Robson D. (1989). Smalltalk-80: The Language. Addison Wesley. ISBN 0201-13688-0
Kölling, M., Quig, B., Patterson, A., Rosenberg, J. (2003). The BlueJ System and its
Pedagogy. Journal of Computer Science Education, v13(4).
Kölling, M. (1999a). The problem of teaching Object-Oriented Programming. Journal of
Object Oriented Programming, v11(8).
Kölling, M. (1999b). The Blue Language. Journal of Object Oriented Programming,
v11(10).
LaLonde, W. (2000). I can read C++ and Java, but I can't read Smalltalk. Journal of ObjectOriented Programming. February, 2000.
Martínez A., Álvarez García F., Ortín Soler F., Cueva Lovelle J. (2000). An OODBMS
developed over the Oviedo3 Operating System. Proceedings of the Simposio Español de
Informática Distribuida (SEID'2000).
Naughton P. (1996). The Java Handbook. McGraw-Hill
Ungar, D., Smith, R. S. (1987). "Self: The Power of Simplicity". In Proceedings of
VII Congresso Iberoamericano de Informática Educativa
1355
OOPSLA'87, Orlando, FL, pp. 277-241.
Shapiro, M., Kloosterman, S., Riccardi, F. (1997). "PerDis. A Persistent Distributed Store
for Persistent Applications", Proceedings of the 3rd Capernet Plenary Workshop.
Stroustrup B. (1991). The C++ Programming Language. Addison-Wesley
Taivalsaari A. (1992). Kevo: A prototype-based object-oriented language based on
concatenation and module operartions. Technical Report DCS--197--1R, University of
Victoria, Victoria, British Columbia, Canada.
VII Congresso Iberoamericano de Informática Educativa
1356
Descargar