Documentos de Académico
Documentos de Profesional
Documentos de Cultura
lógica y funcional
INTRODUCCIÓN
La Programación Lógica y Funcional, es una asignatura que requiere tener conocimientos esenciales
acerca de los lenguajes lógicos y funcionales de la inteligencia artificial, incluyendo la metodología
y los aspectos relativos a la codificación, con el fin de ampliar el conocimiento de tecnologías
alternativas para el desarrollo de sistemas automatizados y la implementación de agentes
inteligentes.
Una piedra clave para un buen estilo es la elección apropiada de nombres de variable. Variables
pobremente nombradas dificultan la lectura del código fuente y su comprensión.
get a b c
return true
else
return false
Debido a la elección de nombres de variable, es difícil darse cuenta de la función del código.
Compárese ahora con la siguiente versión:
return true
else
return false
La intención el código es ahora más sencilla de discernir, "dado una hora en 24 horas, se
devolverá true si es válida y false si no".
Estilo de identación
Estilo de indentación, en lenguajes de programación que usan llaves para identar o delimitar
bloques lógicos de código, como por ejemplo C, es también un punto clave el buen estilo. Usando
un estilo lógico y consistente hace el código de uno más legible. Compárese:
return true;
}else{
return false;
o bien:
if(horas < 24 && minutos < 60 && segundos < 60)
return true;
else
return false;
Los primeros dos ejemplos son mucho más fáciles de leer porque están bien indentados, y los bloques
lógicos de código se agrupan y se representan juntos de forma más clara.
Algunos programadores piensan que las estructuras de decisión como las anteriores, donde el
resultado de la decisión es meramente una computación de un valor booleano, son demasiado
prolijos e incluso propensos al error. Prefieren hacer la decisión en la computación por sí mismo,
como esto:
return horas < 12 && minutos < 60 && segundos < 60;
La diferencia es, con frecuencia, puramente estilística y sintáctica, ya que los compiladores
modernos producirán código objeto idéntico en las dos formas.
El uso de estructuras de control lógicas para bucles también es parte de un buen estilo de
programación. Ayuda a alguien que esté leyendo el código a entender la secuencia de ejecución
(en programación imperativa). Por ejemplo, el siguiente pseudocódigo:
cuenta = 0
endwhile
El extracto anterior cumple con las dos recomendaciones de estilo anteriores, pero el siguiente uso
de la construcción for hace el código mucho más fácil de leer:
En muchos lenguajes, el patrón frecuentemente usado "por cada elemento en un rango" puede
ser acortado a:
for cuenta = 0 to 5
print cuenta * 2
Espaciado
Los lenguajes de formato libre ignoran frecuentemente los espacios en blanco. El buen uso del
espaciado en la disposición del código de uno es, por tanto, considerado un buen estilo de
programación.
int cuenta;
for(cuenta=0;cuenta<10;cuenta++){printf("%d",cuenta*cuenta+cuenta);}
con:
int cuenta;
El orden en que se evalúan los operandos viene dado por unas reglas:
Reglas de procedencia
Reglas de asociatividad
Uso de paréntesis
EVALUACIÓN DE EXPRESIONES
Toda expresión regresa un valor. Si hay más de un operador, se evalúan primero operadores mayor
precedencia, en caso de empate, se aplica regla asociatividad. Para evaluar una expresión no
hay que hacer nada del otro mundo, pues es bien sencillo. Sólo hay que saber sumar, restar, si un
número es mayor que otro.
1. Una sola constante o variable, la cual puede estar precedida por un signo + ó – .
2. Una secuencia de términos (constantes, variables, funciones) separados por operadores.
Además debe considerarse que: Toda variable utilizada en una expresión debe tener un valor
Cualquier constante o variable puede ser reemplazada por una llamada a una función.
(Regla 1) En todas las expresiones se evalúan primero las expresiones de los paréntesis más anidados
(interiores unos a otros); y éstos modifican la prioridad según la cantidad de éstos, los cuales tienen
que estar balanceados (el mismo número de paréntesis que abren debe ser igual al número de los
paréntesis que cierran).
(Regla 2) Todas las expresiones se evalúan tomando en cuenta la jerarquía de los operadores.
(Regla 3) Todas las expresiones se evalúan de izquierda a derecha. Tabla de evaluación de C++
Tabla de evaluación de Java
Las funciones se crearon para evitar tener que repetir constantemente fragmentos de código. Una
función podría considerarse como una variable que encierra código dentro de sí. Por lo tanto
cuando accedemos a dicha variable (la función) en realidad lo que estamos es diciendo al
programa que ejecute un determinado código predefinido anteriormente. Todos los lenguajes de
programación tienen algunos elementos de formación primitivos para la descripción de los datos y
de los procesos o transformaciones aplicadas a estos datos (tal como la suma de dos números o la
selección de un elemento que forma parte de una colección). Estos elementos primitivos son
definidos por reglas sintácticas y semánticas que describen su estructura y significado
respectivamente.
Función: Una función en matemáticas, es una operación que toma un o más valores (argumentos)
y devuelve un resultado (valor de la función para los argumentos dados). Por ejemplo:
F(X) = X / (1+X2)
Donde:
Inicio
Bloque de instrucciones
Fin
Donde:
Cuando definimos una función solo le indicamos al algoritmo que esta función existe, pero una
definición de función no implica la realización de las instrucciones que la constituyen. Para hacer
uso de una función, el algoritmo principal la debe llamar. Por ejemplo:
Función F(X)
Inicio
F = X /(1 + X^2)
Fin
Inicio
Leer N
Fin
1.4.- Disciplina de Tipos
En los lenguajes de programación con disciplina de tipos, cada tipo representa una colección de
valores o datos similares. El conocer los tipos de las funciones ayuda a documentar los programas y
evitar errores en tiempo de ejecución.
DISCIPLINA: Es la coordinación de actitudes con las cuales se instruye para desarrollar habilidades , o
para seguir un determinado código de conducta u "orden".
Un lenguaje tiene disciplina de tipos si los errores de tipos se detectan siempre ⇒ es necesario
determinar los tipos de todos los operandos, ya sea en tiempo de compilación o de ejecución.
Pascal
Cercano a tener disciplina de tipos pero no realiza comprobación de tipos en los registros variantes
(incluso puede omitirse la etiqueta discriminatoria en dichos registros)
Ada
Resuelve el problema de los registros variantes realizando comprobación dinámica de tipos (sólo en
este caso) Tiene una función de biblioteca que permite extraer un valor de una variable de cualquier
tipo (como una cadena de bits) y usarlo como un tipo diferente (no es una conversión de tipos) ⇒ se
trata de una suspensión temporal de la comprobación de tipos
C
No tiene disciplina de tipos por:
− Permite funciones con parámetros sobre los que no se realiza comprobación de tipos
Java
Tiene disciplina de tipos (no hay uniones)
ML y Haskell
• Poseen disciplina de tipos
Los tipos de los parámetros de las funciones (y de estas mismas) se conocen en tiempo de compilación
(ya sea por declaración del usuario o por inferencia de tipos)Haskell y otros lenguajes funcionales
utilizan el sistema de tipos de Milner, que tiene dos características fundamentales:
Disciplina estática de tipos: Los programas bien tipados se pueden conocer en tiempo de
compilación. Un programa bien tipado se puede utilizar sin efectuar comprobaciones de tipo
en tiempo de ejecución, estando garantizado que no se producirán errores de tipo durante
el cómputo.
Polimorfismo: Permite que una misma función se pueda aplicar a parámetros de diferentes
tipos, dependiendo del contexto en el que la función se utilice.
Programación lógica
La programación lógica consiste en la aplicación del corpus de conocimiento sobre lógica para
el diseño de lenguajes de programación; no debe confundirse con la disciplina de la lógica
computacional.
La programación lógica es un tipo de paradigmas de programación dentro del paradigma de
programación declarativa. El resto de los subparadigmas de programación dentro de la
programación declarativa son: programación funcional, programación basada en restricciones,
programas DSL (de dominio específico) e híbridos. La programación lógica gira en torno al concepto
de predicado, o relación entre elementos. La programación funcional se basa en el concepto de
función (que no es más que una evolución de los predicados), de corte más matemático.
Programación funcional
En ciencias de la computación, la programación funcional es un paradigma de programación
declarativa basado en la utilización de funciones aritméticas que no maneja datos mutables o de
estado. Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativa,
que enfatiza los cambios de estado. La programación funcional tiene sus raíces en el cálculo lambda,
un sistema formal desarrollado en los 30s para investigar la definición de función, la aplicación de las
funciones y la recursión. Muchos lenguajes de programación funcionales pueden ser vistos como
elaboraciones del cálculo lambda.
Los lenguajes de programación funcional, especialmente los que son puramente funcionales, han
sido enfatizados en el ambiente académico principalmente y no tanto en el desarrollo de software
comercial. Sin embargo, lenguajes de programación importantes tales como Scheme, Erlang,
Objective Caml y Haskel, han sido utilizados en aplicaciones comerciales e industriales por muchas
organizaciones. La programación funcional también es utilizada en la industria a través de lenguajes
de dominio específico como R (estadística), Mathematica (matemáticas simbólicas), J y K (análisis
financiero), F# en Microsoft.NET y XSLT (XML). Lenguajes de uso específico usados comúnmente como
SQL y Lex/Yacc, utilizan algunos elementos de programación funcional, especialmente al procesar
valores mutables. Las hojas de cálculo también pueden ser consideradas lenguajes de programación
funcional.
La programación funcional también puede ser desarrollada en lenguajes que no están diseñados
específicamente para la programación funcional. En el caso de Perl, por ejemplo, que es un lenguaje
de programación imperativo, existe un libro que describe cómo aplicar conceptos de programación
funcional. JavaScript, uno de los lenguajes más ampliamente utilizados en la actualidad, también
incorpora capacidades de programación funcional.
Programación declarativa
La Programación Declarativa, es un paradigma de programación que está basado en el
desarrollo de programas especificando o "declarando" un conjunto de condiciones, proposiciones,
afirmaciones, restricciones, ecuaciones o transformaciones que describen el problema y detallan su
solución. La solución es obtenida mediante mecanismos internos de control, sin especificar
exactamente cómo encontrarla (tan sólo se le indica a la computadora que es lo que se desea
obtener o que es lo que se está buscando). No existen asignaciones destructivas, y las variables son
utilizadas con Transparencia referencial.
Programación estructurada
La programación estructurada es una forma de escribir programas de ordenador (programación
de computadora) de manera clara. Para ello utiliza únicamente tres estructuras: secuencia, selección
e iteración; siendo innecesario el uso de la instrucción o instrucciones de transferencia incondicional
(GOTO, EXIT FUNCTION, EXIT SUB o múltiples RETURN).
Programación dirigida por eventos
La programación dirigida por eventos es un paradigma de programación en el que tanto la
estructura como la ejecución de los programas van determinados por los sucesos que ocurran en el
sistema, definidos por el usuario o que ellos mismos provoquen.
Para entender la programación dirigida por eventos, podemos oponerla a lo que no es: mientras
en la programación secuencial (o estructurada) es el programador el que define cuál va a ser el flujo
del programa, en la programación dirigida por eventos será el propio usuario —o lo que sea que esté
accionando el programa— el que dirija el flujo del programa. Aunque en la programación secuencial
puede haber intervención de un agente externo al programa, estas intervenciones ocurrirán cuando
el programador lo haya determinado, y no en cualquier momento como puede ser en el caso de la
programación dirigida por eventos.
El creador de un programa dirigido por eventos debe definir los eventos que manejarán su
programa y las acciones que se realizarán al producirse cada uno de ellos, lo que se conoce como
el administrador de evento. Los eventos soportados estarán determinados por el lenguaje de
programación utilizado, por el sistema operativo e incluso por eventos creados por el mismo
programador.
En la programación dirigida por eventos, al comenzar la ejecución del programa se llevarán a
cabo las inicializaciones y demás código inicial y a continuación el programa quedará bloqueado
hasta que se produzca algún evento. Cuando alguno de los eventos esperados por el programa
tenga lugar, el programa pasará a ejecutar el código del correspondiente administrador de evento.
Por ejemplo, si el evento consiste en que el usuario ha hecho click en el botón de play de un
reproductor de películas, se ejecutará el código del administrador de evento, que será el que haga
que la película se muestre por pantalla.
Un ejemplo claro lo tenemos en los sistemas de programación Léxico y Visual Basic, en los que a
cada elemento del programa (objetos, controles, etcétera) se le asignan una serie de eventos que
generará dicho elemento, como la pulsación de un botón del ratón sobre él o el redibujado del
control.
La programación dirigida por eventos es la base de lo que llamamos interfaz de usuario, aunque
puede emplearse para desarrollar interfaces entre componentes de Software como módulos del
núcleo también.
En los primeros tiempos de la computación, los programas eran secuenciales, también llamados
Batch. Un programa secuencial arranca, lee parámetros de entrada, procesa estos parámetros, y
produce un resultado, todo de manera lineal y sin intervención del usuario mientras se ejecuta.
Con la aparición y popularización de los pc, el software empezó a ser demandado para usos
alejados de los clásicos académicos y empresariales para los cuales era necesitado hasta entonces,
y quedó patente que el paradigma clásico de programación no podía responder a las nuevas
necesidades de interacción con el usuario que surgieron a raíz de este hecho...
Programación modular
La programación modular es un paradigma de programación que consiste en dividir un
programa en módulos o subprogramas con el fin de hacerlo más legible y manejable.
Se presenta históricamente como una evolución de la programación estructurada para
solucionar problemas de programación más grandes y complejos de lo que ésta puede resolver.
Al aplicar la programación modular, un problema complejo debe ser dividido en varios
subproblemas más simples, y estos a su vez en otros subproblemas más simples. Esto debe hacerse
hasta obtener subproblemas lo suficientemente simples como para poder ser resueltos fácilmente con
algún lenguaje de programación. Ésta técnica se llama refinamiento sucesivo, divide y vencerás ó
análisis descendente (Top-Down).
Un módulo es cada una de las partes de un programa que resuelve uno de los subproblemas en
que se divide el problema complejo original. Cada uno de estos módulos tiene una tarea bien
definida y algunos necesitan de otros para poder operar. En caso de que un módulo necesite de otro,
puede comunicarse con éste mediante una interfaz de comunicación que también debe estar bien
definida.
Si bien un módulo puede entenderse como una parte de un programa en cualquiera de sus formas
y variados contextos, en la práctica es común representarlos con procedimientos y funciones.
Adicionalmente, también pueden considerarse módulos las librerías que pueden incluirse en un
programa o, en programación orientada a objetos, la implementación de un tipo de dato abstracto.
Programación orientada a objetos
La programación orientada a objetos o POO (OOP según sus siglas en inglés) es un paradigma de
programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas
informáticos. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo y
encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad,
existe variedad de lenguajes de programación que soportan la orientación a objetos.
Programación con restricciones
La Programación con restricciones es un paradigma de la programación en informática, donde
las relaciones entre las variables son expresadas en términos de restricciones (ecuaciones).
Actualmente es usada como una tecnología de software para la descripción y resolución de
problemas combinatorios particularmente difíciles, especialmente en las áreas de planificación y
programación de tareas (calendarización).
Este paradigma representa uno de los desarrollos más fascinantes en los lenguajes de
programación desde 1990 y no es sorprendente que recientemente haya sido identificada por la ACM
(Asociación de Maquinaria Computacional) como una dirección estratégica en la investigación en
computación. Se trata de un paradigma de programación basado en la especificación de un
conjunto de restricciones, las cuales deben ser satisfechas por cualquier solución del problema
planteado, en lugar de especificar los pasos para obtener dicha solución. La programación con
restricciones se relaciona mucho con la programación lógica y con la investigación operativa. De
hecho cualquier programa lógico puede ser traducido en un programa con restricciones y viceversa.
Muchas veces los programas lógicos son traducidos a programas con restricciones debido a que la
solución es más eficiente que su contraparte.
La diferencia entre ambos radica principalmente en sus estilos y enfoques en el modelado del
mundo. Para ciertos problemas es más natural (y por ende más simple) escribirlos como programas
lógicos, mientras que en otros es más natural escribirlos como programas con restricciones.
El enfoque de la programación con restricciones se basa principalmente en buscar un estado en
el cual una gran cantidad de restricciones sean satisfechas simultáneamente. Un problema se define
típicamente como un estado de la realidad en el cual existe un número de variables con valor
desconocido. Un programa basado en restricciones busca dichos valores para todas las variables.
Algunos dominios de aplicación de este paradigma son:
Dominios booleanos, donde solo existen restricciones del tipo verdadero/falso.
Dominios en variables enteras y racionales.
Dominios lineales, donde sólo se describen y analizan funciones lineales.
Dominios finitos, donde las restricciones son definidas en conjuntos finitos.
Dominios mixtos, los cuales involucran dos o más de los anteriores.
Mejorará el mantenimiento del software y permitirá que el código pueda ser leído por cualquier
persona de la empresa que conozca los estándares de codificación. Es necesario indicar que las
recomendaciones son exactamente mejores.