Definición formal para el término "lenguaje puro OO"?

13

No puedo pensar en un lugar mejor entre los hermanos SO para plantear tal pregunta. Originalmente quería preguntar "¿Python es un lenguaje puro OO?" pero teniendo en cuenta los problemas y algún tipo de incomodidad que las personas experimentan al tratar de definir el término, decidí comenzar por obtener una definición clara del término en sí.

Sería bastante justo comenzar con la correspondencia del Dr. Alan Kay, quien ha acuñado el término (tenga en cuenta la inspiración en analogía biológica con las células u otros objetos vivos).

Existen las siguientes formas de abordar la tarea:

  1. Haga un análisis comparativo enumerando los lenguajes de programación que pueden exhibir (o no hacerlo) ciertas propiedades únicas y suficientes para definir el término (aunque Smalltalk, Scala, Java , etc.) son ejemplos posibles, pero IMO de esta manera parece no estar realmente completo ni fructífero )
  2. Dé una definición formal (o cercana a ella, por ejemplo, en un estilo más académico o matemático).
  3. Dé una definición filosófica que dependería totalmente del contexto semántico del lenguaje concreto o de una experiencia de programación a priori (debe haber alguna posibilidad de una explicación exitosa por parte de la comunidad).

Mi versión actual: "Si un cierto lenguaje de programación ( formal ) que puede ( gramaticalmente ) diferenciar entre operaciones y operandos, así como inferir sobre el tipo de cada operando si este tipo es un objeto (en el sentido de OOP) o no, entonces llamamos dicho lenguaje es un lenguaje OO siempre que haya al menos un tipo en este lenguaje que sea un objeto. Finalmente, si todos los tipos de lenguaje son también objetos, definimos dicho lenguaje como lenguaje OO puro (fuerte) ".

Agradecería cualquier posible mejora de la misma. Como puede ver, acabo de hacer que la definición dependa del término "objeto" (a menudo completamente referenciado como clase de objetos).

[EDITAR]

Además, uso la noción (afortunadamente bien entendida) de un tipo como en los idiomas escritos. La programación de tipos de datos o la programación orientada a tipos no es solo una interpretación sintáctica (del texto del programa, es decir, cómo tratar ciertos valores de literales y variables de datos, algo que evoluciona hacia la seguridad de los tipos), sino que puede atribuirse a la gramática del lenguaje y estudiarse de manera formal. (usando lógica matemática) como los llamados sistemas de tipos . Tenga en cuenta que exigir que un sistema de tipos particular tenga un llamado tipo universal es una de las formas de definir la pureza del lenguaje OO (hay formas de expandir esto semánticamente).

nótese bien

cómo responder a :

  • ayuda si especifica un libro o una referencia que respalde / explique su comprensión de la terminología y los conceptos (por lo general, una buena definición cubre o hace referencia a todos los conceptos dependientes, excepto los de primaria).
  • si es posible, indique una categoría con sangría de su respuesta / definición si no está claro lo contrario (ver arriba: 1 - por ejemplo de lenguaje, 2 - lógica matemática, 3 - descripción técnica y filosofía de programación)
  • la clasificación es importante (y también porque el término OO puro se incluye en el término OO) al responder, intente descomponer elementos del paradigma OO de otras metodologías bien conocidas (y de ninguna manera confundirlos / superponerlos, por ejemplo, típicamente se pueden cubrir elementos de programación modular / incorporado con la programación OO): intente distinguir la OOP de (incluyendo o siendo parte de) programación funcional, programación lógica (especialmente altamente especializada), tipos de datos Abstarct (ADT), modular, metaprogramación (genéricos y tiempo de macroexpansión de LISP), Contratos (por ejemplo, Eiffel), Orientado a aspectos (AO), (la diferencia entre la clasificación declarativa y funcional, así como las definiciones históricas de la estructura de Dijkstra son claras)

sobre la dificultad de dar una definición formal : sorprendentemente, es muy fácil dar una descripción matemática de OOP en forma de cierto sistema lógico (formal) (muy probablemente basado en tipos) y definiendo un concepto tras otro. Incluso se puede tratar de hacer algo más práctico aplicando ese formalismo a la verificación de seguridad de tipos o aspectos de diseño de lenguaje nuevo que simplemente el entretenimiento abstractoo el ejercicio (también formulación de búsqueda de OOP en la teoría de tipos intuitiva , tipos dependientes , independientemente, en formalismos FOL como cálculo lambda y solo usando la teoría de categorías). Un punto principal aquí es que, como era de esperartales formulaciones IMO están fuertemente sesgadas (defectuosas) por una comprensión inicialmente incompleta de OOP (en ingeniería informática) y terminan siendo casi inaccesibles después (por lo tanto, apenas contribuyen al mundo de la programación, tal vez excepto que cierto porcentaje encuentra aplicaciones del mundo formal al ser integrado a los idiomas populares ).

Entonces, sí, es difícil dar exactamente una "buena" definición, no solo una definición. Pero estoy seguro de preguntar esto aquí debido a su experiencia y participación directa, muchachos.

Yauhen Yakimovich
fuente
2
Bueno, te has respondido a ti mismo para Python. "No".
psr
2
+1 para la buena pregunta, pero su versión está un poco defectuosa por el problema de que un tipo y un objeto son cosas diferentes.
Frank
55
@JoachimSauer: Dijo en otro correo en la lista de correo de Squeak que "la gran idea es la mensajería" y que lamenta haberlo llamado "Orientado a objetos" y que debería haberlo llamado "Orientado a mensajes". Erlang, por ejemplo, es un lenguaje completamente orientado a objetos que cumple con todos los criterios del Dr. Kay sin tener ningún concepto de "objetos", "métodos", "herencia", "clases", "prototipos" o algo así. .
Jörg W Mittag el
1
Esta podría ser una buena ilustración de que las sintaxis no son suficientes para definir un lenguaje OO. Si uno puede mostrar que la POO (por ejemplo, como herramienta) es semántica solamente (independiente de sintaxis), ¡eso cambia (invierte) mi pregunta por completo!
Yauhen Yakimovich
2
@YauhenYakimovich Este es uno de los problemas fundamentales en la discusión de OOP, cada uno y su perro tienen su propia idea de lo que es. En contraste, la programación estructurada y la programación funcional se pueden definir de manera muy simple. Esto me lleva a cuestionar si OO tiene propiedades similares a la religión en lugar de la ciencia.
Ricky Clarkson

Respuestas:

19

OO, según Alan Kay, todo se trata de pasar mensajes, y eso es todo. Verá que cualidades como el polimorfismo y la encapsulación se derivan realmente del paso de mensajes.

Ahora esa postura es, de hecho, muy extrema, porque básicamente significa que solo Smalltalk e idiomas calificarían.

Creo que puede definir OO como construir su sistema en entidades, que encapsulan completamente su estado y que se hacen intercambiables debido a sus cualidades polimorfas inherentes. Por lo tanto, se podría argumentar que un lenguaje puramente OO asegura que estas dos cualidades centrales siempre se cumplan. Lo que hace que los lenguajes OO sean "impuros" serían mecanismos que permitan la creación de construcciones que no cumplan con estos criterios, como las posibilidades de:

  • declarar campos públicos
  • declarar variables que solo pueden contener instancias de una clase específica y sus subclases (es decir, las variables deben escribirse contra interfaces, que es a través de lo que se comunican los objetos biológicos en la anología de Kay), que se vuelve aún más estrecho si la clase en cuestión es final, como eso deja aún menos espacio para el polimorfismo
  • declarar primitivas

Por otra parte, la pureza del lenguaje en mi humilde opinión es más una debilidad que una fortaleza. OO no es una bala de plata. No hay un solo paradigma.

back2dos
fuente
2
+1 para "OO no es una bala de plata".
Andres F.
1
@AndresF. Tenga en cuenta que el valor práctico de OOP, así como otros conocimientos teóricos relacionados con la programación, no son realmente parte de una pregunta. Es bastante obvio que uno puede escribir código de una manera bastante exitosa sin una comprensión profunda de las técnicas o teorías de programación (y viceversa). Tampoco se discuten las propiedades de aplicación de los lenguajes OO, etc.
Yauhen Yakimovich
@YauhenYakimovich Oh, lo sé. No hubiera votado por la respuesta si hubiera estado fuera de tema. Aún así, me gustó una afirmación con la que estoy de acuerdo.
Andres F.
@AndresF. Claro :-) "OO no es una bala de plata" es muy probable, así como también nos falta un lenguaje de programación perfecto. Pero, ¿qué hace exactamente que la POO no sea una bala de plata? Como un buen informe de error, creo que la terminología detallada y precisa es la forma de responder a esto. He invertido tanto tiempo trabajando con él que tengo mucha curiosidad por llevarlo al siguiente nivel. ¿OOP es solo un montón de ideas copiadas de un libro de programación a otro?
Yauhen Yakimovich
@ back2dos +1 por señalar explícitamente el papel de "pasar mensajes" según Kay (Smalltalk, Objective-C). Aparentemente, nunca tuvo la intención de ver a OOP desarrollada hacia las direcciones que tiene hoy. Pero realmente me gustó que Kay tuviera esas ideas para hacer objetos, NO datos (tipos). Realmente presionó para atribuirles cualidades biológicas, pero terminó en "mensajes".
Yauhen Yakimovich
6

Lo abordaría definiéndolo como un lenguaje que usa construcciones OOP y nada más (de la misma manera que un lenguaje FP puro usa funciones puras con datos inmutables y nada más).

En particular:

  • Cada entidad en la que opera su programa es un Objeto de primera clase , es decir, sin primitivas, sin punteros, sin matrices, etc.
  • Lo único que puede hacer con un objeto es llamar a un método (potencialmente polimórfico) (== enviar un mensaje). No existen otras operaciones.
  • Todos los datos están encapsulados , es decir, no hay acceso de campo público, debe ir a través de métodos en un objeto
  • Si tiene funciones de primera clase, también deben ser objetos , por lo que deberá hacer algo comofunctionObject.call(param1,param2)
  • Sin variables globales : si desea algo como esto, necesitaría usar un objeto para representar el entorno global actual, por ejemplo, environment.getValue("myThing")o colocar la variable en un objeto de clase

Tenga en cuenta que esto todavía deja bastantes opciones abiertas:

  • Modelos de objetos basados ​​en clases versus prototipos
  • Cómo se implementa la herencia (en todo caso)
  • Ya sea que tenga despacho único o múltiple en métodos
  • Si sus objetos están tipados estática o dinámicamente
  • La sintaxis exacta utilizada para las llamadas a métodos (por ejemplo, podría tener algo de azúcar sintáctica para captadores / establecedores, etc.)
mikera
fuente
1
Estas son buenas definiciones, pero no confunda la realidad del objeto con la mera sintaxis. Solo porque las funciones y las variables globales tienen una sintaxis amigable, en realidad pueden ser objetos en el fondo.
ddyer
@ddyer: eso es correcto si realmente es solo una sintaxis, pero creo que si la sintaxis también introduce una semántica diferente, entonces puede romper la "pureza". Por ejemplo, el uso de las variables globales wrt globalVariableNamepara acceder a una variable global es una semántica diferente de la llamada a un método en un objeto, que sería la única forma de acceder a un valor no local en OOP puro.
mikera
Creo que "Todo" necesita ser calificado. Si un lenguaje no tiene capacidad de reflexión en absoluto (por ejemplo, no puede hacer referencia a un método de un objeto por un nombre abstracto, o almacenarlo en una variable), ¿entonces los métodos también deben ser objetos? ¿Son referencias los objetos? ¿Las referencias y los objetos son incluso cosas diferentes?
Joachim Sauer
@Joachim: buen punto. Lo califiqué como "cada entidad en la que opera su programa" para distinguir objetos de metaobjetos en el lenguaje como nombres de variables y construcciones sintácticas. Obviamente, si su programa realmente opera en tales cosas a través de la reflexión, entonces necesitarían ser reificadas como objetos reales, pero eso no siempre será un requisito. De todos modos, si puedes pensar en una mejor calificación, ¡no dudes en editarla!
mikera
"Modelos de objetos basados ​​en clases versus modelos basados ​​en prototipos": pero diría que en ambos casos tiene algún tipo de clasificación, es decir, agrupa objetos con una estructura y un comportamiento comunes.
Giorgio
4

La discusión sobre los llamados lenguajes OO siempre ha sido un poco del lado del cerebro. Es decir:

"Alguien me ha dicho que el lenguaje X es OO, por lo tanto, el lenguaje X es igual a OO, entonces todos los idiomas que carecen de las características del lenguaje X no pueden ser OO. Y como estoy escribiendo mi código en el lenguaje X, todo lo que hago es OO". "

El término diseño orientado a objetos se reduce a 3 cosas:

  1. Diseño modular con objetos autónomos que no conocen información innecesaria sobre el resto del programa, también conocido como acoplamiento lo más suelto posible.
  2. Encapsulación de datos dentro de objetos para evitar el acceso externo, tanto intencional como accidental.
  3. Dependencias claramente especificadas entre objetos. Para lograr un acoplamiento flojo, pero también para hacer que el programa sea más fácil de mantener y expandir.

1) es un diseño de programa puro, se puede lograr en cualquier lenguaje de programación. Sin embargo, algunos idiomas tienen características útiles como class / struct y palabras clave privadas.

2) es principalmente un diseño de programa, aunque no se puede lograr completamente sin soporte de idiomas, ya que necesita mecanismos de lenguaje como privado / estático para protegerse contra el uso accidental.

3) es principalmente el diseño del programa. Normalmente hay tres dependencias diferentes: "el objeto X contiene el objeto Y", "el objeto X es una especie de Y" y "el objeto X interactúa con el objeto Y". Hay muchas características del lenguaje para ayudar con estas dependencias: herencia / polimorfismo, clases base abstractas, etc.

Ahora, si miramos lo anterior, podemos ver que apenas necesita funciones de lenguaje para escribir programas OO. Las características simplemente lo hacen mucho más fácil.

Los objetivos anteriores no se pueden lograr mediante el uso de una lógica hacia atrás fangosa: solo porque usa la palabra clave de clase, su programa no obtiene automáticamente un diseño modular. El hecho de que use la herencia no significa automáticamente que las dependencias de sus objetos tengan sentido. Un lenguaje con características OO aún permitiría cosas como class TheWholeBloodyProgram"Animal hereda Cat".

Lamentablemente, el tema del buen diseño de programa orientado a objetos rara vez se menciona en este tipo de discusiones. Los programadores con lavado de cerebro solo miran la sintaxis y dicen cosas como, por ejemplo, "C ++ tiene tipos de datos primitivos para que su programa C ++ no sea OO", luego van a escribir un programa francamente horrible en su propio idioma favorito, sin usar ningún indicio de programa de diseño lo que sea.

Para responder a la pregunta: muy pocos, si alguno de los idiomas tiene soporte para el diseño adecuado del programa OO. Para averiguar qué lenguajes que tienen ciertas características relacionadas con OO es irrelevante siempre que el programador no sepa qué significa el diseño orientado a objetos. Un programador que afirma que ciertos lenguajes están orientados a objetos probablemente no ha comprendido el concepto de OO como un todo. Pregunte al aspirante a programador de OO cómo diseñan los programas de OO. Si lo primero que hacen es comenzar a gritar palabras clave en el idioma, entonces puede asumir con seguridad que no conocen el diseño OO.

Quizás exista alguna herramienta sofisticada de alto nivel UML-ish muy por encima del código fuente en bruto, que obliga al programador a escribir solo programas con un buen diseño orientado a objetos, pero lo dudo. Las mejores herramientas de diseño para la programación OO probablemente sean el cerebro humano y el sentido común.


fuente
¿Puede aclarar cómo difiere su definición, por ejemplo, la programación modular con tipos de datos abstractos? Creo que estás en el camino correcto, ¡pero todavía no puedo ver el tren!
Jörg W Mittag el
@ JörgWMittag No es necesariamente diferente, los ADT tradicionales se pueden escribir utilizando un diseño orientado a objetos, con una encapsulación adecuada, establecedores / captadores, formas de heredarlo, etc., etc. Pero también se pueden escribir sin tener en cuenta el diseño OO. ->
2
@ JörgWMittag Si tiene un lenguaje como C, por ejemplo, con soporte de lenguaje limitado para OO, entonces es difícil escribir ADT: s de una manera orientada a objetos. El error más común es dejar la asignación del ADT a la persona que llama, es decir, darle una estructura pública con todos los elementos internos expuestos, rompiendo la encapsulación. La forma correcta de hacer esto en C es a través de los llamados "tipos opacos" (tipos incompletos), aunque no muchos programadores de C saben usarlos.
@Lundin: En el artículo publicado por JörgWMittag como un comentario a otra respuesta, hay una comparación interesante (IMO) entre ADT y OO.
Giorgio
Recuerdo de algunos libros de UML (probablemente) un punto adicional 0. Abstracción (destacando la importancia de la formulación abstracta esencial para las relaciones entre objetos como polimorfismo, herencia, agregación, etc.).
Yauhen Yakimovich
2

No, no existe una definición formal o incluso útil, y nunca la habrá. Para algunas personas, OOP significa "Clase base universal" y "Debe usar semántica de referencia, mejor con un recolector de basura", e incluso puede obtener objeciones sobre la sintaxis, una de las cosas menos relevantes jamás inventadas.

Finalmente, primero, debe responder la pregunta "¿Qué es un objeto?". Los de mente más estrecha insistirán en heredar de alguna clase base universal sin sentido y serán asignados innecesariamente en un recolector de basura para calificar. Pero prefiero una definición mucho más útil. El propósito de OOP es tener algunos datos y algunas funciones a las que puede recurrir en esos datos. Entonces

  • Un objeto tiene algún estado y ofrece algunas funciones en ese estado.

En este caso, incluso intcalifica. Después de todo, cuando escribe código de plantilla en C ++ que puede aceptar primitivas u objetos, se hace difícil argumentar que las primitivas son diferentes de manera sustancial. No hay nada significativamente diferente en Vector v1, v2; v1 + v2;lugar de int v1, v2; v1 + v2;(excepto la semántica de inicialización horrible, uno debe admitir). Además, esto permite que las lambdas y esas cosas sean objetos, ya que mantienen el estado, sus capturas, y ofrecen una función en ese estado, para llamar a la lambda.

Afortunadamente, también podemos clasificar los punteros para liberar funciones como objetos, ya que ambos tienen un estado (una dirección) y una función en ese estado (para llamarlo). Por lo tanto, debe permitirse una función libre, incluso si dijera que todas las funciones libres son de hecho punteros de función global.

DeadMG
fuente
2
No veo la necesidad de tal distinción. Pero en segundo lugar, tienen la misma identidad que cualquier otro objeto tiene: comparación de dirección / referencia. El hecho de que no pueda distinguir dos objetos con el mismo estado, excepto mediante la comparación de direcciones, está lejos de ser nuevo y se aplica a todos los objetos.
DeadMG
55
-1. Comienza con una diatriba inútil e innecesaria, cambia brevemente al ataque ad hominem y lo único que es remotamente real (la definición de OOP ) está mal. Lea Sobre la comprensión de la abstracción de datos, revisado por William R. Cook para ver la diferencia entre un tipo de datos abstractos y un objeto.
Jörg W Mittag
1
"No veo la necesidad de tal distinción". Pero esta distinción se encuentra entre las características comúnmente aceptadas de los objetos. Por supuesto, puede desarrollar su propia noción de un objeto que es diferente de lo que comúnmente se acepta. Eres totalmente libre de hacerlo.
Giorgio
2
@ Jörg Ruego diferir. No estoy completamente de acuerdo con esta publicación, pero llamar a la advertencia en el primer párrafo "inútil" o "despotricar" es falso. No existe una definición universalmente aceptada para la POO. Ese es un hecho simple y ampliamente reconocido. El resto de la publicación es una definición de OOP. Ciertamente no es el más utilizado, ni el que yo daría, pero, como dijo DeadMG, en realidad es bastante útil.
Konrad Rudolph
2
@KonradRudolph: ese párrafo se leía muy diferente cuando escribí mi comentario, incluida la comparación de programadores que se preocupan por la sintaxis con los racistas, incluso mencionando a un usuario específico de este sitio por su nombre.
Jörg W Mittag el
0

Puedes pensarlo con un ejemplo negativo. Java no es un lenguaje puro orientado a objetos porque también hay tipos primitivos que no son objetos. Estos son enteros, dobles, matrices, etc. En un lenguaje de objetos puro, la semántica de los objetos está disponible para todo.

También está la cuestión de cuánto del lenguaje está cerrado a modificaciones, incluso dentro del marco de objetos. En java no puede definir nuevas subclases para algunas clases, como String o Class.

¿Qué idiomas son puros? El único candidato que viene a la mente es smalltalk.

ddyer
fuente
¿No es Ruby puro lenguaje OO también?
zxcdw
2
@zxcdw (y ddyer): ese es exactamente el problema: nadie tiene una definición formal de "OO puro", por lo que nadie puede dar una respuesta definitiva a esa pregunta.
Joachim Sauer