stringtranslate.com

Sistema de objetos Lisp común

Combinación de métodos estándar en ANSI common lisp

El Common Lisp Object System (CLOS) es la función para la programación orientada a objetos en ANSI Common Lisp . CLOS es un potente sistema de objetos dinámicos que difiere radicalmente de las funciones de programación orientada a objetos que se encuentran en lenguajes más estáticos como C++ o Java . CLOS se inspiró en sistemas de objetos Lisp anteriores, como MIT Flavors y CommonLoops , aunque es más general que cualquiera de los dos. Propuesto originalmente como un complemento, CLOS se adoptó como parte del estándar ANSI para Common Lisp y se ha adaptado a otros dialectos Lisp como EuLisp o Emacs Lisp . [1]

Características

Los componentes básicos de CLOS son métodos , clases , instancias de esas clases y funciones genéricas . CLOS proporciona macros para definir: defclass, defmethody defgeneric. Las instancias se crean con el método make-instance.

Las clases pueden tener múltiples superclases , una lista de espacios (variables miembro en el lenguaje C++/Java) y una metaclase especial . Los espacios se pueden asignar por clase (todas las instancias de una clase comparten el espacio) o por instancia. Cada ranura tiene un nombre y se puede acceder al valor de una ranura mediante ese nombre utilizando la función slot-value. Además, se pueden definir funciones genéricas especiales para escribir o leer valores de ranuras. Cada espacio en una clase CLOS debe tener un nombre único.

CLOS es un sistema de despacho múltiple . Esto significa que los métodos pueden especializarse en cualquiera o todos los argumentos requeridos. La mayoría de los lenguajes OO son de envío único, lo que significa que los métodos solo están especializados en el primer argumento. Otra característica inusual es que los métodos no "pertenecen" a clases; Las clases no proporcionan un espacio de nombres para funciones o métodos genéricos. Los métodos se definen por separado de las clases y no tienen acceso especial (por ejemplo, "esto", "auto" o "protegido") a los espacios de clase.

Los métodos en CLOS se agrupan en funciones genéricas . Una función genérica es un objeto que se puede llamar como una función y que asocia una colección de métodos con un nombre compartido y una estructura de argumentos, cada uno de ellos especializado en diferentes argumentos. Dado que Common Lisp proporciona clases que no son CLOS para estructuras y tipos de datos integrados (números, cadenas, caracteres, símbolos, ...), el despacho CLOS también funciona con estas clases que no son CLOS. CLOS también admite el envío de objetos individuales (especialistas de eql). CLOS no admite de forma predeterminada el envío de todos los tipos de datos de Common Lisp (por ejemplo, el envío no funciona para tipos de matrices totalmente especializados o para tipos introducidos por deftype). Sin embargo, la mayoría de las implementaciones de Common Lisp proporcionan un protocolo de metaobjeto que permite que funciones genéricas proporcionen reglas de distribución y especialización específicas de la aplicación.

El envío en CLOS también es diferente de la mayoría de los lenguajes OO:

  1. Dada una lista de argumentos, se determina una lista de métodos aplicables.
  2. Esta lista está ordenada según la especificidad de sus especialistas de parámetros.
  3. Los métodos seleccionados de esta lista luego se combinan en un método efectivo utilizando la combinación de métodos utilizada por la función genérica.
  4. Luego se llama al método efectivo con los argumentos originales.

Este mecanismo de despacho funciona en tiempo de ejecución. Por lo tanto, agregar o eliminar métodos puede provocar cambios en los métodos efectivos (incluso cuando la función genérica se llama con los mismos argumentos) en tiempo de ejecución. Cambiar la combinación de métodos también puede conducir a diferentes métodos efectivos.

Por ejemplo,

; Declare el prototipo de estructura de argumento común. ( defgenérico f ( x y ))   ; Defina una implementación para (f entero y), donde y coincida con todos los tipos. ( método de definición f (( x entero ) y ) 1 )     ( f 1 2,0 ) => 1    ; Defina una implementación para (f entero real). ( método de definición f (( x entero ) ( y real )) 2 )      ( f 1 2.0 ) => 2 ;El envío cambió en tiempo de ejecución.     

Como los sistemas OO en la mayoría de los lenguajes dinámicos , CLOS no impone la encapsulación . Se puede acceder a cualquier ranura mediante la función o mediante métodos de accesoslot-value (opcionalmente generados automáticamente) . Para acceder a él a través de usted debe saber el nombre de la ranura. Los programadores de CL utilizan la función de paquete del lenguaje para declarar qué funciones o estructuras de datos se pretenden exportar.slot-value

Además de los métodos normales ("primarios"), también existen métodos :before, :aftery :around"auxiliares". Los dos primeros se invocan antes o después del método principal, en un orden particular basado en la jerarquía de clases. Un :aroundmétodo puede controlar si el método principal se ejecuta o no. Además, el programador puede especificar si se deben llamar a todos los métodos primarios posibles a lo largo de la jerarquía de clases o solo al que proporciona la coincidencia más cercana.

La combinación de métodos estándar proporciona los métodos primarios, antes, después y alrededor explicados anteriormente. Existen otras combinaciones de métodos con otros tipos de métodos. Se pueden definir nuevas combinaciones de métodos (tanto simples como complejas) y tipos de métodos.

CLOS permite herencia múltiple . Cuando el orden predeterminado en el que se ejecutan los métodos en herencia múltiple no es correcto, el programador puede resolver los problemas de herencia de diamantes especificando el orden de las combinaciones de métodos.

CLOS es dinámico, lo que significa que no sólo el contenido, sino también la estructura de sus objetos se pueden modificar en tiempo de ejecución. CLOS admite cambiar las definiciones de clase sobre la marcha (incluso cuando ya existen instancias de la clase en cuestión), así como cambiar la membresía de clase de una instancia determinada a través del change-classoperador. CLOS también permite agregar, redefinir y eliminar métodos en tiempo de ejecución. El problema del círculo-elipse se resuelve fácilmente en CLOS y la mayoría de los patrones de diseño de programación orientada a objetos desaparecen o son cualitativamente más simples. [2]

CLOS no es un lenguaje prototipo : las clases deben definirse antes de que se puedan crear instancias de objetos como miembros de esa clase.

Protocolo de metaobjeto

Fuera del estándar ANSI Common Lisp, existe una extensión de CLOS ampliamente implementada llamada Metaobject Protocol (MOP). El MOP define una interfaz estándar para los fundamentos de la implementación de CLOS, tratando clases, descripciones de ranuras, funciones genéricas y métodos en sí mismos como instancias de metaclases , y permite la definición de nuevas metaclases y la modificación de todo el comportamiento de CLOS. La flexibilidad del CLOS MOP prefigura la programación orientada a aspectos , que más tarde fue desarrollada por algunos de los mismos ingenieros, como Gregor Kiczales . El MOP define el comportamiento de todo el sistema de objetos mediante un conjunto de protocolos. Estos se definen en términos de CLOS. Por lo tanto, es posible crear nuevos sistemas de objetos ampliando o cambiando la funcionalidad CLOS proporcionada. El libro El arte del protocolo Metaobject describe el uso y la implementación de CLOS MOP.

Las diversas implementaciones de Common Lisp tienen un soporte ligeramente diferente para el protocolo Meta-Object. El proyecto Closer [3] tiene como objetivo proporcionar las características que faltan.

Influencias de sistemas de objetos más antiguos basados ​​en Lisp

Flavors (y su sucesor New Flavours) fue el sistema de objetos de la máquina Lisp del MIT . Gran parte de los sistemas operativos de Lisp Machine y muchas aplicaciones utilizan Flavors o New Flavors. Los sabores introdujeron herencia múltiple y mixins , entre otras características. Flavors está en su mayor parte obsoleto, aunque existen implementaciones para Common Lisp. Flavors estaba usando el paradigma de transmisión de mensajes. New Flavors introdujo funciones genéricas.

CommonLoops fue el sucesor de LOOPS (de Xerox Interlisp -D). CommonLoops se implementó para Common Lisp. Una implementación portátil llamada Portable CommonLoops (PCL) fue la primera implementación de CLOS. PCL está ampliamente adaptado y todavía proporciona la base para la implementación CLOS de varias implementaciones de Common Lisp . PCL se implementa principalmente en Common Lisp portátil con sólo unas pocas partes dependientes del sistema.

CLOS en otros lenguajes de programación

Debido al poder y la expresividad de CLOS, así como a la disponibilidad histórica de Tiny CLOS (una implementación CLOS portátil simplificada escrita por Gregor Kiczales para su uso con Scheme), los sistemas de objetos basados ​​en MOP similares a CLOS se han convertido en la norma de facto en la mayoría de los casos. Implementaciones de dialectos Lisp, además de encontrar su camino hacia las instalaciones de programación orientada a objetos de otros idiomas :

Otras lecturas

Referencias

  1. ^ "CLOS es un estándar. Varios proveedores suministran CLOS. CLOS (o partes de él) se utiliza para agregar orientación a objetos a otros dialectos Lisp como EuLisp o Emacs Lisp". pag. 110 de Veitch 1998
  2. ^ En las diapositivas de Patrones de diseño en lenguajes dinámicos, Peter Norvig presenta sus hallazgos de que 16 de 23 patrones de diseño tomados de varios libros de texto son "invisibles o más simples" en Dylan o Common Lisp que en C++.
  3. ^ Proyecto más cercano: más cerca de MOP
  4. ^ Deniau, Laurent (12 de marzo de 2010). El sistema de objetos C: uso de C como lenguaje orientado a objetos de alto nivel (PDF) . arXiv : 1003.2547 . CiteSeerX 10.1.1.763.7946 . Consultado el 17 de marzo de 2022 . 
  5. ^ Extensión orientada a objetos de Dynace a C
  6. ^ Newton, Jim; Rodas, Christophe (28 de noviembre de 2008). "Especialistas personalizados en Lisp orientado a objetos". Revista de Informática Universal . 14 (20): 3370–3388. CiteSeerX 10.1.1.523.2413 . doi : 10.3217/jucs-014-20-3370 . S2CID  12032836 . Consultado el 17 de marzo de 2022 . 
  7. ^ Tiny CLOS, desarrollado por Gregor Kiczales

Literatura