¿Cuál es el siguiente nivel de abstracción? [cerrado]

15

Dado que los lenguajes de programación inicialmente solo usaban líneas de código ejecutadas secuencialmente, evolucionaron para incluir funciones que eran uno de los primeros niveles de abstracción, y luego se crearon clases y objetos para abstraerlo aún más; ¿Cuál es el siguiente nivel de abstracción?

¿Qué es aún más abstracto que las clases o hay alguna todavía?

Jordan Medlock
fuente
17
Parece pensar que es una progresión lineal, con un orden ("X es más abstracto que Y es más abstracto que Z"). Siento disentir.
2
Sería una buena idea decir por qué suplicas diferir. ;) (léase: ¡Estoy interesado!)
sergserg
3
Propongo la "abstracción" definitiva: hacer lo que pienso, no lo que escribo. ;)
Izkata
1
@Delnan: La abstracción no introduce un orden total, pero es posible decir "más abstracto", "menos abstracto". Por ejemplo, una implementación genérica de clasificación de fusión es más abstracta que una implementación de clasificación de fusión que solo funciona para enteros.
Giorgio
2
Bros, aprende algo de teoría de categorías. Entonces podemos discutir lo que realmente significa abstracción como los hombres civilizados.
davidk01

Respuestas:

32

Creo que tienes algunas ideas falsas sobre la historia de la informática.

La primera abstracción (en 1936) fue, de hecho, el cálculo Lambda de Alonzo Church, que es la base del concepto de funciones de alto orden y todos los lenguajes funcionales que siguieron. Inspiró directamente a Lisp (el segundo lenguaje de programación de alto nivel más antiguo, creado en 1959), que a su vez inspiró todo, desde ML hasta Haskell y Clojure.

La segunda abstracción fue la programación procesal. Salió de las arquitecturas informáticas de von Neumann donde se escribieron programas secuenciales, una instrucción a la vez. FORTRAN (el lenguaje de programación de alto nivel más antiguo, 1958) fue el primer lenguaje de alto nivel que salió del paradigma procesal.

La tercera abstracción probablemente fue en realidad una programación declarativa, primero ejemplificada por Absys (1967), y luego Prolog (1972). Es la base de la programación lógica, donde las expresiones se evalúan haciendo coincidir una serie de declaraciones o reglas, en lugar de ejecutar una serie de instrucciones.

La cuarta abstracción fue la programación orientada a objetos, que hizo su primera aparición en los programas Lisp en los años 60, pero más tarde fue ejemplificada por Smalltalk en 1972. (Aunque parece haber cierto debate sobre si el estilo de Smalltalk es el de pasar mensajes) la única abstracción orientada a objetos verdadera. No voy a tocar eso.)

Todas las demás abstracciones, especialmente en la arquitectura de computadora tradicional de von Neumann, son variaciones de esos cuatro temas. No estoy convencido de que haya otra abstracción más allá de esas cuatro que no sea simplemente una variación o una combinación de ellas.

Pero una abstracción es, en esencia, simplemente una forma de modelar y describir un algoritmo. Puede describir los algoritmos como una serie de pasos discretos, como un conjunto de reglas que deben obedecerse, como un conjunto de funciones matemáticas o como objetos interactivos. Es muy difícil concebir otra forma de describir o modelar algoritmos, e incluso si lo hay, no estoy convencido de su utilidad.

Sin embargo, existe el modelo de computación cuántica. En la computación cuántica, son necesarias nuevas abstracciones para modelar algoritmos cuánticos. Siendo un neófito en esta área, no puedo comentarlo.

Greyfade
fuente
44
¿Podría la programación orientada a aspectos ser considerada otra forma de abstracción?
Shivan Dragon
¿La programación orientada a objetos salió de Lisp en los años 60? [cita requerida], a lo grande. Todo lo que escuché dice que salió de Simula en los años 60, que era un descendiente directo de ALGOL, un lenguaje imperativo que no tenía nada que ver con Lisp. Smalltalk surgió tomando conceptos introducidos por Simula y girándolos para sentirse más "lispy".
Mason Wheeler
3
@MasonWheeler: está en los manuales de Lisp 1 y 1.5, y es común escuchar a Lispers hablar de programas orientados a objetos, especialmente los viejos. Los muchachos de IA eran grandes haciendo sistemas de objetos en Lisp en ese momento.
greyfade
2
@ShivanDragon: Yo diría que no. Es solo una forma de instrumentar un programa de otro modo procesal con arneses adicionales. Realmente no modela algoritmos, ni parece influir en el diseño de estructuras de datos.
greyfade
44
En realidad, el cálculo del combinador de SKI es anterior tanto al cálculo lambda como a la máquina de Turing.
Jörg W Mittag
4

Para muchos, la forma más pura de abstracción de código en la era actual de la programación binaria es la "función de orden superior". Básicamente, la función en sí misma se trata como datos, y las funciones de las funciones se definen, tal como las vería en ecuaciones matemáticas con operadores que definen el resultado de sus operandos y un orden predeterminado de operaciones que definen el "anidamiento" de estas operaciones. Las matemáticas tienen muy pocos "comandos imperativos" en su estructura; Los dos ejemplos que se me ocurren son "dejar que x tenga algún valor o ser cualquier valor conforme a alguna restricción" y "funciones por partes" en las que la entrada determina la expresión necesaria para producir la salida. Estas construcciones son fácilmente representables como sus propias funciones; la "función" x siempre devuelve 1, y "sobrecargas" de funciones se definen en términos de lo que se les pasa (que, a diferencia de las sobrecargas orientadas a objetos, se pueden definir en función de la entrada de valores), lo que permite la evaluación "por partes" de un grupo de funciones con nombre, incluso en términos de sí mismas. Como tal, el programa elimina la noción de imperativos en el nivel bajo y, en cambio, se enfoca en "evaluarse a sí mismo" dados los datos de entrada.

Estas funciones de orden superior forman la columna vertebral de los "lenguajes funcionales"; lo que hace un programa se define en términos de "funciones puras" (una o más entradas, una o más salidas, sin efectos secundarios o "estado oculto"), que se anidan entre sí y se evalúan según sea necesario. En tales casos, la mayoría de la "lógica imperativa" se abstrae; el tiempo de ejecución maneja la llamada real de funciones, y cualquier condición en la cual una u otra sobrecarga de una función deba ser llamada. En dicho programa, el código no se considera como "hacer" algo, sino como "ser" algo, y qué se determina exactamente a medida que el programa se ejecuta con la entrada inicial.

Las funciones de orden superior ahora son un elemento básico de muchos lenguajes imperativos también; Las declaraciones lambda de .NET básicamente permiten la entrada funcional "anónima" en otra "función" (implementada de manera imperativa pero teóricamente no tiene que ser así), permitiendo así el "encadenamiento" altamente personalizable de "funciones" de propósito muy general para lograr El resultado deseado.

Otra abstracción comúnmente vista en la última ronda de lenguajes de programación es la tipificación dinámica de variables basada en el concepto de "tipificación de pato"; si parece un pato, nada como un pato, vuela como un pato y grazna como un pato, puedes llamarlo pato. No importa si en realidad es un pato real o un lienzo. PODRÍA importar si en realidad es un ganso o un cisne, pero, de nuevo, podría no importar si lo único que le importa es que nada y vuela, y se parece un poco a un pato. Esto se considera lo último en herencia de objetos; no te importa lo que es , excepto darle un nombre; lo que es más importante es lo que hace. En tales lenguajes hay básicamente solo dos tipos; el "átomo", un único elemento de información (un "valor"; un número, carácter, función, lo que sea), y la "tupla", compuesta de un átomo y un "puntero" a todo lo demás en la tupla. Exactamente cómo estos tipos son implementados en binario por el tiempo de ejecución es irrelevante; con estos, puede lograr la funcionalidad de prácticamente todos los tipos que se le ocurran, desde tipos de valores simples hasta cadenas y colecciones (que, dado que los valores pueden ser de "tipos" diferentes, permite "tipos complejos", también conocidos como "objetos").

KeithS
fuente
1
El "tipeo de pato" (al menos como lo describe) no es realmente novedoso ni está limitado a lenguajes tipados dinámicamente; ha existido durante mucho tiempo en lenguajes tipados estáticamente como "subtipado estructural", mejor visto en OCaml.
Tikhon Jelvis
2

Uno podría considerar lenguajes específicos de dominio como SQL como un orden superior de abstracción. SQL es un lenguaje muy específico que abstrae operaciones como el almacenamiento y proporciona funciones de nivel superior basadas en la teoría de conjuntos. Considere también cuántos lenguajes actuales hoy en día no se dirigen a una arquitectura específica sino a una máquina virtual (como JVM o .NET CLR). Por ejemplo, C # se compila en IL, que el motor de tiempo de ejecución nativo interpreta (o con más frecuencia JIT'd --Just In Time Compiled-- a una implementación nativa).

Ha habido mucho bullicio sobre el concepto de DSL que se utiliza para crear lenguajes de muy alto nivel que se pueden utilizar sin mucha experiencia técnica para crear un programa de trabajo. Piense si alguien pudiera describir sus entidades e interacciones en un inglés cercano y el entorno operativo manejara todo, desde presentar una interfaz de usuario simple, hasta almacenar datos en una base de datos de algún tipo. Una vez que esas operaciones se vuelven abstractas, puedes imaginar lo fácil que puede ser la programación.

Existen algunos en la actualidad, como JetBrains MPS (que es un juego de herramientas para describir DSL o un generador de lenguaje). Microsoft tuvo una breve incursión (y muy prometedor podría agregar) en este espacio con su lenguaje M (el lenguaje M era tan completo que el lenguaje se definió en M).

Los críticos del concepto apuntan a intentos fallidos anteriores para eliminar a los programadores del trabajo de desarrollo de programas, la diferencia con los bancos de trabajo DSL (como los llama Fowler) es que los desarrolladores aún estarían involucrados en la codificación de conceptos que los Expertos de Dominio podrían usar para expresar Las necesidades de su dominio. Al igual que los proveedores de sistemas operativos y lenguaje crean herramientas que usamos para la programación, nosotros usamos DSL para proporcionar herramientas a los usuarios comerciales. Uno podría imaginar DSL que describan los datos y la lógica, mientras que los desarrolladores crean intérpretes que almacenan y recuperan datos y aplican la lógica expresada en el DSL.

Michael Brown
fuente
1

Yo diría que las metaestructuras, los módulos, los marcos, las plataformas y los servicios son agrupaciones de características de nivel más alto que las clases. Mi jerarquía de abstracciones del sistema de programación:

  • servicios
  • plataformas, pilas de soluciones
  • marcos
  • módulos, paquetes
  • meta estructuras: metaclases, funciones de orden superior, genéricos, plantillas, rasgos, aspectos, decoradores
  • objetos, clases, tipos de datos
  • funciones, procedimientos, subrutinas
  • Estructuras de Control
  • líneas de código

Las metaestructuras como metaclases , funciones de orden superior y genéricos añaden claramente abstracción a clases básicas, funciones, tipos de datos e instancias de datos. Los rasgos, los aspectos y los decoradores son mecanismos más nuevos para combinar características de código y, de manera similar, "aceleran" otras clases y funciones.

Incluso los lenguajes pre-objeto tenían módulos y paquetes, por lo que ponerlos por encima de las clases podría ser discutible. Pero contienen esas clases y metaestructuras, así que las clasifico más alto.

Los marcos son la respuesta más importante: organizan múltiples clases, metaestructuras, módulos, funciones y demás para proporcionar abstracciones sofisticadas de alto nivel. Y, sin embargo, los marcos siguen funcionando casi por completo en el ámbito de la programación.

Las pilas o plataformas de soluciones generalmente combinan múltiples marcos, subsistemas o componentes en un entorno para resolver múltiples problemas.

Finalmente, hay servicios, a menudo implementados como servicios web o de red. Estas son arquitecturas, marcos, pilas de soluciones o capacidades de aplicación entregadas como paquetes completos. Sus componentes internos son a menudo opacos, exponiendo principalmente las interfaces de administrador, programación e usuario. PaaS y SaaS son ejemplos comunes.

Ahora, esta progresión puede no ser del todo satisfactoria, por algunas razones. Primero, hace una ordenada progresión lineal o jerarquía de cosas que no son perfectamente lineales o jerárquicas. Cubre algunas abstracciones como "pilas" y servicios que no están completamente bajo el control del desarrollador. Y no plantea ningún nuevo polvo mágico de duendes. (Spoiler: no hay polvo mágico de duendes ) .

Creo que es un error buscar solo nuevos niveles de abstracción . Todos los que enumeré anteriormente han existido durante años , incluso si no han sido tan prominentes o populares como lo son ahora. Y durante esos años, las abstracciones posibles en todos los niveles de codificación han mejorado. Ahora tenemos colecciones genéricas de uso general, no solo matrices. Recorremos las colecciones, no solo los rangos de índice. Tenemos comprensiones de listas y filtros de listas y operaciones de mapas. Las funciones de muchos idiomas pueden tener un número variable de argumentos y / o argumentos predeterminados. Y así. Estamos aumentando la abstracción en todos los niveles, por lo que agregar más niveles no es un requisito para aumentar el nivel general de abstracción.

Jonathan Eunice
fuente
1

La siguiente abstracción después de las clases son metaclases . Es así de simple ;)

una clase cuyas instancias son clases. Así como una clase ordinaria define el comportamiento de ciertos objetos, una metaclase define el comportamiento de ciertas clases y sus instancias. No todos los lenguajes de programación orientados a objetos admiten metaclases. Entre los que lo hacen, la medida en que las metaclases pueden anular cualquier aspecto dado del comportamiento de la clase varía. Cada idioma tiene su propio protocolo de metaobjetos, un conjunto de reglas que gobiernan cómo interactúan los objetos, las clases y las metaclases ...

Sebastian Bauer
fuente
1
Las metaclases son los objetos raíz de la (s) jerarquía (s) de herencia del lenguaje. .NET es objeto. También puede pensar en las interfaces como metaclases; definen la interfaz de sus herederos independientemente de la clase "padre" real del heredero.
KeithS
1
@KeithS eso no es lo que significa la palabra en ningún contexto que la haya visto, desde CLOS a UML a C #. Una metaclase es una clase cuyas instancias son clases: una implementación débil es C # 's, Typeque brinda capacidades reflexivas pero no mutación (no se puede agregar un nuevo método al MyTypedecir lo typeof(MyType).Methods += new Method ( "Foo", (int x)=>x*x )que se puede hacer en CLOS)
Pete Kirkham
1

Me sorprende que nadie haya mencionado la teoría de categorías.

La unidad de programación más fundamental es la función que se basa en tipos. Las funciones generalmente se denotan como f: A -> B, donde A y B son tipos. Si pones estas cosas, a las que llamo tipos y funciones, juntas de la manera correcta obtienes algo llamado categoría. No tienes que parar en este punto.

Tome estas cosas, categorías y pregúntese cuál sería la forma correcta de relacionarlas entre sí. Si lo haces bien, obtienes algo llamado functor que va entre dos categorías y generalmente se denota como F: C -> B. Una vez más, no tienes que detenerte.

Puede tomar todos los functores y juntarlos de la manera correcta y, si hace las cosas bien, comienza a preguntarse cómo relacionar dos functores entre sí. En este punto, obtienes algo llamado transformación natural, mu: F -> G, donde F y G son functores.

Mi conocimiento en este punto se vuelve borroso, pero puedes seguir haciendo esto y seguir subiendo la escalera de la abstracción. Los objetos y las clases ni siquiera se acercan a describir qué tan alto puedes subir la escalera de abstracción. Hay muchos idiomas que pueden expresar los conceptos anteriores computacionalmente y el más destacado de esos idiomas es Haskell. Entonces, si realmente quieres saber de qué se trata la abstracción, entonces aprende algo de Haskell o Agda o HOL o ML.

davidk01
fuente
1

Creo que el modelo de actor falta en la lista de candidatos.

Esto es lo que quiero decir con actores:

  • entidades independientes
  • que reciben mensajes, y cuando reciben un mensaje, pueden
  • crear nuevos actores,
  • actualizar algún estado interno para el siguiente mensaje,
  • y enviar mensajes

Este modelo es algo más allá de las máquinas deterministas de Turing, y en realidad está más cerca de nuestro hardware del mundo real cuando se miran programas concurrentes. A menos que emplee pasos de sincronización adicionales (costosos), en estos días, cuando su código recibe datos, ese valor ya puede haber cambiado en el otro lado del mismo dado, tal vez incluso dentro del mismo núcleo.

Breve discusión / introducción: http://youtube.com/watch?v=7erJ1DV_Tlo

Christopher Creutzig
fuente
su publicación es bastante difícil de leer (muro de texto). Te importaría editarlo en una mejor forma?
mosquito
0

Si te entiendo correctamente, tus "abstracciones ascendentes" pueden considerarse como encapsulaciones lógicas cada vez más grandes, relacionadas principalmente con la reutilización de código.

De específico instrucciones ejecutadas una tras otra, pasamos a funciones / subrutinas , que encapsulan, o resumen, una agrupación lógica de instrucciones en un solo elemento. Luego tenemos objetos , o módulos , que encapsulan subrutinas relacionadas con una determinada entidad lógica o categoría, por lo que puedo agrupar todas las operaciones de cadena en la Stringclase, o todas las operaciones matemáticas comunes en laMath módulo (o clase estática, en lenguajes como C #) .

Entonces, si esa es nuestra progresión, ¿qué viene después? Bueno, no creo que tengas el siguiente paso claro. Como otros han respondido, su progresión se aplica solo a los estilos de programación imperativa / procesal, y otros paradigmas no comparten sus conceptos de abstracción. Pero si hay algo que puede extender lógicamente su metáfora, son los servicios .

Un servicio es similar a una clase en el sentido de que es una entidad que expone la funcionalidad, pero implica una separación de preocupaciones mucho más estricta que el ir y venir con los objetos que usted creó. Exponen un conjunto limitado de operaciones, ocultan la lógica interna y ni siquiera se ejecutan necesariamente en la misma máquina.

De nuevo, hay una buena distinción. En la mayoría de los casos, usará un objeto que actúa como proxy de un servicio , y los dos serán muy similares, pero como arquitectura, los dos son distintos.

Avner Shahar-Kashtan
fuente
0

Nuevas formas de abstracción te ocultan el trabajo de bajo nivel. Los procedimientos y funciones con nombre le ocultan las direcciones del programa. Los objetos ocultan la gestión dinámica de la memoria y algunas "declaraciones if" dependientes del tipo.

Sugeriría que el siguiente nivel de abstracciones prácticas que te ocultarán la carga de trabajo de bajo nivel son las de la programación reactiva funcional . Mira las "señales" en algo como http://elm-lang.org/ que oculta las devoluciones de llamada y actualiza las dependencias que tendría que administrar explícitamente en javascript. FRP puede ocultar gran parte de la complejidad de la comunicación entre procesos y entre máquinas que se necesita en aplicaciones de Internet a gran escala y el paralelismo de alto rendimiento también.

Estoy bastante seguro de que esto es lo que nos va a entusiasmar a todos en los próximos 5 años más o menos.

interestar
fuente
1
FRP es excelente, pero se trata de un tipo de programación bastante específico (es decir, programación reactiva ). No es muy bueno para modelar otro tipo de programas. Sin embargo, el tipo de programación más general que representa, escribir su código en términos de álgebras, es un buen candidato para un nuevo nivel de abstracción.
Tikhon Jelvis
0

La teoría de conjuntos, como se implementa parcialmente en bases de datos relacionales, pero también en lenguajes de estadísticas como SAS y R, proporciona un nivel de abstracción diferente pero posiblemente más alto que OO.

James Anderson
fuente