Un paradigma de programación es una forma relativamente de alto nivel de conceptualizar y estructurar la implementación de un programa informático . Un lenguaje de programación puede clasificarse como compatible con uno o más paradigmas. [1]
Los paradigmas se dividen y describen en diferentes dimensiones de la programación. Algunos paradigmas tratan sobre las implicaciones del modelo de ejecución , como permitir efectos secundarios o si la secuencia de operaciones está definida por el modelo de ejecución. Otros paradigmas tratan sobre la forma en que se organiza el código, como agruparlo en unidades que incluyen tanto el estado como el comportamiento. Otros paradigmas tratan sobre la sintaxis y la gramática .
Algunos paradigmas de programación comunes incluyen (mostrados en relación jerárquica): [2] [3] [4]
Los paradigmas de programación surgen de la investigación en ciencias de la computación sobre las prácticas existentes de desarrollo de software . Los hallazgos permiten describir y comparar las prácticas de programación y los lenguajes utilizados para codificar programas. Para tener una perspectiva, otras investigaciones estudian los procesos de ingeniería de software y describen varias metodologías para describirlos y compararlos.
Un lenguaje de programación se puede describir en términos de paradigmas. Algunos lenguajes admiten solo un paradigma. Por ejemplo, Smalltalk admite el paradigma orientado a objetos y Haskell admite el paradigma funcional. La mayoría de los lenguajes admiten varios paradigmas. Por ejemplo, un programa escrito en C++ , Object Pascal o PHP puede ser puramente procedimental , puramente orientado a objetos o puede contener aspectos de ambos paradigmas u otros.
Al utilizar un lenguaje que admite múltiples paradigmas, el desarrollador elige qué elementos del paradigma utilizar. Sin embargo, esta elección puede no implicar la consideración de los paradigmas en sí. El desarrollador suele utilizar las características de un lenguaje tal como las proporciona el lenguaje y en la medida en que las conoce. La categorización del código resultante por paradigma suele ser una actividad académica que se realiza en retrospectiva.
Los lenguajes categorizados como paradigmáticos imperativos tienen dos características principales: establecen el orden en el que ocurren las operaciones, con construcciones que controlan explícitamente ese orden, y permiten efectos secundarios, en los que el estado puede modificarse en un momento dado, dentro de una unidad de código, y luego leerse en un momento distinto dentro de una unidad de código diferente. La comunicación entre las unidades de código no es explícita.
Por el contrario, los lenguajes del paradigma declarativo no indican el orden en el que se deben ejecutar las operaciones. En cambio, proporcionan una cantidad de operaciones disponibles en el sistema, junto con las condiciones en las que se permite ejecutar cada una de ellas. [7] La implementación del modelo de ejecución del lenguaje rastrea qué operaciones se pueden ejecutar libremente y elige el orden de forma independiente. Más información en Comparación de lenguajes de programación multiparadigma .
En la programación orientada a objetos , el código se organiza en objetos que contienen un estado que pertenece y (normalmente) controla el código del objeto. La mayoría de los lenguajes orientados a objetos también son lenguajes imperativos.
En la programación orientada a objetos, los programas se tratan como un conjunto de objetos que interactúan. En la programación funcional , los programas se tratan como una secuencia de evaluaciones de funciones sin estado. Al programar computadoras o sistemas con muchos procesadores, en la programación orientada a procesos , los programas se tratan como conjuntos de procesos concurrentes que actúan sobre estructuras de datos compartidas lógicas .
Muchos paradigmas de programación son tan conocidos por las técnicas que prohíben como por las que apoyan . Por ejemplo, la programación funcional pura no permite efectos secundarios , mientras que la programación estructurada no permite la construcción goto . En parte por esta razón, los nuevos paradigmas suelen ser considerados doctrinarios o demasiado rígidos por aquellos acostumbrados a los más antiguos. [8] Sin embargo, evitar ciertas técnicas puede hacer que sea más fácil comprender el comportamiento del programa y demostrar teoremas sobre la corrección del programa.
Los paradigmas de programación también se pueden comparar con los modelos de programación , que permiten invocar un modelo de ejecución utilizando únicamente una API. Los modelos de programación también se pueden clasificar en paradigmas según las características del modelo de ejecución.
Para la computación paralela , es común usar un modelo de programación en lugar de un lenguaje. La razón es que los detalles del hardware paralelo se filtran en las abstracciones utilizadas para programar el hardware. Esto hace que el programador tenga que mapear patrones en el algoritmo sobre patrones en el modelo de ejecución (que se han insertado debido a la fuga de hardware en la abstracción). Como consecuencia, ningún lenguaje de programación paralela se adapta bien a todos los problemas de computación. Por lo tanto, es más conveniente usar un lenguaje secuencial base e insertar llamadas API a modelos de ejecución paralela a través de un modelo de programación. Dichos modelos de programación paralela se pueden clasificar de acuerdo con abstracciones que reflejan el hardware, como memoria compartida , memoria distribuida con paso de mensajes , nociones de lugar visible en el código, etc. Estos pueden considerarse sabores del paradigma de programación que se aplican solo a lenguajes paralelos y modelos de programación.
Algunos investigadores de lenguajes de programación critican la noción de paradigmas como una clasificación de lenguajes de programación, por ejemplo, Harper, [9] y Krishnamurthi. [10] Argumentan que muchos lenguajes de programación no pueden clasificarse estrictamente en un paradigma, sino que incluyen características de varios paradigmas. Véase Comparación de lenguajes de programación multiparadigma .
Con el tiempo se han desarrollado diferentes enfoques de programación. La clasificación de cada enfoque se describió en el momento en que se desarrolló por primera vez, pero a menudo no hasta algún tiempo después, de forma retrospectiva. Un enfoque temprano identificado conscientemente como tal es la programación estructurada , defendida desde mediados de la década de 1960. El concepto de un paradigma de programación como tal data al menos de 1978, en la conferencia del Premio Turing de Robert W. Floyd , titulada Los paradigmas de la programación , que cita la noción de paradigma utilizada por Thomas Kuhn en su La estructura de las revoluciones científicas (1962). [11] Los primeros lenguajes de programación no tenían paradigmas de programación claramente definidos y, a veces, los programas hacían un uso extensivo de declaraciones goto. El uso liberal de las cuales condujo a un código espagueti que es difícil de entender y mantener. Esto condujo al desarrollo de paradigmas de programación estructurada que prohibían el uso de declaraciones goto; solo permitían el uso de construcciones de programación más estructuradas. [12]
El código de máquina es el nivel más bajo de programación informática, ya que son instrucciones de máquina que definen el comportamiento en el nivel más bajo de abstracción posible para una computadora. Como es la forma más prescriptiva de codificar, se clasifica como imperativo.
A veces se le llama el lenguaje de programación de primera generación .
El lenguaje ensamblador introdujo mnemónicos para instrucciones de máquina y direcciones de memoria . El lenguaje ensamblador se clasifica como imperativo y a veces se lo denomina lenguaje de programación de segunda generación .
En la década de 1960, se desarrollaron lenguajes ensambladores para soportar la biblioteca COPY y capacidades bastante sofisticadas de generación y preprocesamiento de macros condicionales, CALL a subrutinas , variables externas y secciones comunes (globales), lo que permitió una reutilización significativa del código y el aislamiento de las especificaciones del hardware mediante el uso de operadores lógicos como READ/WRITE/GET/PUT. El lenguaje ensamblador se utilizó, y todavía se utiliza, para sistemas críticos en cuanto al tiempo y, a menudo, en sistemas integrados , ya que brinda el mayor control sobre lo que hace la máquina.
Los lenguajes procedimentales , también llamados lenguajes de programación de tercera generación , son los primeros que se describen como lenguajes de alto nivel . Admiten vocabulario relacionado con el problema que se está resolviendo. Por ejemplo,
Estos lenguajes se clasifican como paradigmas procedimentales. Controlan directamente el proceso paso a paso que sigue un programa informático. Por tanto, la eficacia y eficiencia de un programa de este tipo depende en gran medida de la habilidad del programador.
En un intento de mejorar los lenguajes procedimentales, se crearon lenguajes de programación orientada a objetos (OOP), como Simula , Smalltalk , C++ , Eiffel , Python , PHP , Java y C# . En estos lenguajes, los datos y los métodos para manipularlos se encuentran en la misma unidad de código llamada objeto . Esta encapsulación garantiza que la única forma en que un objeto puede acceder a los datos es a través de los métodos del objeto que contiene los datos. Por lo tanto, el funcionamiento interno de un objeto se puede cambiar sin afectar el código que utiliza el objeto.
Existe una controversia planteada por Alexander Stepanov , Richard Stallman [13] y otros programadores, en relación con la eficacia del paradigma OOP frente al paradigma procedimental. La necesidad de que cada objeto tenga métodos asociativos lleva a algunos escépticos a asociar la OOP con la hinchazón del software ; un intento de resolver este dilema llegó a través del polimorfismo .
Aunque la mayoría de los lenguajes OOP son de tercera generación, es posible crear un lenguaje ensamblador orientado a objetos. High Level Assembly (HLA) es un ejemplo de esto que admite plenamente tipos de datos avanzados y programación en lenguaje ensamblador orientado a objetos, a pesar de sus orígenes tempranos. Por lo tanto, los diferentes paradigmas de programación pueden verse más bien como memes motivacionales de sus defensores, en lugar de representar necesariamente un progreso de un nivel al siguiente. [ cita requerida ] Las comparaciones precisas de la eficacia de los paradigmas en competencia se vuelven frecuentemente más difíciles debido a la terminología nueva y diferente que se aplica a entidades y procesos similares junto con numerosas distinciones de implementación entre lenguajes.
Un programa de programación declarativa describe cuál es el problema, no cómo resolverlo. El programa está estructurado como un conjunto de propiedades a encontrar en el resultado esperado, no como un procedimiento a seguir. Dada una base de datos o un conjunto de reglas, la computadora intenta encontrar una solución que coincida con todas las propiedades deseadas. Un arquetipo de un lenguaje declarativo es el lenguaje de cuarta generación SQL , y la familia de lenguajes funcionales y de programación lógica.
La programación funcional es un subconjunto de la programación declarativa. Los programas escritos con este paradigma utilizan funciones , bloques de código que se comportan como funciones matemáticas . Los lenguajes funcionales desalientan los cambios en el valor de las variables mediante la asignación , haciendo un gran uso de la recursión en su lugar.
El paradigma de programación lógica considera la computación como un razonamiento automatizado sobre un conjunto de conocimientos. Los hechos sobre el dominio del problema se expresan como fórmulas lógicas y los programas se ejecutan aplicando reglas de inferencia sobre ellos hasta que se encuentra una respuesta al problema o se demuestra que el conjunto de fórmulas es inconsistente.
La programación simbólica es un paradigma que describe programas capaces de manipular fórmulas y componentes de programas como datos. [4] De este modo, los programas pueden modificarse a sí mismos de forma eficaz y parecer que "aprenden", lo que los hace adecuados para aplicaciones como la inteligencia artificial , los sistemas expertos , el procesamiento del lenguaje natural y los juegos de ordenador. Los lenguajes que admiten este paradigma incluyen Lisp y Prolog . [14]
La programación diferenciable estructura los programas de manera que puedan diferenciarse en su totalidad, generalmente mediante diferenciación automática . [15] [16]
La programación alfabetizada , como una forma de programación imperativa , estructura los programas como una red centrada en el ser humano, como en un ensayo de hipertexto : la documentación es parte integral del programa, y el programa está estructurado siguiendo la lógica de la exposición en prosa, en lugar de la conveniencia del compilador.
Las técnicas simbólicas como la reflexión , que permiten que el programa se refiera a sí mismo, también podrían considerarse un paradigma de programación. Sin embargo, esto es compatible con los paradigmas principales y, por lo tanto, no es un paradigma real en sí mismo.