stringtranslate.com

Programación funcional total

La programación funcional total (también conocida como programación funcional fuerte , [1] en contraste con la programación funcional ordinaria o débil ) es un paradigma de programación que restringe el rango de programas a aquellos que son demostrablemente terminantes . [2]

Restricciones

La terminación está garantizada por las siguientes restricciones:

  1. Una forma restringida de recursión , que opera sólo sobre formas "reducidas" de sus argumentos, como la recursión de Walther , la recursión subestructural o la "fuertemente normalizadora", como lo demuestra la interpretación abstracta del código. [3]
  2. Toda función debe ser una función total (en lugar de parcial ), es decir, debe tener una definición para todo lo que se encuentra dentro de su dominio.
    • Hay varias formas posibles de ampliar funciones parciales de uso común, como la división, para que sean totales: elegir un resultado arbitrario para las entradas en las que la función normalmente no está definida (como para la división); agregar otro argumento para especificar el resultado para esas entradas; o excluirlas mediante el uso de características del sistema de tipos, como los tipos de refinamiento . [2]

Estas restricciones significan que la programación funcional total no es Turing-completa . Sin embargo, el conjunto de algoritmos que se pueden utilizar sigue siendo enorme. Por ejemplo, cualquier algoritmo para el que se pueda calcular un límite superior asintótico (mediante un programa que solo utilice la recursión de Walther) se puede transformar de manera trivial en una función demostrablemente terminante utilizando el límite superior como un argumento adicional que se decrementa en cada iteración o recursión.

Por ejemplo, no se demuestra de manera trivial que quicksort sea recursivo subestructural, pero solo recurre hasta una profundidad máxima de la longitud del vector (complejidad temporal en el peor de los casos O ( n 2 )). Una implementación de quicksort en listas (que sería rechazada por un verificador recursivo subestructural) es, utilizando Haskell :

importar Data.List ( partición )  qsort [] = [] qsort [ a ] ​​= [ a ] ​​qsort ( a : como ) = let ( menor , mayor ) = partición ( < a ) como en qsort menor ++ [ a ] ​​++ qsort mayor                       

Para hacerlo recursivo subestructural usando la longitud del vector como límite, podríamos hacer:

importar Data.List ( partición )  qsort x = qsortSub x x -- caso mínimo qsortSub [] as = as -- muestra la terminación -- casos estándar de qsort qsortSub ( l : ls ) [] = [] -- no recursivo, por lo que se acepta qsortSub ( l : ls ) [ a ] ​​= [ a ] ​​-- no recursivo, por lo que se acepta qsortSub ( l : ls ) ( a : as ) = let ( lesser , greater ) = partition ( < a ) as -- recursivo, pero recurre en ls, que es una subestructura de -- su primera entrada. in qsortSub ls lesser ++ [ a ] ​​++ qsortSub ls greater                                          

Algunas clases de algoritmos no tienen un límite superior teórico, pero sí tienen un límite superior práctico (por ejemplo, algunos algoritmos basados ​​en heurísticas pueden programarse para "darse por vencidos" después de ciertas recursiones, lo que también garantiza la terminación).

Otro resultado de la programación funcional total es que, en principio, tanto la evaluación estricta como la evaluación perezosa dan como resultado el mismo comportamiento; sin embargo, una u otra puede ser preferible (o incluso necesaria) por razones de rendimiento. [4]

En la programación funcional total, se hace una distinción entre datos y codatos : los primeros son finitos , mientras que los segundos son potencialmente infinitos. Estas estructuras de datos potencialmente infinitas se utilizan para aplicaciones como E/S . El uso de codatos implica el uso de operaciones como la corecursion . Sin embargo, es posible realizar E/S en un lenguaje de programación funcional total (con tipos dependientes ) también sin codatos. [5]

Tanto Epigram como Charity podrían considerarse lenguajes de programación totalmente funcionales, aunque no funcionen de la forma que Turner especifica en su artículo. Lo mismo podría decirse de la programación directa en el Sistema F , en la teoría de tipos de Martin-Löf o en el Cálculo de Construcciones .

Véase también

Referencias

  1. ^ Este término se debe a: Turner, DA (diciembre de 1995). Programación funcional elemental fuerte . Primer simposio internacional sobre lenguajes de programación funcional en educación. Springer LNCS. Vol. 1022. págs. 1–13..
  2. ^ ab Turner, DA (28 de julio de 2004), "Programación funcional total", Journal of Universal Computer Science , 10 (7): 751–768, doi :10.3217/jucs-010-07-0751
  3. ^ Turner, DA (28 de abril de 2000), "Cómo garantizar la terminación en ESFP", Journal of Universal Computer Science , 6 (4): 474–488, doi :10.3217/jucs-006-04-0474
  4. ^ Las diferencias entre la evaluación perezosa y la evaluación ansiosa se analizan en: Granström, JG (2011). Tratado sobre la teoría de tipos intuicionista. Lógica, epistemología y la unidad de la ciencia. Vol. 7. ISBN 978-94-007-1735-0.Véanse en particular las páginas 86-91.
  5. ^ Granström, JG (mayo de 2012), "Un nuevo paradigma para el desarrollo basado en componentes", Journal of Software , 7 (5): 1136–1148, doi :10.4304/jsw.7.5.1136-1148[ enlace muerto ] Copia archivada