¿Qué tanto alboroto sobre Haskell? [cerrado]

109

Conozco algunos programadores que siguen hablando de Haskell cuando están entre ellos, y aquí en SO todo el mundo parece amar ese lenguaje. Ser bueno en Haskell parece algo así como el sello de un programador genio.

¿Alguien puede dar algunos ejemplos de Haskell que demuestren por qué es tan elegante / superior?

Frank
fuente

Respuestas:

134

La forma en que me lo propusieron, y lo que creo que es cierto después de haber trabajado en el aprendizaje de Haskell durante un mes, es el hecho de que la programación funcional tuerce tu cerebro de maneras interesantes: te obliga a pensar en problemas familiares de diferentes maneras. : en lugar de bucles, piense en mapas, pliegues y filtros, etc. En general, si tiene más de una perspectiva sobre un problema, estará mejor capacitado para razonar sobre este problema y cambiar de punto de vista según sea necesario.

La otra cosa realmente interesante de Haskell es su sistema de tipos. Está estrictamente escrito, pero el motor de inferencia de tipos lo hace sentir como un programa de Python que mágicamente le dice cuando ha cometido un error estúpido relacionado con el tipo. Los mensajes de error de Haskell en este sentido son algo deficientes, pero a medida que se familiarice más con el idioma, se dirá a sí mismo: ¡esto es lo que se supone que es escribir!

Edward Z. Yang
fuente
47
Cabe señalar que los mensajes de error de Haskell no faltan, los de ghc sí. El estándar Haskell no especifica cómo se envían los mensajes de error.
PyRulez
Para la plebe como yo, GHC significa Glasgow Haskell Compiler. en.wikipedia.org/wiki/Glasgow_Haskell_Compiler
Lorem Ipsum
137

Este es el ejemplo que me convenció de aprender Haskell (y me alegro de haberlo hecho).

-- program to copy a file --
import System.Environment

main = do
         --read command-line arguments
         [file1, file2] <- getArgs

         --copy file contents
         str <- readFile file1
         writeFile file2 str

Bien, es un programa breve y legible. En ese sentido, es mejor que un programa C. Pero, ¿en qué se diferencia esto de (digamos) un programa de Python con una estructura muy similar?

La respuesta es evaluación perezosa. En la mayoría de los lenguajes (incluso algunos funcionales), un programa estructurado como el anterior daría como resultado que todo el archivo se cargara en la memoria y luego se escribiera nuevamente con un nuevo nombre.

Haskell es "vago". No calcula las cosas hasta que lo necesita y, por extensión , no calcula las cosas que nunca necesita. Por ejemplo, si eliminara la writeFilelínea, Haskell no se molestaría en leer nada del archivo en primer lugar.

Tal como están las cosas, Haskell se da cuenta de que writeFiledepende de readFiley, por lo tanto, puede optimizar esta ruta de datos.

Si bien los resultados dependen del compilador, lo que suele suceder cuando ejecuta el programa anterior es lo siguiente: el programa lee un bloque (digamos 8 KB) del primer archivo, luego lo escribe en el segundo archivo y luego lee otro bloque del primero archivo y lo escribe en el segundo archivo, y así sucesivamente. (¡Intenta ejecutarlo strace!)

... que se parece mucho a lo que haría la implementación eficiente de C de una copia de archivo.

Por lo tanto, Haskell le permite escribir programas compactos y legibles, a menudo sin sacrificar mucho rendimiento.

Otra cosa que debo agregar es que Haskell simplemente dificulta la escritura de programas con errores. El asombroso sistema de tipos, la falta de efectos secundarios y, por supuesto, la compacidad del código Haskell reduce los errores por al menos tres razones:

  1. Mejor diseño de programas. La complejidad reducida conduce a menos errores lógicos.

  2. Código compacto. Menos líneas para que existan errores.

  3. Compila errores. Muchos errores simplemente no son válidos para Haskell .

Haskell no es para todos. Pero todo el mundo debería intentarlo.

Artelius
fuente
¿Cómo cambiaría exactamente la constante de 8 KB (o lo que sea)? Porque apuesto a que una implementación de Haskell sería más lenta que una versión C de otra manera, especialmente sin precarga ...
user541686
1
@Mehrdad Puede cambiar el tamaño del búfer con hSetBuffering handle (BlockBuffering (Just bufferSize)).
David
3
Es sorprendente que esta respuesta tenga 116 votos a favor, pero lo que hay allí es simplemente incorrecto. Este programa va a leer todo el archivo, a menos que utilice cadenas de bytes perezosos (que se puede hacer con Data.Bytestring.Lazy.readFile), que nada tienen que ver con Haskell es un lenguaje vago (no estricto). Las mónadas se están secuenciando , esto significa que aproximadamente "todos los efectos secundarios se realizan cuando se elimina el resultado". En cuanto a la magia de "lazy Bytestring": esto es peligroso, y puedes hacerlo con una sintaxis similar o más simple en la mayoría de los otros lenguajes.
Jo So
14
El viejo estándar aburrido readFiletambién hace IO perezoso de la misma manera que lo Data.ByteString.Lazy.readFilehace. Entonces, la respuesta no es incorrecta y no es simplemente una optimización del compilador. De hecho, esto es parte de la especificación de Haskell : "La readFilefunción lee un archivo y devuelve el contenido del archivo como una cadena. El archivo se lee perezosamente, bajo demanda, como con getContents".
Daniel Wagner
1
Creo que las otras respuestas apuntan a cosas que son más especiales sobre Haskell. Muchos lenguajes / entornos tienen corrientes, se puede hacer algo similar en el Nodo: const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2)). Bash también tiene algo similar:cat $1 > $2
Max Heiber
64

Estás haciendo la pregunta incorrecta.

Haskell no es un lenguaje en el que ves algunos ejemplos interesantes y dices "¡Ajá, ya veo, eso es lo que lo hace bueno!"

Es más bien, tenemos todos estos otros lenguajes de programación, y todos son más o menos similares, y luego está Haskell, que es totalmente diferente y loco de una manera que es totalmente asombrosa una vez que te acostumbras a la locura. Pero el problema es que lleva bastante tiempo aclimatarse a la locura. Cosas que distinguen a Haskell de casi cualquier otro idioma incluso semi-convencional:

  • Evaluación perezosa
  • Sin efectos secundarios (todo es puro, IO / etc ocurre a través de mónadas)
  • Sistema de tipo estático increíblemente expresivo

así como algunos otros aspectos que son diferentes de muchos lenguajes convencionales (pero compartidos por algunos):

  • funcional
  • espacios en blanco significativos
  • tipo inferido

Como han respondido algunos otros carteles, la combinación de todas estas características significa que usted piensa en la programación de una manera completamente diferente. Por eso es difícil encontrar un ejemplo (o un conjunto de ejemplos) que comunique esto adecuadamente a Joe-mainstream-programmer. Es una cosa experiencial. (Para hacer una analogía, puedo mostrarles fotos de mi viaje a China en 1970, pero después de ver las fotos, todavía no sabrán cómo fue haber vivido allí durante ese tiempo. Del mismo modo, puedo mostrarles un Haskell 'clasificación rápida', pero aún no sabrá lo que significa ser un Haskeller).

Brian
fuente
17
No estoy de acuerdo con tu primera oración. Al principio, me impresionaron mucho algunos ejemplos de código Haskell y lo que realmente me convenció de que valía la pena aprenderlo fue este artículo: cs.dartmouth.edu/~doug/powser.html Pero, por supuesto, esto es interesante para un matemático / físico. Un programador que investigue cosas del mundo real encontraría ridículo este ejemplo.
Rafael S. Calsaverini
2
@Rafael: Eso plantea la pregunta "¿Qué le impresionaría a un programador que investiga cosas del mundo real"?
JD
¡Buena pregunta! No soy un programador del "mundo real", así que no sé qué les gusta. jajaja ... sé lo que les gusta a los físicos y matemáticos. : P
Rafael S. Calsaverini
27

Lo que realmente distingue a Haskell es el esfuerzo que hace en su diseño para hacer cumplir la programación funcional. Puede programar con un estilo funcional en prácticamente cualquier idioma, pero es muy fácil abandonarlo a la primera comodidad. Haskell no te permite abandonar la programación funcional, por lo que debes llevarlo a su conclusión lógica, que es un programa final sobre el que es más fácil razonar y esquiva toda una clase de los tipos de errores más espinosos.

Cuando se trata de escribir un programa para uso en el mundo real, es posible que a Haskell le falte algo práctico, pero tu solución final será mejor por haber conocido a Haskell desde el principio. Definitivamente no he llegado a ese punto todavía, pero hasta ahora aprender Haskell ha sido mucho más esclarecedor que decir que Lisp estaba en la universidad.

gtd
fuente
1
Bueno, siempre existe la posibilidad de usar siempre y solo la mónada ST y / o unsafePerformIOpara las personas que solo quieren ver arder el mundo;)
sara
22

Parte del alboroto es que la pureza y la escritura estática permiten el paralelismo combinado con optimizaciones agresivas. Los lenguajes paralelos están de moda ahora y el multinúcleo es un poco disruptivo.

Haskell le ofrece más opciones de paralelismo que prácticamente cualquier lenguaje de propósito general, junto con un compilador de código nativo rápido. Realmente no hay competencia con este tipo de soporte para estilos paralelos:

Entonces, si le interesa hacer que su multinúcleo funcione, Haskell tiene algo que decir. Un buen lugar para comenzar es con el tutorial de Simon Peyton Jones sobre programación paralela y concurrente en Haskell .

Don Stewart
fuente
"junto con un compilador de código nativo rápido"?
JD
Creo que dons se refiere a GHCI.
Gregory Higley
3
@Jon: shootout.alioth.debian.org/u32/… Haskell lo hace bastante bien en los tiroteos, por ejemplo.
Peaker
4
@Jon: El código de shootout es muy antiguo, y de un pasado lejano donde GHC era menos un compilador optimizador. Aún así, demuestra que el código de Haskell puede ser de bajo nivel para producir rendimiento, si es necesario. Las nuevas soluciones en el tiroteo son más idiomáticas y aún más rápidas.
Peaker
1
@GregoryHigley Hay una diferencia entre GHCI y GHC.
Jeremy List
18

La memoria transaccional de software es una forma genial de lidiar con la concurrencia. Es mucho más flexible que el paso de mensajes y no es propenso a bloqueos como los mutex. La implementación de STM de GHC se considera una de las mejores.

bmdhacks
fuente
18

Pasé el último año aprendiendo Haskell y escribiendo un proyecto bastante grande y complejo en él. (El proyecto es un sistema de comercio de opciones automatizado, y todo, desde los algoritmos de comercio hasta el análisis y el manejo de datos de mercado de bajo nivel y alta velocidad, se realiza en Haskell). Es considerablemente más conciso y más fácil de entender (para aquellos con antecedentes apropiados) de lo que sería una versión de Java, además de extremadamente robusta.

Posiblemente, la mayor ganancia para mí ha sido la capacidad de modularizar el flujo de control a través de cosas como monoides, mónadas, etc. Un ejemplo muy simple sería el monoide Ordering; en una expresión como

c1 `mappend` c2 `mappend` c3

donde c1y así sucesivamente retorno LT, EQo GT, c1volviendo EQcausas la expresión de continuar, la evaluación c2; si c2devuelve LTo GTese es el valor del todo, y c3no se evalúa. Este tipo de cosas se vuelve considerablemente más sofisticado y complejo en cosas como generadores de mensajes monádicos y analizadores sintácticos en los que puedo tener diferentes tipos de estado, tener diferentes condiciones de aborto o puede querer poder decidir para cualquier llamada en particular si abortar realmente significa "Sin procesamiento adicional" o significa "devolver un error al final, pero continuar con el procesamiento para recopilar más mensajes de error".

Todo esto es algo que lleva algo de tiempo y probablemente bastante esfuerzo para aprender, por lo que puede ser difícil presentar un argumento convincente para aquellos que aún no conocen estas técnicas. Creo que el tutorial de All About Monads ofrece una demostración bastante impresionante de una faceta de esto, pero no esperaría que alguien que no esté familiarizado con el material ya lo "entienda" en la primera, o incluso en la tercera, lectura cuidadosa.

De todos modos, también hay muchas otras cosas buenas en Haskell, pero esta es una de las principales que no veo que se mencione tan a menudo, probablemente porque es bastante complejo.

Curt J. Sampson
fuente
2
¡Muy interesante! ¿Cuántas líneas de código Haskell entraron en su sistema de comercio automatizado en total? ¿Cómo manejó la tolerancia a fallas y qué tipo de resultados de desempeño obtuvo? He estado pensando recientemente que Haskell tiene el potencial de ser bueno para la programación de baja latencia ...
JD
12

Para ver un ejemplo interesante, puede consultar: http://en.literateprograms.org/Quicksort_(Haskell)

Lo interesante es observar la implementación en varios idiomas.

Lo que hace que Haskell sea tan interesante, junto con otros lenguajes funcionales, es el hecho de que tienes que pensar de manera diferente sobre cómo programar. Por ejemplo, generalmente no usará bucles for o while, pero usará la recursividad.

Como se mencionó anteriormente, Haskell y otros lenguajes funcionales sobresalen con aplicaciones de escritura y procesamiento en paralelo para trabajar en múltiples núcleos.

James Black
fuente
2
la recursividad es la bomba. eso y la coincidencia de patrones.
Ellery Newcomer
1
Deshacerme de los bucles for y while es la parte más difícil para mí cuando escribo en un lenguaje funcional. :)
James Black
4
Aprender a pensar en recursividad en lugar de en bucles también fue la parte más difícil para mí. Cuando finalmente se asimiló, fue una de las mejores epifanías de programación que he tenido.
Chris Connett
8
Excepto que el programador Haskell que trabaja rara vez usa la recursividad primitiva; la mayoría de las veces usa funciones de biblioteca como map y foldr.
Paul Johnson
18
Encuentro más interesante que el algoritmo de ordenación rápida original de Hoare se bastardizó en esta forma basada en listas fuera de lugar aparentemente para que las implementaciones inútilmente ineficientes pudieran escribirse "elegantemente" en Haskell. Si intenta escribir una selección rápida real (en el lugar) en Haskell, encontrará que es horrible como el infierno. Si intenta escribir una ordenación rápida genérica de rendimiento competitivo en Haskell, encontrará que en realidad es imposible debido a errores de larga data en el recolector de basura de GHC. Aclamando a quicksort como un buen ejemplo de Haskell mendiga la fe, en mi humilde opinión.
JD
8

No podría darte un ejemplo, soy un chico de OCaml, pero cuando estoy en una situación como la tuya, la curiosidad simplemente se apodera de ti y tengo que descargar un compilador / intérprete y probarlo. Probablemente aprenderá mucho más de esa manera sobre las fortalezas y debilidades de un lenguaje funcional dado.

maxaposteriori
fuente
1
No olvide leer el código fuente del compilador. Eso también le dará mucha información valiosa.
JD
7

Una cosa que encuentro muy interesante cuando trato con algoritmos o problemas matemáticos es la evaluación inherente y perezosa de los cálculos de Haskell, que solo es posible debido a su estricta naturaleza funcional.

Por ejemplo, si desea calcular todos los números primos, puede usar

primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0]

y el resultado es en realidad una lista infinita. Pero Haskell lo evaluará de izquierda a derecha, por lo que siempre que no intente hacer algo que requiera la lista completa, aún puede usarlo sin que el programa se atasque en el infinito, como:

foo = sum $ takeWhile (<100) primes

que suma todos los números primos menos de 100. Esto es bueno por varias razones. En primer lugar, solo necesito escribir una función principal que genere todos los números primos y luego estoy prácticamente listo para trabajar con números primos. En un lenguaje de programación orientado a objetos, necesitaría alguna forma de decirle a la función cuántos números primos debería calcular antes de regresar, o emular el comportamiento de la lista infinita con un objeto. Otra cosa es que, en general, terminas escribiendo código que expresa lo que quieres calcular y no en qué orden evaluar las cosas; en cambio, el compilador lo hace por ti.

Esto no solo es útil para listas infinitas, de hecho se usa sin que usted lo sepa todo el tiempo cuando no hay necesidad de evaluar más de lo necesario.

waxwing
fuente
2
Esto no es del todo cierto; Con el comportamiento de retorno de rendimiento de C # (un lenguaje orientado a objetos), también puede declarar listas infinitas que se evalúan bajo demanda.
Jeff Yates
2
Buen punto. Tiene usted razón y debería evitar decir lo que se puede y no se puede hacer en otros idiomas de manera tan categórica. Creo que mi ejemplo fue defectuoso, pero sigo pensando que se gana algo con la forma perezosa de evaluación de Haskell: realmente está ahí de forma predeterminada y sin ningún esfuerzo por parte del programador. Y esto, creo, se debe a su naturaleza funcional y a la ausencia de efectos secundarios.
Waxwing
8
Quizás le interese leer por qué "tamiz" no es el tamiz de Eratosthenes: lambda-the-ultimate.org/node/3127
Chris Conway
@Chris: Gracias, ¡ese fue un artículo bastante interesante! La función de primos anterior no es la que he estado usando para mis propios cálculos, ya que es terriblemente lenta. Sin embargo, el artículo trae un buen punto de que verificar todos los números para el mod es realmente un algoritmo diferente.
Waxwing
6

Estoy de acuerdo con otros en que ver algunos pequeños ejemplos no es la mejor manera de mostrar a Haskell. Pero daré algunos de todos modos. Aquí hay una solución ultrarrápida para los problemas 18 y 67 del Proyecto Euler , que le piden que encuentre la ruta de suma máxima desde la base hasta el vértice de un triángulo:

bottomUp :: (Ord a, Num a) => [[a]] -> a
bottomUp = head . bu
  where bu [bottom]     = bottom
        bu (row : base) = merge row $ bu base
        merge [] [_] = []
        merge (x:xs) (y1:y2:ys) = x + max y1 y2 : merge xs (y2:ys)

Aquí hay una implementación completa y reutilizable del algoritmo BubbleSearch de Lesh y Mitzenmacher. Lo usé para empaquetar archivos multimedia grandes para el almacenamiento de archivos en DVD sin desperdicio:

data BubbleResult i o = BubbleResult { bestResult :: o
                                     , result :: o
                                     , leftoverRandoms :: [Double]
                                     }
bubbleSearch :: (Ord result) =>
                ([a] -> result) ->       -- greedy search algorithm
                Double ->                -- probability
                [a] ->                   -- list of items to be searched
                [Double] ->              -- list of random numbers
                [BubbleResult a result]  -- monotone list of results
bubbleSearch search p startOrder rs = bubble startOrder rs
    where bubble order rs = BubbleResult answer answer rs : walk tries
            where answer = search order
                  tries  = perturbations p order rs
                  walk ((order, rs) : rest) =
                      if result > answer then bubble order rs
                      else BubbleResult answer result rs : walk rest
                    where result = search order

perturbations :: Double -> [a] -> [Double] -> [([a], [Double])]
perturbations p xs rs = xr' : perturbations p xs (snd xr')
    where xr' = perturb xs rs
          perturb :: [a] -> [Double] -> ([a], [Double])
          perturb xs rs = shift_all p [] xs rs

shift_all p new' [] rs = (reverse new', rs)
shift_all p new' old rs = shift_one new' old rs (shift_all p)
  where shift_one :: [a] -> [a] -> [Double] -> ([a]->[a]->[Double]->b) -> b
        shift_one new' xs rs k = shift new' [] xs rs
          where shift new' prev' [x] rs = k (x:new') (reverse prev') rs
                shift new' prev' (x:xs) (r:rs) 
                    | r <= p    = k (x:new') (prev' `revApp` xs) rs
                    | otherwise = shift new' (x:prev') xs rs
                revApp xs ys = foldl (flip (:)) ys xs

Estoy seguro de que este código parece un galimatías aleatorio. Pero si lee la entrada del blog de Mitzenmacher y comprende el algoritmo, se sorprenderá de que sea posible empaquetar el algoritmo en código sin decir nada sobre lo que está buscando.

Habiéndole dado algunos ejemplos tal como me pidió, diré que la mejor manera de comenzar a apreciar a Haskell es leer el documento que me dio las ideas que necesitaba para escribir el paquete de DVD: Por qué la programación funcional es importante por John Hughes. El documento en realidad es anterior a Haskell, pero explica brillantemente algunas de las ideas que hacen que la gente le guste Haskell.

Norman Ramsey
fuente
5

Para mí, el atractivo de Haskell es la promesa de una exactitud garantizada por el compilador . Incluso si es para partes puras del código.

He escrito una gran cantidad de código de simulación científica, y he preguntado por lo que muchas veces si hubo un error en mis códigos anteriores, lo que podría invalidar una gran cantidad de trabajo actual.

rpg
fuente
6
¿Cómo garantiza la corrección?
Jonathan Fischoff
Las partes puras del código son mucho más seguras que las impuras. El nivel de confianza / esfuerzo invertido es mucho mayor.
rpg
1
qué te dio esa impresión?
JD
5

Encuentro que para ciertas tareas soy increíblemente productivo con Haskell.

La razón es por la sintaxis sucinta y la facilidad de prueba.

Así es la sintaxis de declaración de función:

foo a = a + 5

Esa es la forma más sencilla en la que puedo pensar en definir una función.

Si escribo la inversa

inverseFoo a = a - 5

Puedo verificar que sea inverso para cualquier entrada aleatoria escribiendo

prop_IsInverse :: Double -> Bool
prop_IsInverse a = a == (inverseFoo $ foo a)

Y llamando desde la línea de comando

jonny @ ubuntu: runhaskell quickCheck + nombres fooFileName.hs

Lo que verificará que todas las propiedades de mi archivo se mantengan, probando aleatoriamente las entradas cien veces.

No creo que Haskell sea el lenguaje perfecto para todo, pero cuando se trata de escribir pequeñas funciones y probar, no he visto nada mejor. Si su programación tiene un componente matemático, esto es muy importante.

Jonathan Fischoff
fuente
¿Qué problemas estás resolviendo y qué otros idiomas has probado?
JD
1
Gráficos 3D en tiempo real para el móvil y el iPad.
Jonathan Fischoff
3

Si puede entender el sistema de tipos en Haskell, creo que en sí mismo es un gran logro.

Dr. Watson
fuente
1
¿Qué hay que conseguir? Si es necesario, piense en "datos" == "clase" y "clase de tipo" = "interfaz" / "rol" / "rasgo". No puede ser más sencillo. (Ni siquiera hay "nulo" para estropearlo. Nulo es un concepto que puede incorporar a su tipo usted mismo.)
jrockway
8
Hay mucho que conseguir, jrockway. Si bien usted y yo lo encontramos relativamente sencillo, muchas personas, incluso muchos desarrolladores, encuentran ciertos tipos de abstracciones muy difíciles de entender. Conozco a muchos desarrolladores que todavía no comprenden la idea de punteros y referencias en lenguajes más convencionales, a pesar de que los usan todos los días.
Gregory Higley
2

no tiene construcciones de bucle. no muchos idiomas tienen este rasgo.

Badri
fuente
17
ghci>: m + Control.Monad ghci> forM_ [1..3] print 1 2 3
sastanin
1

Estoy de acuerdo con aquellos que dicen que la programación funcional tuerce su cerebro para que vea la programación desde un ángulo diferente. Solo lo he usado como aficionado, pero creo que cambió fundamentalmente la forma en que abordo un problema. No creo que hubiera sido tan efectivo con LINQ sin haber estado expuesto a Haskell (y usando generadores y listas de comprensión en Python).

Jacob
fuente
-1

Para ventilar una visión contraria: Steve Yegge escribe que los lenguajes Hindely-Milner carecen de la flexibilidad necesaria para escribir buenos sistemas :

HM es muy bonito, en un sentido matemático formal totalmente inútil. Maneja muy bien algunas construcciones de cálculo; el envío de coincidencia de patrones que se encuentra en Haskell, SML y OCaml es particularmente útil. Como era de esperar, maneja algunas otras construcciones comunes y altamente deseables de manera incómoda en el mejor de los casos, pero explican esos escenarios diciendo que estás equivocado, que en realidad no los quieres. Ya sabes, cosas como, oh, establecer variables.

Vale la pena aprender Haskell, pero tiene sus propias debilidades.

RossFabricante
fuente
5
Si bien es cierto que los sistemas de tipos fuertes generalmente requieren que se adhiera a ellos (eso es lo que hace que su fortaleza sea útil), también es cierto que muchos (¿la mayoría?) De los sistemas de tipos basados ​​en HM existentes tienen, de hecho, algún tipo de ' escape hatch 'como se describe en el enlace (tome Obj.magic en O'Caml como ejemplo, aunque nunca lo he usado excepto como un truco); en la práctica, sin embargo, para muchos tipos de programas, nunca se necesita tal dispositivo.
Zach Snow
3
La cuestión de si el establecimiento de variables es "deseable" depende de cuánto dolor es usar los constructos alternativos frente a cuánto dolor es causado por el uso de variables. Eso no es para descartar todo el argumento, sino más bien para señalar que tomar la afirmación "las variables son una construcción muy deseable" como axioma no es la base de un argumento convincente. Resulta que es la forma en que la mayoría de la gente aprende a programar.
gtd
5
-1: Las declaraciones de Steve están en parte desactualizadas, pero en su mayoría están completamente equivocadas en los hechos. La restricción de valor relajada de OCaml y el sistema de tipos de .NET son algunos ejemplos obvios en contra de sus declaraciones.
JD
4
Steve Yegge tiene una abeja irrazonable en su capó sobre la escritura estática, y no solo la mayor parte de lo que dice al respecto es incorrecto, sino que también lo menciona en cada oportunidad disponible (e incluso en algunas no disponibles). Haría bien en confiar únicamente en su propia experiencia a este respecto.
ShreevatsaR
3
Aunque no estoy de acuerdo con Yegge sobre la escritura estática frente a la dinámica, Haskell tiene el tipo Data.Dynamic. Si desea escritura dinámica, ¡puede tenerla!
jrockway