Paradigmas de la Computación
Fundamentos de Computación II
INTRODUCCIÓN
Lenguaje natural: es el lenguaje en el que se comunican las personas a través del habla y la
escritura.
Lenguajes de programación: son diseñados y se pueden implementar en computadoras.
No pueden ser comparados con los lenguajes naturales en términos de expresividad y
subjetividad. Deben describirse de manera formal, completa y precisa independiente de la
máquina y de la implementación.
La evolución continua y rápida de los Lenguajes de Programación, obliga cada cierto tiempo a
realizar un reajuste en los Lenguajes.
No existe un camino o método para decidir cuándo reemplazar una tecnología por otra,
muchas veces es la moda, de ahí la importancia de comparar punto por punto los diferentes
tipos de Lenguajes de Programación de acuerdo al paradigma de programación al que
pertenecen.
DEFINICIÓN DE LENGUAJE DE PROGRAMACIÓN
“Es un sistema notacional para describir computaciones en una forma legible tanto
para la máquina como para el ser humano.”
Computación:
✓La computación incluye todo tipo de operaciones de computadora.
✓Un lenguaje de programación es un idioma artificial diseñado para expresar
computaciones que pueden ser llevadas a cabo por máquinas como las computadoras.
✓ Pueden usarse para crear programas que controlen el comportamiento físico y
lógico de una máquina, para expresar algoritmos con precisión, o como modo de
comunicación humana.
✓Está formado por un conjunto de símbolos y reglas sintácticas y semánticas que
definen su estructura y el significado de sus elementos y expresiones.
Programación:
Es el proceso por el cual se escribe, se prueba, se depura, se compila y se mantiene el
código fuente de un programa informático.
Un programa se escribe en un lenguaje de programación y las operaciones que llevan
a expresar un algoritmo en forma de programa se llaman programación o código
fuente.
Características de los lenguajes de programación:
✓ El lenguaje de programación debe ser universal: cualquier problema debe tener una
solución que puede ser programada en el lenguaje y dicha solución ser
implementada en cualquier computador.
✓ El lenguaje de programación debe ser implementable en una computadora, es
decir: debe ser posible ejecutar un programa en términos del lenguaje en cualquier
máquina.
La notación matemática generalmente no es implementable porque en su notación es
posible formular problemas que no pueden ser resueltos por cualquier computadora.
Los lenguajes naturales tampoco son implementables por razones totalmente
diferentes: ellos son imprecisos y tienden a ser ambiguos.
La definición del lenguaje se puede dividir en 2 partes:
1) Sintaxis ( estructura)
2) Semántica (significado)
Sintaxis:
Ejemplo:
<enunciado if> ::= if (<expresión>) <enunciado> [else <enunciado>]
Semántica:
Es más difícil de describir con precisión. La semántica expresa los efectos de la
ejecución en un contexto determinado. A veces esta definición interactúa con los
significados de otros elementos del lenguaje, y por ello, la semántica es la parte mas
difícil en la definición de un lenguaje.
Ejemplo:
Un enunciado if es ejecutado, primero, evaluando su expresión, la misma que debe
tener tipo aritmético o apuntador, incluyendo todos los efectos colaterales, y si se
compara diferente de 0, el enunciado que sigue a la expresión es ejecutada. Si existe
una parte else, y la expresión es 0, el enunciado que sigue al “else” es ejecutado.
Cuando se escriben las sentencias es necesario controlar la seguridad de las mismas.
En el ejemplo del if:
¿qué ocurre si la expresión no se evalúa correctamente a cierto o falso, porque hay un
error de división por cero?
Los lenguajes de programación constan de:
✓Un conjunto finito de símbolos, a partir del cual se define el léxico o vocabulario del
lenguaje.
✓Un conjunto finito de reglas, la gramática del lenguaje (sintaxis) , para la construcción
de las sentencias “correctas” del lenguaje.
✓Semántica, que asocia un significado, la acción que debe llevarse a cabo, a cada posible
construcción del lenguaje.
ANTECEDENTES DE LOS LENGUAJES DE PROGRAMACIÓN
Durante el florecimiento griego de las Matemáticas, se tuvo el concepto de algoritmo, que
es el antecedente de los Lenguajes de Programación, como una secuencia de pasos
lógicos para resolver un problema.
Las primeras computadoras fueron construidas en el año 1940 por John Von Neumann.
A principios de los años 50, aparecen las computadoras digitales de uso general.
Los primeros programas fueron escritos en códigos de máquina, originándose el lenguaje
ASSEMBLER, que es muy dependiente de la máquina, conocido como un Lenguaje de bajo
nivel.
Entre 1954 y 1957 fue desarrollado el FORTRAN por un equipo de IBM, con uso científico.
La supervivencia del Fortran se debe, parcialmente, a que los compiladores son muy
eficientes, y producen código muy rápido.
Entre sus características tenemos la implementación de los siguientes conceptos: Arreglo
o matriz, if ramificado.
Entre 1959 y 1960 aparece COBOL, que fue desarrollado por el Departamento de
Defensa de Estados Unidos, tuvo un uso comercial: Bancos, Empresas.
En Cobol resulta difícil de programar los algoritmos complejos.
Las características en las que Cobol fue pionero son: uso de estructura de registro, la
separación de las estructuras de datos de la sección de ejecución.
En 1960, se crea el Lenguaje ALGOL60, con el objetivo de proporcionar un lenguaje
para la descripción de los algoritmos. La mayoría de los lenguajes imperativos actuales
son derivados de Algol: Pascal, C y Ada.
Algol60 introdujo conceptos como: bloques de inicio y fin, declaraciones de tipo para
las variables, recursión y paso de parámetros por valor.
Al mismo tiempo que se creaban estos 3 lenguajes se estaban desarrollando otros
lenguajes con base en el concepto matemático de Función. Dos ejemplos importantes
son LISP y APL.
A fines de los años 50 se diseña el LISP por John McCarthy, introdujo el concepto
“recolección de basura”, es decir recuperación automática de la memoria no utilizada,
que es muy diferente a la arquitectura de Von Neumann, por lo que se desarrolló una
máquina para ejecutar programas LISP.
En los años 60 se produce una explosión de lenguajes de programación:
ALGOL, BASIC, CLIP, MATHLAB, PL/1, UNICODE.etc.
El lenguaje BASIC, diseñado en 1964, fue creado con el objetivo de ser un lenguaje
simple para los nuevos sistemas de tiempo compartido.
En 1971 se creó el PASCAL, como un lenguaje pequeño, simple, estructurado que se
pretendía utilizar en la enseñanza de la programación.
A principios de 1972, se desarrolló el PROLOG, como un ejemplo de la programación
lógica.
En 1972, Dennins Ritchie diseñó en los laboratorios Bell, el lenguaje C. El éxito de C se
debe en parte a la popularidad del sistema operativo Unix.
En los años 80 se desarrolló el ADA, sigue en uso, pues es un lenguaje importante e
influyente debido a su cuidadoso diseño.
A partir de 1980 se desarrolló el C++ en los laboratorios Bell.
Se le han agregado una enorme cantidad de Bibliotecas, ha sido transportado
virtualmente a todas las plataformas. Se ha convertido en un lenguaje muy grande, difícil
de implementar.
En 1995 apareció JAVA, lenguaje orientado a objetos, para aplicaciones de internet y de
redes. Tiene la ventaja de ser relativamente simple, limpiamente diseñado y provisto de
una gran biblioteca de herramientas para ventanas.
En los años 90 aparece el lenguaje funcional HASKELL.
La tendencia será a que los lenguajes de programación deben ser principalmente
declarativos y no imperativos.
Es muy importante para el éxito de un Lenguaje de programación la necesidad de una
biblioteca, escrita de manera independiente al sistema bien integrada en el lenguaje
mismo. Java sin el API (conjunto de bibliotecas) hubiera sido “simplemente otro
lenguaje”.
C++ también tiene una biblioteca con herramientas, aunque no los sistemas de ventanas
y de redes de JAVA.
La evolución de los lenguajes de programación se ha organizado en cinco generaciones:
1. En la primera generación se incluyen los lenguajes máquina, en los que los datos y las
operaciones sobre ellos se describen mediante ceros y unos. Son códigos o notaciones
muy difíciles de entender por los programadores y cada procesador tiene el suyo
propio .
Ejemplo: el byte 01111000 le dice al procesador Z80 de Zilog (microprocesador de 8 bits)
que copie en el registro A el contenido del registro B.
1. La segunda generación es la que incluye a los lenguajes ensambladores, cuya
traducción a lenguaje máquina es muy sencilla, y aún hoy se utilizan para tareas muy
específicas, como puede ser para programar drivers para dispositivos.
Ejemplo: el byte 01111000 se representa mediante el mnemónico “LD A,B”, que es más
sencillo de recordar .
EVOLUCIÓN
3. La tercera generación es la que incluye a los lenguajes de alto nivel como Pascal,
Fortran, C o Java.
Se denominan de alto nivel porque están muy alejados de la máquina pero muy cercanos a
los programadores.
Para su traducción a lenguaje máquina se necesitan compiladores o intérpretes.
Surgen alrededor de los años 60 siendo los primeros Fortran, Lisp, Algol y Cobol.
4. La cuarta generación agrupa a lenguajes de propósito específico, como SQL,
Natural, o el del paquete estadístico SPSS que permite manipular grandes cantidades
de datos con fines estadísticos.
5. La quinta generación incluye lenguajes que se utilizan, en primer lugar, en el área
de la Inteligencia Artificial, con los que se especifica mas qué problema hay que
resolver que cómo se resuelve dicho problema con una secuencia de acciones.
De los primeros que se incluyen en este grupo es el lenguaje Prolog, aunque otros
lenguajes funcionales como Haskell, también se clasifican como de quinta generación.
Para grandes desarrollos en los que intervienen varios programadores, un lenguaje de
programación se convierte en una parte de un entorno de desarrollo de software, que
obliga a utilizar una metodología de desarrollo que permita comprender el programa
como un todo e identificar fácilmente qué efecto produciría un cambio local.
Los entornos, por lo tanto, se convierten en un conjunto de herramientas para la
escritura y traducción de los programas, para manipular los archivos del programa,
registrar cambios y realizar pruebas y análisis.
Los entornos de programación son el objeto de la ingeniería del software.
Entornos de Programación
El estudio de los paradigmas de los lenguajes de programación es tan importante
para el programador, como lo es dominar unos lenguajes concretos, ya que este
conocimiento va a permitir saber qué lenguaje es el más adecuado para cada tipo de
escenario y cada problema a resolver.
PARADIGMAS DE LA PROGRAMACIÓN
Un paradigma de programación es un modelo básico de diseño y desarrollo de programas,
que permite producir programas con unas directrices específicas, tales como: estructura
modular, fuerte cohesión, alta rentabilidad, etc.
¿Qué es un Paradigma?
Para algunos puede resultar sorprendente que existan varios paradigmas de
programación.
La mayor parte de los programadores están familiarizados con un único paradigma, el
de la programación procedimental.
Sin embargo hay multitud de ellos atendiendo a alguna particularidad metodológica o
funcional, como por ejemplo:
✓ el basado en reglas de gran aplicación en la ingeniería del conocimiento para el
desarrollo de sistemas expertos, en que el núcleo del mismo son las reglas de
producción del tipo "if then";
✓ el de programación lógica, basado en asertos y reglas lógicas que define un entorno
de programación de tipo conversacional, deductivo, simbólico y no determinista;
¿Cuántos paradigmas hay?
✓ el de programación funcional, basado en funciones y mecanismos para aplicar
argumentos, que define un entorno de programación interpretativo, funcional y aplicativo.
✓ el de programación heurística que aplica para la resolución de los problemas "reglas de
buena lógica" pueden ser correctas aunque no se garantiza su éxito, modelizando el
problema de una forma adecuada para aplicar estas heurísticas atendiendo a su
representación, estrategias de búsqueda y métodos de resolución.
✓ el de programación paralela; el basado en restricciones; el basado en el flujo de datos; el
orientado al objeto, etc.
Un paradigma de programación es una colección de modelos conceptuales que juntos
modelan el proceso de diseño y determinan, al final, la estructura de un programa.
Entonces, un paradigma es…
Tipos de paradigmas. Categorías
Teniendo en cuenta la solución que aportan para resolver el problema se agrupan en tres
categorías :
a) Solución procedimental u operacional. Describe etapa a etapa el modo de construir la
solución. Es decir señala la forma de obtener la solución.
b) Solución declarativa. Señala las características que debe tener la solución, sin describir
cómo procesarla. Es decir señala qué se desea obtener pero no cómo obtenerlo.
c) Solución demostrativa. Es una variante de la procedimental. Especifica la solución
describiendo ejemplos y permitiendo que el sistema generalice la solución de estos
ejemplos para otros casos. Aunque es fundamentalmente procedimental, el hecho de
producir resultados muy diferentes a ésta, hace que sea tratada como una categoría
separada.
La característica fundamental de estos paradigmas es la secuencia computacional realizada
etapa a etapa para resolver el problema.
Su mayor dificultad reside en determinar si el valor computado es una solución correcta del
problema, por lo que se han desarrollado multitud de técnicas de depuración y verificación
para probar la corrección de los problemas desarrollados basándose en este tipo de
paradigmas.
Paradigmas procedimentales u operacionales
Existen dos tipos de paradigmas con efectos de lado:
✓el imperativo
✓el orientado a objetos
El paradigma por procedimientos, es tal vez el más conocido y utilizado en el proceso de
programación, donde los programas se desarrollan a través de procedimientos.
Pascal, C y BASIC son tres de los lenguajes imperativos más importantes.
La palabra del latín “imperare” significa "dar instrucciones".
El paradigma se inició al principio del año 1950 cuando los diseñadores reconocieron que
las variables y los comandos o instrucciones de asignación constituían una simple pero útil
abstracción del acceso a memoria y actualización del conjunto de instrucciones máquina.
Este paradigma se caracteriza por un modelo abstracto de ordenador que consiste en un gran
almacenamiento de memoria.
El ordenador almacena una representación codificada de un cálculo y ejecuta una secuencia
de comandos que modifican el contenido de ese almacenamiento. Este paradigma viene bien
representado por la arquitectura Von Newman (1903-1957), ya que utiliza este modelo de
máquina para conceptualizar las soluciones: "Existe un programa en memoria que se va
ejecutando secuencialmente, y que toma unos datos de la memoria, efectúa unos cálculos y
actualiza la memoria“.
La programación en el paradigma imperativo consiste en determinar qué datos son
requeridos para el cálculo, asociar a esos datos unas direcciones de memoria, y efectuar paso
a paso una secuencia de transformaciones en los datos almacenados, de forma que el estado
final represente el resultado correcto.
Paradigma imperativo
En su forma pura este paradigma sólo soporta sentencias simples que modifican la
memoria y efectúan bifurcaciones condicionales e incondicionales. Incluso cuando se
añade una forma simple de abstracción procedimental, el modelo permanece básicamente
sin cambiar. Los parámetros de los procedimientos son "alias" de las zonas de memoria,
por lo que pueden alterar su valor, y no retorna ningún tipo de cálculo. La memoria
también se puede actualizar directamente mediante referencias globales.
El paradigma imperativo debe su nombre al papel dominante que desempeñan las
sentencias imperativas. Su esencia es el cálculo iterativo, paso a paso, de valores de nivel
inferior y su asignación a posiciones de memoria.
Si se analizan las características fundamentales de este tipo de paradigma se detectan
las siguientes:
✓ Concepto de celda de memoria ("variable") para almacenar valores.
El componente principal de la arquitectura es la memoria, compuesto por un gran
número de celdas donde se almacenan los datos. Las celdas tienen nombre (concepto
de variable) que las referencian.
✓ Operaciones de asignación. Estrechamente ligado a la arquitectura de la memoria, se
encuentra la idea de que cada valor calculado debe ser "almacenado", es decir asignado
a una celda. Esta es la razón de la importancia de la sentencia de asignación en el
paradigma imperativo. Las nociones de celda de memoria y asignación en bajo nivel, se
tienden a todos los lenguajes de programación y fuerzan en los programadores un estilo
de pensamiento basado en la arquitectura Von Neumann.
✓Repetición. Un programa imperativo, normalmente realiza su tarea ejecutando
repetidamente una secuencia de pasos elementales, ya que en este modelo computacional
la única forma de ejecutar algo complejo es repitiendo una secuencia de instrucciones.
✓A este tipo de paradigma de programación se le suele llamar algorítmico, dado que el
significado de algoritmo es análogo al de receta, método, técnica, procedimiento o rutina, y
se define como "un conjunto finito de reglas diseñadas para crear una secuencia de
operaciones para resolver un tipo específico de problemas".
Algoritmos + Estructura de Datos = Programas
Ejemplo:
El cálculo imperativo del máximo común divisor. Posee variables enteras, aritméticas
enteras y ejecuta instrucciones secuencialmente, incluyendo asignaciones, selecciones y
ciclos como el while.
Números Primos (Pascal)
(* Genera números primos en el rango 2..n, utilizando la criba de Eratóstenes *)
Program primos(input, output);
Const n=50;Var i: 2..n;j: 2..25;iprimo: boolean;
Begin
for i:=2 to n do
Begin (* ¿ Es primo i ? *)j:=2; iprimo:=true;While iprimo and (j<=i div 2) doif ( (i mod j) <>0)then j:=j+1 else iprimo:=false;(* Si es primo imprime su valor *)if iprimo then write (i:3)
EndEnd.
En este programa se destacan las tres
características principales del
paradigma imperativo:
•Celdas de memoria: declaraciones
de var (i,j, primo)
•Operaciones de asignación de tipo
destructivo: j:=2, iprimo:=true, ..
•Sentencias repetitivas: for y while
Ejemplo 1
Ordenar (C)/* Ordena un conjunto de datos leídos desde el dispositivo de entrada, utilizando el método de la burbuja */
#include <stdio.h>void ordenar (int *, int);void escribir (int *, int);int main( ){int n=0, dato;int a[50];scanf("%d", &dato);while(dato != EOF);a[n++] = dato;scanf("%d",&dato); }ordenar(a,n-1);escribir(a,n-1);}/* función ordenar */void ordenar (int a[ ], int n){ int i,j, tem;for (i=0; i<n; y++)for (j=i+1; j<=n; j++)if (a[i]>a[j]){tem = a[i];a[i]=a[j];a[j]=tem;}}void escribir (int a[ ], int n){int i;for (y=0; i<n; y++){if (!(i % 10)) printf ("\n");printf("% 5d", a[i]);}}
La función ordenar compara parejas
de datos contiguos e intercambia su
contenido si el primero es mayor que
el segundo. Y en cada iteración de la
variable j, coloca en la cabeza de la
lista que está ordenando el dato
menor (la burbuja más ligera)
En este ejemplo, al igual que en
anterior predominan los tres
componentes descritos del
paradigma imperativo.
Ejemplo 2
El paradigma orientado a objetos
✓Es el paradigma de programación más utilizado en el mundo del desarrollo de software en
el siglo XXI. Se basa en los conceptos de objetos y clases de objetos.
✓Utilizan código reutilizable, extensión del paradigma imperativo: java, C++
✓la POO enfatiza en los datos al contrario de la programación procedimental que enfatiza
en los algoritmos.
✓La idea fundamental es combinar en una única unidad o módulo, tanto los datos como las
funciones que operan sobre esos datos. Tal unidad se llama un objeto.
✓No se puede acceder a los datos directamente, sino a través de los métodos. Los datos
son ocultos, de modo que están protegidos de alteraciones accidentales.
✓Los datos y las funciones se dice que están encapsulados en una única entidad. El
encapsulamiento de datos y la ocultación de los datos son términos clave en la descripción
de lenguajes orientados a objetos.
• Abstracción (tipos abstractos de datos y clases).
• Encapsulado de datos.
• Ocultación de datos.
• Herencia.
• Polimorfismo.
C++ a pesar de que soporta todas las características anteriores que definen la orientación
a objetos, no es un lenguaje orientado a objetos puro.
C++ soporta orientación a objetos pero es compatible con C y permite que programas C++
se escriban sin utilizar características orientadas a objetos.
Propiedades
Alrededor de 1970 David Parnas planteó el ocultamiento de la información como una
solución al problema de gerenciar grandes proyectos software.
Su idea fue encapsular cada variable global en un módulo con un grupo de operaciones (al
igual que los procedimientos y las funciones) que permitan tener un acceso directo a la
variable. Otros módulos pueden acceder a la variable sólo indirectamente, llamando a
estas operaciones. Hoy se usa el término objeto para tales módulos o variables
encapsuladas a sí mismas.
Lenguajes imperativos como Pascal Y C han sido modificados (o añadidos) para que
soporten el paradigma orientado a objetos para dar Delphi en el caso de Pascal y C++ en el
caso de C.
Son aquellos lenguajes de programación en los cuales se le indica a la computadora que es lo
que se desea obtener o que es lo que se está buscando, por ejemplo:
“Obtener los nombres de todos los empleados que tengan más de 32 años”.
Algunos ejemplos de lenguajes declarativos son el Datatrieve, SQL y las expresiones regulares.
El SQL -Structured Query Language - (Lenguaje Estructurado de Consultas) es un lenguaje
declarativo que une características del Álgebra y el Cálculo Relacional que nos permite lanzar
consultas contra una Base de Datos para recuperar información de nuestro interés,
almacenada en ella.
Paradigmas declarativos
Ejemplos de consultas SQL:
SELECT Nombre From Tabl_fich_personales where Edad >=18;
Muestra el Campo "Nombre" de todos los individuos mayores de 18 años de la tabla
"Tabl_fich_personales"
Los lenguajes declarativos están basados en la definición de funciones o relaciones. No
utilizan instrucciones de asignación (sus variables no almacenan valores). Son los más
fáciles de utilizar (no se requieren conocimientos específicos de informática), están muy
próximos al hombre.
Se suelen denominar también lenguajes de órdenes, ya que los programas están
formados por sentencias que ordenan “qué es lo que se quiere hacer”, no teniendo el
programador que indicar a la computadora el proceso detallado (el algoritmo) de cómo
hacerlo”.
Se dividen en lenguajes funcionales y lógicos.
Ventajas Desventajas
Código más corto y eficiente. En parte, difícil de comprender para personas
ajenas.
Realizable con métodos no conocidos en el
momento de la programación.
Basado en una forma de pensar no habitual
en las personas (estado de solución).
Optimización sencilla, ya que la ejecución se
gestiona mediante un algoritmo.
Las características de casos de aplicación
individuales se pueden considerar en la
programación, pero únicamente de forma
compleja.
Es posible el mantenimiento independiente
del desarrollo de la aplicación.
Paradigma Lógico
✓ El control básico de este paradigma son las inferencias lógicas.
✓ Ninguna operación secuencial.
✓ Se basa en la lógica simbólica.
✓ Los lenguajes lógicos son el otro tipo de lenguajes declarativos, y en ellos los
programas están formados por una serie de definiciones de predicados.
También se les denomina lenguajes de programación lógica, y el mayor exponente es el
lenguaje PROLOG.
Se aplican sobre todo en la resolución de problemas de Inteligencia Artificial.
✓ No tienen ningún control secuencial.
✓ Toda la acción es a través de la evaluación de una función, en particular recursión.
✓ Se basa en la noción abstracta de una función.
✓ Los lenguajes funcionales son un tipo de lenguajes declarativos, en los que los
programas están formados por una serie de definiciones de funciones.
Ejemplos de estos lenguajes son el LISP y el SCHEME.
Se suelen aplicar a problemas de Inteligencia Artificial.
Paradigma funcional
Primo (Lisp)Determina si un número es primo o no(DEFUN PRIMO(N)COND((EQ N 2) T) ((EQ N 3) T)(T (PRIMO1 N (QUOTIENT N 2)))))(DEFUN PRIMO1 (N Y)COND((EQ (REMAINDER N Y) 0) NIL)((EQ Y 2) T)(T (PRIMO1 N (DIFERENCE Y 1))))Y al ejecutarlo, por ejemplo se tendría,(PRIMO 3) T(PRIMO 8) NUL
OrdenaOrdena de forma ascendente los elemento de una listaDEFUN ORDENAR (LISTA)COND((NULL LISTA) NIL)(T (CONS (CAR (INVERSO (BURBUJA LISTA)))(ORDENAR (CDR(INVERSO (BURBUJA LISTA))))))))(DEFUN BURBUJA (LISTA)
(COND((NULL (CDR LISTA)) LISTA)((GRATERP (CAR LISTA) (CADR LISTA))(CONS (CAR LISTA) (BURBUJA (CDR LISTA))))(T (CONS (CADR LISTA)(BURBUJA (CONS (CAR LISTA) (CDDR LISTA)))))))
Al ejecutarse se tendría, por ejemplo,
(ORDENAR 20 8 1 3) (1,3,8,20)
la función INVERSO invierte la lista
Ejemplo de Lisp
Una función o un grupo de funciones compuestas por funciones más simples estableciéndose que una función puede llamar a otra, o el resultado de una función puede ser usado como argumento de otra función.
Ventajas Desventajas
Los programas no tienen estados Los datos (por ejemplo, las variables) no se
pueden modificar
Muy adecuados para la paralelización No se permite el acceso eficiente a grandes
cantidades de datos
El código se puede testar fácilmente No se recomienda para conexiones a bases
de datos y servidores
Código fácilmente verificable, incluso las
funciones sin estado se pueden verificar
No es adecuado para muchas recursiones
de la misma pila
Fácil de combinar con la programación
imperativa y orientada a objetos
La programación recurrente puede dar
lugar a errores graves
Código más preciso y más corto No apto para todas las tareas
Ejemplo de programación declarativa frente a imperativa
Un punto fuerte de la programación declarativa es su capacidad para describir
problemas de forma más corta y precisa que el lenguaje imperativo.
Ejemplo: Si se tiene que crear una lista con nombres, con la programación declarativa
se puede describir en PHP con solo una línea de código, mientras que el
procedimiento imperativo necesita cinco líneas.
Programación imperativa:
$listaparticipantes = [1 => 'Peter', 2 => 'Hans', 3 => 'Sarah'];
$nombres = [];
foreach ($listaparticipantes as $id => $apellido)
{ $nombres[] = $apellido;
}
Programación declarativa:
$nombres = array_values($listaparticipantes);
✓También llamada programación por ejemplos el programador no especifica
procedimentalmente cómo construir una solución. En su lugar, presentan soluciones de
problemas similares y permite al sistema que generalice una solución procedimental a
partir de estas demostraciones.
✓Los esquemas individuales para generalizar tales soluciones van desde simular una
secuencia procedimental o inferir intenciones.
✓Los sistemas que infieren, intentan generalizar usando razonamiento basado en el
conocimiento.
✓Se provee al sistema de soluciones similares y se deja que se generalice una solución a
partir de estos ejemplos
✓Ejemplos: sistemas de inducción, redes de neuronas artificiales y programación
genética.
Paradigmas demostrativos
Desventajas:
✓Conocer cuándo un programa es correcto. En el caso de los sistemas procedimentales, se
consigue estudiando el algoritmo y el resultado de juegos de ensayo apropiados.
✓La programación demostrativa es del tipo "bottom-up" y se adapta bien a nuestra
capacidad de pensar. Sin embargo en la mayor parte de los paradigmas la resolución del
problema se efectúa aplicando métodos abstractos "top-down".
Muchas de las tareas más interesantes y difíciles de programación implican utilizar el
ordenador para resolver problemas del tipo: "¿Cuál es el camino más corto?" "Listar todos
los casos posibles", "¿Existe una disposición de elementos que satisfaga?.
Las características de estos problemas implica potencialmente una búsqueda exhaustiva de
todas las posibles combinaciones de algún conjunto finito, que si no está controlado puede
producir una "explosión combinatoria" (incremento exponencial del espacio de búsqueda
con la dimensión del problema) imposible de tratar.
Paradigma heurístico
La Programación Heurística implica una forma de modelizar el problema en lo que
respecta a la representación de su estructura, estrategias de búsqueda y métodos de
resolución, que configuran el Paradigma Heurístico.
La Programación Heurística ha venido a significar el uso del conocimiento específico del
dominio para cubrir esta explosión de posibilidades guiando la búsqueda por las
direcciones más prometedoras.
Se puede definir como "aquel tipo de programación computacional que aplica para la
resolución de problemas reglas de buena lógica (reglas del pulgar). denominadas
heurísticas, las cuales proporcionan entre varios cursos de acción uno que presenta
visos de ser el más prometedor, pero no garantiza necesariamente el curso de acción
más efectivo.”
Este tipo de programación se aplica con mayor intensidad en el campo de la Inteligencia
Artificial (IA), y en especial, en el de la Ingeniería del Conocimiento, dado que el ser
humano opera la mayor parte de las veces utilizando heurísticas, un hecho cierto que una
heurística es la conclusión del razonamiento humano en un dominio específico, por lo que
es normal que este tipo de programación que encuadrado en el área de la I.A., ya que
implementa el conocimiento humano, dado por la experiencia, utilizando reglas de buena
lógica.
Se aconseja utilizar un modelo heurístico cuando:
✓Los datos, limitados e inexactos, utilizados para estimar los parámetros modelo
pueden contener errores inherentes muy superiores a los proporcionados con la
solución de una buena heurística.
✓Se utiliza un modelo simplificado, que por sí es una representación imprecisa de
un problema real, por lo que la solución "óptima" es puramente académica.
✓No se dispone de un método exacto que sea fiable para ser aplicado en un
modelo del problema; o si existe, es intratable computacionalmente.
✓Se desea mejorar la eficacia de un algoritmo optimizador aplicado al modelo por
ejemplo, proporcionando buenas soluciones de inicio, guiando la búsqueda y
reduciendo el número de soluciones candidatas
✓Se tiene la necesidad de resolver el mismo problema frecuentemente, o una base
de tiempo real, y el tratamiento heurístico significa un ahorro computacional.
¿Cuando utilizar método heurístico?
Una buena heurística debe ser:
✓Simple
✓Con requerimientos razonables de memoria
✓Con velocidad de búsqueda que no produzca incrementos polinomiales, ni exponenciales
✓Precisa
✓Robusta
✓Que proporcione soluciones múltiples
✓Que disponga de un buen criterio de parada que incorpore el conocimiento obtenido
durante la búsqueda.
Este paradigma es lo de moda de hoy en día, aunque ya hace años que existe.
El paradigma reactivo se centra en los flujos de datos y como entrelazarlo con objetos.
Posee flujo de datos constantes (stream) y reaccionan a los cambios porque no se sabe
cuando se produce o cuando llegara al sistema.
Lenguajes:
Los siguientes lenguajes poseen una librería basada en ReactiveX que les permite
pertenecer al paradigma de la Programación reactiva
Java: RxJavaJavaScript: RxJSC#: Rx.NETC#(Unity): UniRxScala: RxScalaClojure: RxClojureC++: RxCppLua: RxLuaRuby: Rx.rbPython: RxPY
Paradigma reactivo
CONCLUSIONES
✓La comprensión básica de los conceptos de los lenguajes de programación y los
diferentes paradigmas son necesarios para todos los ingenieros de software, no tanto
para los especialistas en un lenguaje de programación. Esto se debe a que los
lenguajes de programación son una herramienta fundamental.
✓Los lenguajes de programación influencian notablemente la manera en que
pensamos acerca del diseño y construcción del software y los algoritmos y estructuras
de datos que utilicemos para desarrollar software.
✓Las técnicas de programación brindan una guía de cómo diseñar, organizar e
implementar las funciones de las que se compone el programa.
Ejemplo de estas técnicas son:
• Descomposición funcional: que identifica las funciones que sirven como
operaciones abstractas del problema.
• Abstracción de datos. que permite diferir las estructuras de datos
representativas de las entidades presentes en el problema y las operaciones que
se realizan con ellas.
• Encapsulamiento: que facilitan reunir estructuras de datos y operaciones en un
tipo abstracto, dando sólo forma de acceso a la estructura a través de sus
operaciones.
• Organización de ficheros: que permite formar biblioteca de código reutilizable.
Ejemplo: función que calcula el numero de dígitos decimales en un entero resuelto por lenguajes de diferentes paradigmas de programación: C++, Java y Visual Prolog.
En C++:
#include <iostream.h>int numdigits (int x);void main()
{ int numero;cout<<"\n Ingrese un número entero:";cin>>numero;cout<<"\n El número de digitos es:"<<numdigits(numero);
}int numdigits (int x)
{int t=x, n=1;while (t>=10)
{n++;t=t/10;
}return n;}
Al ejecutar:
Ingrese un número entero:566El número de dígitos es: 3
En Java:/** Crea una clase Numdig*/package lenguaje1;import biblioteca.*;public class Numdig {int numero;public void ingresar() {numero=LE.leerInt("Ingrese entero");}public void calcular(){int t=numero, n=1;while (t>=10){n++;t=t/10;}LE.mostrarInformacion("Número de dígitos:"+ n);}public static void main(String args[]){Numdig obj = newNumdig();obj.ingresar();obj.calcular();}}
Al ejecutar:
EntradaIngrese entero: 566Aceptar Cancelar
InformaciónNúmero de dígitos: 3Aceptar
En Visual Prolog:
predicatesnondeterm numdigits(integer, integer)clauses
numdigits(N,1):-N<10.
numdigits(N,F):-N>=10,N1=N/10,
numdigits(N1,F1),F=F1 + 1.
goal
numdigits(566,F).
Al ejecutar:
F=31 solution
Conclusión: Observamos que un mismo problema se puede resolver con
diferentes lenguajes de programación: C++, Java, Visual Prolog., pero
siempre hay un Lenguaje más adecuado de acuerdo al problema.
Top Related