programacion funciones funcional ejemplos scala f# functional-programming

scala - funciones - Casos de uso no numéricos para la programación funcional?



programacion funcional (18)

Acabo de terminar de leer un libro sobre Scala. Lo que me sorprende es que cada ejemplo en todo el libro fue numérico de una forma u otra.

Al igual que muchos programadores, la única matemática que uso es de matemáticas discretas y combinatorias, y generalmente eso no es matemática. Programo de manera explícita. Realmente me faltan algunos ejemplos convincentes de alternativas / suplementos funcionales a los algoritmos regulares de oo.

¿Cuáles son algunos casos de uso no numéricos para la programación funcional?


Echa un vistazo al procesamiento de textos en Python . El libro comienza con algunos ejemplos simples pero bien motivados donde las técnicas de programación funcional hacen que el código sea más fácil de leer y más probable que sea correcto.


LINQ toma muchas señales de la programación funcional. Echar un vistazo a cómo se implementa un proveedor de LINQ arbitrario podría proporcionarle algunos conocimientos prácticos.


La coincidencia de patrones también es un lugar donde brilla la programación funcional, por lo que es realmente útil en áreas como la Bioinformática.

Sin embargo, dados los excelentes compiladores que tenemos hoy, la programación funcional brilla en casi todos lados.


La programación funcional es un paradigma como procedimental / estructurado, orientado a objetos y programación genérica / plantilla. Es muy completo para que puedas hacer lo que quieras.

Además de las matemáticas y las ciencias, facilita la combinación de analizadores sintácticos, la inteligencia artificial, la concurrencia, la evaluación dinámica, las co-rutinas, las continuas, la notación concisa (ciclo más rápido de cerebro a teclado y texto y menos código que mantener) , parametización fuertemente tipada (ver tipos algebraicos de Haskell) y autorreflexión dinámica (por ejemplo, intérpretes metacirculares minimalistas con REPL).


Mi empresa me pidió que escribiera una aplicación personalizada que permitiera a los usuarios realizar consultas ad hoc en una base de datos de archivos planos. Los usuarios de esta aplicación eran sus tipos típicos de Joe Empresario. No son programadores, y es poco probable que hayan visto una declaración SQL en sus vidas.

Como resultado, tuve la tarea de desarrollar una interfaz de usuario amigable que permitiera a los usuarios seleccionar columnas, tablas, condiciones, etc. para crear una consulta. Esto es un desafío porque puedo representar la declaración de SQL en la interfaz de usuario sin crear primero una representación abstracta de la misma en la memoria.

La primera iteración fue escrita en C #. Creé una clase de carga de bote para representar la sintaxis abstracta de una declaración de SQL, lo que resultó en un modelo de objetos realmente engorroso:

  • a Unirse a clase, una clase de colección Uniones
  • una clase WhereClause, una clase de colección WhereClauses
  • una clase SelectedColumn, clase de colección SelectedColumns
  • una clase OrderBy, colección de colecciones OrderBy
  • una clase SqlStatement que agrupó todas las clases mencionadas anteriormente

La conversión de una instancia de SqlStatement a una cadena fue gloriosamente dolorosa, fea y problemática. Mover la dirección opuesta, de cadena a SqlStatement, fue aún peor, ya que rompió las piezas de una cadena de SQL utilizando mucha manipulación de expresiones regulares y cadenas.

Arreglé el sistema, produje una aplicación que funcionó, pero no estaba muy contenta con eso. Especialmente no sucedió cuando los requisitos comerciales de la aplicación cambiaron en mí, lo que me obligó a volver a visitar mi código C #.

Solo como experimento, reescribí mi SqlStatement en F # y lo representé como una unión:

type dir = Asc | Desc type op = Eq | Gt | Gte | Lt | Lte type join = Inner | Left | Right type sqlStatement = | SelectedColumns of string list | Joins of (string * join) list | Wheres of (string * op * string) list | OrderBys of (string * dir) list type query = SelectedColumns * Joins * Wheres * OrderBys

Esa pequeña cantidad de código reemplazó unos cientos de líneas de C # y una docena de clases. Más importante aún, la coincidencia de patrones simplificó el proceso requerido para convertir la representación abstracta en una cadena SQL.

La parte divertida fue convertir una cadena SQL de nuevo en un objeto de consulta utilizando fslex / fsyacc.

Si mal no recuerdo, el código original de C # totalizó 600 líneas y alrededor de una docena de clases, muchas expresiones regulares confusas y requirió dos días para escribir y probar. En comparación, el código F # consistía en un archivo .fs de alrededor de 40 líneas, 100 líneas más o menos para implementar el analizador / analizador lexer, y consumía algunas horas de mi día para probar.

En serio, escribir esta parte de la aplicación en F # fue como hacer trampa, así de trivialmente fácil.




Verifique " Estructuras de datos puramente funcionales " (y aquí está la tesis doctoral que inspiró el libro).

Muestran cómo se pueden crear estructuras de datos estándar en lenguajes puramente funcionales (sin efectos secundarios). Luego puede usarlos para programar cualquier cosa.

Descargo de responsabilidad: Estoy haciendo un Atwood aquí, apenas he leído un par de reseñas del libro y he echado un vistazo a la tesis, está en mi lista de temas pendientes.


"Comenzando con Erlang" tiene un extenso ejemplo de cliente / servidor (comenzando en la Sección 1.3.5) que puede adaptarse a sus necesidades.


Es cierto que muchos libros sobre programación funcional usan "programación numérica" ​​para enseñar, pero hay excepciones.

Haskell School of Expression es un libro para principiantes sobre Haskell que utiliza la multimedia como su vehículo para la enseñanza.

Real World Haskell en realidad no tiene ningún vehículo en particular a lo largo de todo el libro, pero hay varios capítulos que cubren la escritura de programas "reales" en un estilo funcional.


El mejor ejemplo específico que puedo dar es StringTemplate , un motor de plantillas utilizado (entre muchos otros lugares) en el generador de analizadores ANTLR.

En un artículo sobre el diseño y desarrollo de StringTemplate, Terence Parr escribió que originalmente era escéptico de la programación funcional, y se rió de sí mismo cuando se dio cuenta de que StringTemplate era esencialmente un lenguaje funcional para generar texto.


Reducción de la brecha del algoritmo: un programa funcional de tiempo lineal para el formateo de párrafos (1997)
por Oege De Moor, Jeremy Gibbons
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.7923

Estructuración de paradigmas gráficos en TkGofer (1997) por Koen Claessen, Ton Vullinghs, Erik Meijer http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.5525

Modelado de procesos de oficina con analizadores funcionales (1994) por Gert Florijn
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.1307


Tengo otro para ti:

Estoy involucrado en las primeras etapas de la creación de prototipos de un conjunto de nuevos productos financieros a escala empresarial destinados a bancos pequeños y medianos, gobiernos locales, bolsas de valores, etc. Probablemente esté pensando "oh, código financiero, usted debe estar haciendo un montón de matemáticas "- en realidad, no. Estos productos están destinados a ser altamente personalizables y permiten a los usuarios implementar reglas comerciales en puntos estratégicos de la aplicación.

Estamos usando F # para representar e interpretar las reglas comerciales. Para usar un ejemplo ingenuo, vamos a escribir un código para el procesamiento de cheques, podríamos escribir las reglas de esta manera:

type condition = | Test of string | And of condition * condition | Or of condition * condition | Not of condition type transactionWorkflow = | Reject | Approve | AdministratorOverride of string | If of condition * transactionWorkflow list (* condition, true condition *) | IfElse of condition * transactionWorkflow list * transactionWorkflow list (* condition, true condition, false condition *) | AttachForms of string list

Usando una aplicación especial, los usuarios pueden escribir algunas reglas comerciales representadas por la estructura anterior. Por ejemplo:

let checkProcessingWorkflow = [If(Test("account doesn''t exist") ,[AdministratorOverride("Account doesn''t exist. Continue?"); AttachForms ["40808A - Null Account Deposit"]] ); If(Test("deposit > 10000") ,[ If(And(Test("account created within 3 months") ,Test("out of country check")) ,[Reject]); IfElse(Test("account state = TX") ,[AttachForms ["16A"; "16B"]] ,[AttachForms ["1018"]] ) ] ); Approve ]

Entonces, en lugar de escribir un motor de reglas de negocio para gobernarlos todos, manejamos ciertos procesos como un lenguaje específico de dominio muy pequeño interpretado por F #. Espero que este enfoque nos permita diseñar DSL legibles por negocios muy simples sin necesidad de detectar reglas conflictivas.

Por supuesto, todo lo anterior es solo un código conceptual, y todavía estamos en las primeras etapas de crear un prototipo de uno de nuestros sistemas de reglas. Estamos usando F # en lugar de Java o C # por una razón en particular: coincidencia de patrones.


Hoy en día, ni siquiera consideraría escribir un lector / analizador de DSL en un lenguaje no funcional (en un sentido amplio del término). Los ADT y la coincidencia de patrones lo hacen mucho más fácil.


Para aquellos que consideran que LISP es un lenguaje de programación funcional, hay un servidor http escrito en común lisp, presentado en un documento de 1994 y aún en desarrollo en 2006:

para cosas más modernas, es posible que desee preguntar a google "servidor web haskell", probablemente encontrará algunos ejemplos interesantes. uno dirígeme a encontrar este sitio: http://code.haskell.org/ .


Ted Neward escribió un artículo de 10 partes sobre Scala, dirigido a programadores de Java, y la serie terminó con la escritura de un DSL en Scala. Esta DSL en particular es en realidad una calculadora numérica, pero eso no es lo interesante, es la forma en que la DSL se puede ensamblar fácilmente en un lenguaje funcional

Parte 1

Parte 2

Part3


¡Pregunta realmente interesante porque pensé que era el único autor que escribía libros sobre programación funcional para numéricos!

La programación funcional se ha usado históricamente mucho más comúnmente para la metaprogramación, es decir, programas de escritura que manipulan otros programas. Esto incluye intérpretes y compiladores (por ejemplo, para DSL), así como aplicaciones más esotéricas como demostradores de teoremas (Coq, Isabelle) y sistemas de reescritura de términos (por ejemplo, sistemas de álgebra computacional como Mathematica). La familia de idiomas Meta Language (ML) se diseñó específicamente para esto.


Cuanto más uso un estilo funcional, mejor me gusta. Considera este fragmento de Python de otra pregunta :

>>> testlist [1, 2, 3, 5, 3, 1, 2, 1, 6] >>> [i for i,x in enumerate(testlist) if x == 1] [0, 5, 7]

Esta es una afirmación más o menos matemática, pero hay muchos generadores en Python. Una vez que te acostumbras, usar una lista de comprensión en lugar de un bucle es fácil de entender y es menos probable que tenga un error (no se obtienen errores "desactualizados").