2012-05-28 14 views
11

He oído que hay una rama de GHC que compila a código estricto por defecto, mientras que la pereza se puede habilitar mediante anotación. (IIRC, dijo que una compañía financiera desarrolla la sucursal y la usa para el código de producción). ¿Es eso cierto? No puedo encontrarlorama no vago de GHC

La persona también sugirió que la opinión de que la evaluación estricta es más práctica que la evaluación perezosa (de manera predeterminada) gana aceptación cada vez más. No encuentro esto confirmado en la lista de correo de Haskell, pero tal vez eso se deba a que la gente no está orientada a la práctica.

Todo lo que encuentro en Haskell estricto son cosas explícitas como $! y rnf. Aunque considero que la evaluación perezosa es muy elegante, me gustaría desarrollar un programa en Haskell en el que quiera evitar fugas de espacio y me gustaría tener un rendimiento predecible.

Descargo de responsabilidad: No estoy defendiendo el rigor, solo me gustaría echarle un vistazo al estricto Haskell o algo así.

+0

Tengo curiosidad - ¿Qué sorpresas groseros te topaste? –

+1

Por (la expresión ciertamente estúpida) groseras surpise quise decir fugas de espacio e imprevisibilidad de tiempo de ejecución. En realidad, no me he encontrado con ellos, pero me parece que estos problemas son reales, ¿verdad? (En este momento estoy evaluando qué idioma usar). – chs

+2

Creo que esto podría llamarse 'Mu'? Lennart Augustsson puede haberlo mencionado en alguna parte. – jtobin

Respuesta

12

Está buscando Disciple.

Así que hay dos tipos de pereza para distinguir en Haskell. Hay E/S perezosa, que es una abominación y se resuelve con las bibliotecas de iteratee (plug Shameless: incluida mi biblioteca pipes). Luego está la pereza en los cálculos puros, que sigue siendo objeto de debate, pero voy a tratar de resumir las principales ventajas de la pereza, puesto que ya está familiarizado con el inconveniente:

pereza es más eficiente

Un ejemplo sencillo es:

any = foldr (||) False 

any encuentra o ningún valor en una lista es True. Esto solo evalúa los elementos hasta el primer True, por lo que no importa si la lista es muy larga.

La pereza solo computa todo lo que tiene que hacer, lo que significa que si encadena dos cálculos perezosos, puede mejorar la complejidad del tiempo del cálculo resultante. This Stack Overflow comment da otro buen ejemplo de esto.

Esta es en realidad la misma razón por la que las bibliotecas iteratee son muy eficientes en el uso de los recursos. Solo hacen todo el trabajo que tienen para generar resultados, y esto lleva a una memoria y uso del disco muy eficientes con una semántica muy fácil de usar.

pereza es inherentemente más componibles

Esto es bien conocido por las personas que han programado en los dos idiomas estrictas y funcionales, pero en realidad inadvertidamente demostrado una prueba limitada de este mientras se trabaja en la biblioteca pipes, donde el La versión perezosa es la única versión que permite una instancia Category. Las tuberías realmente funcionan en cualquier mónada, incluida la mónada pura Identity, por lo que mis pruebas también se traducen en código puro.

Esta es la verdadera razón por la que creo que la pereza en general es realmente el futuro de la programación, sin embargo, todavía creo que es una pregunta abierta si Haskell implementó o no la pereza "a la derecha".

+0

Una conferencia en video que trata este tema muy bien está disponible gratuitamente [aquí] (http://videoag.fsmpi.rwth-aachen.de/?view=player&videoid=2034#content). (Nota: el video está en inglés, y no tengo ninguna asociación con el video o la universidad en Aquisgrán) – dflemstr

+2

Creo que la principal ventaja de la pereza es que proporciona flexibilidad y una separación de preocupaciones. También es necesario como predeterminado en un idioma que quiere ser considerado declarativo. En el haskell ideal, su modelo de evaluación sería simplemente un detalle de implementación. – jberryman

+0

@jberryman Correcto, y lo que estaba tratando de decir es que esta intuición de "flexibilidad" y "separación de preocupaciones" puede ser rigurosa simplemente diciendo que solo la pereza forma una Categoría. –

1

Si lo entiendo correctamente, un Haskell estricto no podría tener E/S monádica tal como la conocemos.La idea en Haskell es que todo el código Haskell es puro (que incluye acciones IO, que funcionan como la mónada de estado) y "principal" da un valor de tipo IO() al tiempo de ejecución que fuerza repetidamente en el operador de secuenciación >> = .

Para un contrapunto a la publicación de Tekmo puede consultar el blog de Robert Harper, * http://existentialtype.wordpress.com/2011/04/24/the-real-point-of-laziness/ y relacionado. Va en ambos sentidos.

En mi experiencia, la pereza es difícil al principio, pero luego te acostumbras y está bien.

La pieza clásica de defensa para la pereza es el documento de Hughes "Por qué la programación funcional es importante", que debería poder encontrar fácilmente.

+5

Monadic IO no depende de la pereza. – is7s

+0

No necesita forzar en '>> ='; 'getLine >> = putStrLn' es una expresión perfectamente autónoma que produce una acción que hace lo que dice, y puede evaluarla completamente antes de que realmente se realice la acción de IO. – Ashe

3

Se han dicho algunas cosas buenas acerca de por qué no debe rehuir la flojera de Haskell, pero creo que la pregunta original sigue sin respuesta.

La aplicación de funciones en Haskell no es estricta; es decir, un argumento de función se evalúa solo cuando es necesario.

~ Haskell Report 2010 > Predefined Types and Classes # Strict Evaluation

Esto es un poco engañoso, sin embargo. Las implementaciones pueden evaluar los argumentos de la función antes de que sean necesarios, pero solo de forma limitada. Debe preservar la semántica no estricta: de modo que si la expresión de un argumento da como resultado un bucle infinito, y ese argumento no se utiliza, entonces una llamada a función con ese argumento no debe tener un bucle infinito.

Así que usted tiene permitido implementar Haskell de una manera que no es completamente "Lazy", pero tampoco puede ser "Estricto". Esto parece una contradicción a primera vista, pero no lo es. Unos temas relacionados es posible que desee comprobar hacia fuera:

  • Eager Haskell, una implementación del lenguaje de programación Haskell que por defecto utiliza la evaluación ansiosos. Creo que esto es en lo que estabas pensando (aunque no es una rama de GHC).
  • Speculative Execution y Paralelismo especulativo (consulte, por ejemplo, el paquete speculation).
  • Optimistic Evaluation, un documento de SPJ sobre la aceleración de GHC con optimizaciones de rigor.
4

Parece que ha oído hablar de Robert Ennals 'PhD thesis on speculative evaluation con GHC. Creó un tenedor de GHC llamado fork "spec_eval", donde se realizó la evaluación especulativa. Debido a que Haskell no es estricto en lugar de ser explícitamente vago, spec_eval fue estricto hasta el punto donde realmente hizo la diferencia. Si bien fue más rápido en todos los casos, requirió grandes cambios a GHC y nunca se fusionó.

Esta pregunta tiene un tipo de been answered before en este sitio.