Un lenguaje de programación que no permite IO. Haskell no es un lenguaje puro

7

¿Existen lenguajes 100% puros (como describo en la publicación Stack Overflow ya disponible, y si es así, ¿podrían usarse para hacer cosas? es decir, tienen una implementación? No estoy buscando matemáticas en bruto en papel / cálculo lambda puro. Sin embargo, el cálculo lambda puro con un compilador o un sistema de tiempo de ejecución adjunto es algo que me interesaría conocer.

    
pregunta TheIronKnuckle 22.11.2011 - 09:28

6 respuestas

20

De hecho, como Simon Peyton Jones dijo una vez, Haskell es el mejor lenguaje imperativo que existe.

En serio, la pureza no es un asunto religioso. El problema no es que existan funciones impuras y datos mutables. El problema en los lenguajes convencionales es que a menudo no se puede decir que lo impuro sea puro y mutable desde inmutable: no mirándolo, ni compilándolo, sino ejecutándolo.

Esta es la gran ventaja que tienen Clean, Haskell (y seguidores como Frege ). A la inversa, los idiomas como F #, Scala o Clojure que abrazan el mundo imperativo y solo agregan la posibilidad de construir algo funcional al mismo tiempo que sufren los mismos problemas que los lenguajes imperativos, aunque pueden parecer muy prácticos.

    
respondido por el Ingo 22.11.2011 - 10:32
9

Me parece que estás intentando reinventar Haskell.

  

El lenguaje no necesita tener efectos secundarios en absoluto. El sistema de tiempo de ejecución lo hace. El compilador / sistema de tiempo de ejecución simplemente necesita buscar la función principal y tratarla como un punto de entrada al programa en su totalidad.

Buena descripción de cómo se hace IO en Haskell.

  

Demonios, tal vez podrías ejecutar hasta que necesites preguntar al usuario, envolver el resto del código como un programa completamente nuevo en el tipo de devolución

¿Quieres decir mónadas?

>>= :: M a -> (a -> M b)

Después de que la primera mitad (M a) solicitó al usuario que proporcione datos (de tipo a), la segunda mitad (a - > M b) es el "resto" que describe.

Si Haskell te permite realizar una introspección de funciones en lugar de solo permitirte ejecutarlas, también sería homoicónico.

    
respondido por el Waquo 22.11.2011 - 13:35
6

Yo consideraría a Haskell como 100% puro. Y ciertamente puede hacer cosas.

Si bien hay algunos buenos debates sobre lo que realmente significa "100% puro", ciertamente no es cierto que un lenguaje funcional puro no pueda hacer IO. Consulte también las comp.lang.functional Preguntas frecuentes .

Todo lo que tiene que hacer para permitir IO en un lenguaje puro es pasar un parámetro que represente el estado del mundo al programa y devolver el estado del mundo como salida. Este programa no tiene efectos secundarios, es referencialmente transparente y cuenta como 100% puro. Esto es más o menos lo que hace Ik Monad de Haskell bajo el capó.

Una mención especial tal vez para Clojure, que es definitivamente un lenguaje práctico con todo el ecosistema JVM y la cadena de herramientas a su alcance. Claramente, no es 100% puro (ya que puede obtener efectos secundarios a través de las referencias administradas de STM, varias funciones de IO o interoperabilidad de Java). Sin embargo, el lenguaje central si evita estos casos especiales es puramente funcional. Entonces, si te limitas al subconjunto puro de Clojure, en realidad tienes un lenguaje funcional puro bastante decente para la mayoría de los propósitos.

    
respondido por el mikera 22.11.2011 - 11:29
4

Un lenguaje "puro" que no podía hacer IO no podía hacer mucho. ... después de todo, incluso imprimir un resultado en la pantalla es IO. Entonces, si no puedes ver el resultado de un programa, ¿no sería algo inútil?

No podías leer archivos, no podías escuchar sockets, no podías interactuar con los usuarios, no podías pedir información, etc. ¿Qué bueno sería?

Dicho esto, Haskell es el más cercano a la programación funcional "pura" (lo que sea que signifique) que conozco. Su sistema completo de IO incluso está hecho con Monads, que es una mezcla de IO y funcional.

También sé de "Limpio", que es un lenguaje académico funcional y ve a IO como una transformación de un objeto de Mundo si recuerdo bien ... sin embargo, esto comienza a ser muy exótico.

    
respondido por el dagnelies 22.11.2011 - 10:31
1

"Lenguaje puramente funcional" es un término bastante confuso. Tomado literalmente, el término significa algo así como "un lenguaje que solo es funcional y nada más". Así que abarca Haskell, ML, Clean, etc .; El esquema se acerca pero no lo logra; y los lenguajes funcionales "impuros" son estrictamente Perl, Scala, JavaScript, etc. --- lenguajes "multi-paradigma" con un buen soporte para la programación funcional. Sin embargo, eso no es claramente lo que la gente quiere decir con "puramente funcional".

La clave es entender que las personas que dicen "lenguaje puramente funcional" realmente quieren decir "lenguaje puramente funcional" --- un lenguaje basado en funciones puras --- y "puramente funcional" es un resbalón de la lengua que es convertirse en convencional El lema es "son las funciones que son puras, no el lenguaje".

Ahora, obviamente, no puede hacer E / S con funciones puras 1 . Esto hace que los lenguajes puramente funcionales sean diferentes de los lenguajes impuros, donde una función como (semántica inventada)

promptForName = do { print "What is your name"; getLine }

podría atribuirse el tipo String -> String . ¡Pero un lenguaje funcional generalmente tendrá muchos otros tipos además de las funciones! ("Puramente funcional" no significa "todo es una función" de la misma manera que " OO puro "significa" todo es un objeto ".) Puedes usar cualquiera de esos tipos para hacer E / S, si es para lo que quieres ese tipo.

Por lo tanto, la mónada IO en Haskell es solo un tipo de datos. Un valor de ese tipo representa una lista de acciones de E / S que debe realizar el programa (básicamente). En tiempo de ejecución, la computadora alterna entre evaluar esa lista un poco más y ejecutar las acciones descritas. ¡Pero la evaluación no hace E / S! Eso sucede después de el valor ya se ha obtenido.

1 Sin definir semántica adicional. Podría decir "un programa es una función de tipo String -> String ; ejecutarlo lee el contenido de STDIN como una cadena (perezosa), aplica la función a esa cadena y escribe el resultado (perezoso) string to STDOUT; pero el punto de entrada es la función only del tipo String -> String en el programa que tiene esa semántica, por lo que no es realmente el tipo de función que hace I / O aquí.

    
respondido por el Jonathan Cast 02.12.2015 - 01:50
1

Puede consultar lenguajes reactivos sincrónicos como Lustre o Señal , por ejemplo. Esos son lenguajes dedicados a la especificación de sistemas reactivos integrados, basados en la programación de flujo de datos.

Usted define funciones que operan en valores a lo largo del tiempo. Esas funciones pueden mantener un estado, en cuyo caso se denominan nodos . En Signal, los nodos y funciones son diferentes tipos de procesos . Pero la forma en que se define el estado es haciendo referencia a los valores anteriores de las variables de flujo.

Entonces, por ejemplo, podría codificar una máquina de estado teniendo una variable interna estado . En cada paso de tiempo, el nuevo estado se define como una función (pura) de las entradas actuales y el estado anterior.

Cuando se trata de compilar esos idiomas en, por ejemplo, C, obtiene variables globales que se sobrescriben dentro de un bucle grande (la aparente antítesis de la programación funcional pura), pero en realidad es perfecto en un contexto donde se requiere la asignación de memoria estática y la ejecución determinista en tiempo de ejecución.

    
respondido por el coredump 22.03.2016 - 21:11

Lea otras preguntas en las etiquetas