Unidad Ii
Unidad Ii
Unidad Ii
MODELO DE
PROGRAMACIÓN
FUNCIONAL
INTRODUCCIÓN AL MODELO DE
PROGRAMACIÓN FUNCIONAL
¿QUÉ ES LA PROGRAMACIÓN FUNCIONAL?
Entre ellos cabe destacar: un sistema de tipos polimórficos que permite definir una amplia variedad de
estructuras de datos de uso genérico, la posibilidad de definir funciones que aceptan otras funciones
como argumentos y devuelven funciones como resultado, facilidades para definir y manipular estructuras
de datos infinitas, un modelo computacional simple, claro y bien fundamentado, etc.
De no menor importancia es la posibilidad de razonar, de forma sencilla, acerca de las propiedades de los
programas: su corrección, su eficacia, su comportamiento en ejecución. Esto permite optimizar las tareas
de implementación de los lenguajes funcionales.
Podemos encontrar, en casi todos los lenguajes de programación funcional, un
núcleo común de conceptos y técnicas asentado sobre bases firmemente
establecidas.
• Funciones puras
• Inmutabilidad
• Funciones currificadas
• Recursividad
En una hoja de cálculo, se especifica cada celda en términos de los valores de otras celdas.
Por ejemplo:
• No especificamos el orden en el que las celdas serán calculadas, en cambio obtenemos el orden que
garantiza que la hoja de cálculo puede calcular las celdas respetando las dependencias.
• No indicamos a la hoja de cálculo como manejar la memoria, en cambio esperamos que nos presente un
plano de celdas, aparentemente infinito, pero que solo utiliza la memoria de las celdas que están
actualmente en uso.
• Lo más importante, especificamos el valor de una celda por una expresión (cuyas partes pueden ser
evaluadas en cualquier orden), en vez de una secuencia de comandos que calculan los valores.
FUNCIONES PURAS E INMUTABILIDAD
Una función pura es la que cumple con estas dos características:
1 LISP
2
SCHEME
3 COMMON LISP
4 Haskell
INTRODUCCIÓN A LA
PROGRAMACIÓN FUNCIONAL
EN F#
INTRODUCCION
La programación funcional es un estilo de programación que enfatiza el uso de funciones y
datos inmutables.
La programación funcional con tipo es cuando la programación funcional se combina con tipos
estáticos, F# como con. En general, los conceptos siguientes se destacan en la programación
funcional:
Función
Una función es una construcción que generará una salida cuando se proporcione una
entrada. Más formalmente, asigna un elemento de un conjunto a otro conjunto. Este
formalismo se eleva en concreto de muchas maneras, especialmente cuando se usan
funciones que operan en colecciones de datos. Es el concepto más básico (y
importante) de la programación funcional.
TERMINOLOGÍA
Expresión
Una expresión es una construcción de código que genera un valor. En F#, este
valor debe estar enlazado o omitirse explícitamente. Una expresión se puede
reemplazar trivialmente por una llamada de función.
La pureza-pureza
Es una propiedad de una función de modo que el valor devuelto sea siempre
el mismo para los mismos argumentos, y que su evaluación no tenga efectos
secundarios. Una función pura depende completamente de sus argumentos.
TERMINOLOGÍA
Transparencia referencial
Inmutabilidad
✓ Sintaxis ligera
✓ Detección de patrones
✓ Programación asincrónica
F# es un lenguaje de programación:
Fuertemente tipado
Multiparadigma
“Functional-First”
De código abierto
Multiplataforma
PRINCIPALES
CARACTERÍSTICAS
Inferencia de tipos:
F# permite hacer con funciones todo lo que se puede hacer con los
valores de forma sencilla tales como asignación como parámetro,
almacenamiento en estructuras o funciones cruzadas
Uso de expresiones lambda:
let addOne x = x + 1
Miembros
Restricciones
as Clases Se utiliza para asignar un nombre de objeto al objeto de clase
actual. También se usa para asignar un nombre a un patrón entero
Coincidencia de patrones dentro de una coincidencia de patrones.
Bucles:
expresión while...do
done Sintaxis detallada En la sintaxis detallada, indica el final de un
bloque de código en una expresión de
bucle.
Palabra clave Vínculo Descripción
downcast Conversiones Se usa para convertir a un tipo que está más
abajo en la cadena de herencia.
Sintaxis detallada
exception Control de excepciones Se utiliza para declarar un tipo de excepción.
Tipos de excepción
inherit Herencia Se utiliza para especificar una clase base o una interfaz base.
inline Funciones Se usa para indicar una función que debe integrarse
directamente en el código del llamador.
Funciones insertadas
!
Celdas de referencia De referencia una celda de referencia.
Expresiones de cálculo Después de una palabra clave, indica una
versión modificada del comportamiento de
la misma, controlado por un flujo
de trabajo.
!=
No se utiliza en F#. Utilice <> para las
operaciones de desigualdad.
“
Literales Delimita una cadena de texto.
Cadenas
…
Cadenas Delimita una cadena de texto literal. Se
diferencia de @"..." en que puede
indicar un carácter de comilla mediante
el uso de comillas simples en la cadena.
#
Directivas de compilador Prefija una directiva de compilador o
Tipos flexibles preprocesador, como #light .
Cuando se usa con un tipo, indica un tipo
flexible, que hace referencia a un tipo o a
cualquiera de sus tipos derivados.
SÍMBOLO U OPERADOR VÍNCULOS DESCRIPCIÓN
$
Se utiliza internamente para determinados
nombres de variable y función generados
por el compilador.
%
Operadores aritméticos Calcula el resto entero.
Expresiones de código Se utiliza para ensamblar expresiones en
delimitadas expresiones de código delimitadas con tipo.
%%
Expresiones de código Se utiliza para ensamblar expresiones en
delimitadas expresiones de código delimitadas sin tipo.
%?
Operadores que aceptan Calcula el resto entero, cuando el lado
valores NULL derecho es un tipo que acepta valores NULL.
&
Expresiones de coincidencia Calcula la dirección de un valor mutable para
usarlo al interoperar con otros lenguajes.
Se utiliza en los patrones AND.
&&
Operadores booleanos Calcula la operación AND booleana.
&&&
Operadores bit a bit Calcula la operación AND bit a bit.
SÍMBOLO U OPERADOR VÍNCULOS DESCRIPCIÓN
‘
Literales Delimita un literal de carácter único.
Generalización automática Indica un parámetro de tipo genérico.
‘ ’. . .’ ‘
Delimita un identificador que de otro modo
no sería un identificador válido, como una
palabra clave de lenguaje.
( )
Unit (Tipo) Representa el valor único del tipo de unidad.
( ... )
Tuplas Indica el orden en que se evalúan las
Sobrecarga de operadores expresiones.
Delimita una tupla.
Se utiliza en las definiciones de operador.
( * . . . *)
Delimita un comentario que podría abarcar
varias líneas.
(|...|)
Patrones activos Delimita un modelo activo.
También se denominan delimitadores de
modelo activo
SÍMBOLO U OPERADOR VÍNCULOS DESCRIPCIÓN
*
Operadores aritméticos Cuando se utiliza como un operador binario,
Tuplas multiplica los lados izquierdo y derecho.
Unidades de medida En los tipos, indica el emparejamiento en una
tupla. Se utiliza en unidades de medida de tipos
*?
Operadores que Multiplica los lados izquierdo y derecho, si el lado
aceptan valores NULL derecho es un tipo que acepta valores NULL.
**
Operadores aritméticos Calcula la operación de exponenciación ( x ** y
significa x elevado a la potencia de y ).
+
Operadores aritméticos Si se utiliza como un operador binario, suma los
lados izquierdo y derecho.
Cuando se utiliza como un operador unario, indica
una cantidad positiva. (Formalmente, genera el
mismo valor sin modificar el signo)
+?
Operadores que Suma los lados izquierdo y derecho, si el lado
aceptan valores NULL derecho es un tipo que acepta valores NULL.
,
Tuplas Separa los elementos de una tupla o los
parámetros de tipo.
FUNCIONES
FUNCIONES
Al igual que en otros lenguajes, una función de F# tiene un nombre,
puede tener parámetros y tomar argumentos, y tiene un cuerpo.
Sintaxis
let f x = x + 1
En el ejemplo anterior, el nombre de función es f , el argumento es x , que tiene el tipo int , el cuerpo de la función
es x + 1 y el valor devuelto es de tipo int .
Por ejemplo, el código siguiente produce un error cuando aparece en el ámbito de módulo, pero no cuando aparece dentro de una
función:
let list1 = [ 1; 2; 3]
// Error: duplicate definition.
let list1 = []
let function1 =
let list1 = [1; 2; 3]
let list1 = []
List1
let f (x : int) = x + 1
Si se especifica un tipo, sigue al nombre del parámetro y se separa del nombre mediante dos puntos. Si se omite el tipo
del parámetro, el compilador infiere el tipo de parámetro. Por ejemplo, en la siguiente definición de función, se deduce
que el argumento x es del tipo int porque 1 es de tipo int .
let f x = x + 1
Pero el compilador intentará que la función sea lo más genérica posible. Por ejemplo, observe el código siguiente:
let f x = (x, x)
La función crea una tupla a partir de un argumento de cualquier tipo. Dado que no se especifica el tipo, la función se
puede usar con cualquier tipo de argumento.
Cuerpo de la función
El cuerpo de una función puede contener definiciones de variables locales y funciones.
Estas variables y funciones están en ámbito en el cuerpo de la función actual, pero no fuera de ella.
Una vez habilitada la opción de sintaxis ligera, se debe usar sangría para indicar que es una definición de un cuerpo de
función, como se muestra en el ejemplo siguiente:
En la función cylinderVolume , como se muestra en la sección anterior, el tipo de pi se determina a partir del tipo del literal 3.14159
como float .
El compilador usa el tipo de pi para determinar el tipo de la expresión h * pi * r * r como float . Por tanto, el tipo de valor devuelto
global de la función es float.
Tal como se escribe el código anterior, el compilador aplica float a toda la función. Si también quiere aplicarlo a los tipos de
parámetro, use el código siguiente:
Es posible que algunas funciones recursivas desborden la pila del programa o tengan un rendimiento ineficaz si
no se escriben con cuidado y con el conocimiento de determinadas técnicas especiales, como el uso de
acumuladores y continuaciones
Valores de función
En F#, todas las funciones se consideran valores, de hecho, se conocen como valores de función. Dado que las funciones son valores, se pueden
usar como argumentos de otras funciones o en otros contextos donde se usan los valores. El siguiente ejemplo muestra una función que toma
un valor de función como argumento:
El tipo de un valor de función se especifica mediante el token -> . En el lado izquierdo de este token está el tipo del argumento y, en el lado
derecho, el valor devuelto. En el ejemplo anterior, apply1 es una función que toma una función transform como argumento, donde transform es
una función que toma un entero y devuelve otro entero. En el código siguiente se muestra cómo usar apply1 :
let increment x = x + 1
let result1 = apply1 increment 100
El valor de result será 101 después de ejecutar el código anterior. Si hay varios argumentos, se separan por sucesivos tokens -> , como se
muestra en el ejemplo siguiente:
Las expresiones lambda se definen mediante la palabra clave fun . Una expresión lambda es similar
a una definición de función, salvo que en lugar del token = se usa el token -> para separar la lista
de argumentos del cuerpo de la función. Al igual que en una definición de función normal, se
pueden deducir o especificar explícitamente los tipos de argumento, y el tipo de valor devuelto de
la expresión lambda se deduce del tipo de la última expresión en el cuerpo. Para obtener más
información, vea Expresiones lambda: Palabra clave fun .
Composición de funciones y canalización
En F#, las funciones se pueden componer a partir de otras funciones. La composición de dos funciones función1 y función2 es otra
función que representa la aplicación de función1 seguida de la aplicación de función2:
let function1 x = x + 1
let function2 x = x * 2
let h = function1 >> function2
let result5 = h 100
El resultado es 202.
La canalización permite encadenar llamadas a funciones como operaciones sucesivas. La canalización funciona de la siguiente manera:
let result = 100 |> function1 |> function2
El resultado es 202 de nuevo.
Los operadores de composición toman dos funciones y devuelven una función. Por el contrario, los operadores de canalización toman
una función y un argumento, y devuelven un valor. En el ejemplo de código siguiente se muestra la diferencia entre los operadores de
canalización y composición mostrando las diferencias en las firmas de función y el uso.