Haskell o ML estándar para principiantes? [cerrado]


Voy a enseñar un curso de división inferior en estructuras discretas. He seleccionado el libro de texto Discrete Structures, Logic, and Computability en parte porque contiene ejemplos y conceptos que son conducentes a la implementación con un lenguaje de programación funcional. (También creo que es un buen libro de texto.)

Quiero un lenguaje FP fácil de entender para ilustrar los conceptos de DS y que los estudiantes puedan usar. La mayoría de los estudiantes habrán tenido solo uno o dos semestres de programación en Java, en el mejor. Después de mirar a Scheme, Erlang, Haskell, Ocaml y SML, me he decidido por Haskell o ML Estándar. Me inclino por Haskell por las razones que se describen a continuación, pero me gustaría la opinión de aquellos que son programadores activos en uno u otro.

  • Tanto Haskell como SML tienen coincidencia de patrones que hace que describir un algoritmo recursivo sea fácil.
  • Haskell tiene buenas comprensiones de listas que coinciden muy bien con la forma en que se expresan dichas listas matem.
  • Haskell tiene una evaluación perezosa. Ideal para construir listas infinitas usando la técnica de comprensión de listas.
  • SML tiene un intérprete verdaderamente interactivo en el cual las funciones pueden ser definidas y usadas. En Haskell, las funciones deben ser definidas en un archivo separado y compiladas antes de ser usadas en el shell interactivo.
  • SML da confirmación explícita del argumento de la función y devuelve los tipos en una sintaxis que es fácil de entender. Por ejemplo: val foo = fn: int * int - > int. La sintaxis implícita de curry de Haskell es un poco más obtusa, pero no totalmente extraña. Por ejemplo: foo :: Int -> Int -> Int.
  • Haskell usa enteros de precisión arbitraria por defecto. Es una biblioteca externa en SML / NJ. Y SML / NJ trunca la salida a 70 caracteres por defecto.
  • La sintaxis lambda de Haskell es sutil uses usa una sola barra invertida. El LME es más explícito. Aunque no estoy seguro de si alguna vez necesitaremos a Lambda en esta clase.

Esencialmente, LME y Haskell son aproximadamente equivalentes. Me inclino hacia Haskell porque me encanta la lista de comprensiones y listas infinitas en Haskell. Pero me preocupa que el extenso número de símbolos en la sintaxis compacta de Haskell pueda causar problemas a los estudiantes. Por lo que he reunido leyendo otros posts en SO, Haskell no se recomienda para principiantes que comienzan con FP. Pero no vamos a construir aplicaciones completas, solo probaremos algoritmos simples.

¿Qué haces pensar?


Editar: Al leer algunas de sus grandes respuestas, debo aclarar algunos de mis puntos.

En SML, no hay distinción sintáctica entre definir una función en el intérprete y definirla en un archivo externo. Digamos que quieres escribir la función factorial. En Haskell puedes poner esta definición en un archivo y cargarla en GHCi:

fac 0 = 1
fac n = n * fac (n-1)

Para mí, eso es claro, sucinto, y coincide con la definición matemática en el libro. Pero si quieres para escribir la función en GHCi directamente, debe usar una sintaxis diferente:

let fac 0 = 1; fac n = n * fac (n-1)

Cuando se trabaja con intérpretes interactivos, desde una perspectiva de enseñanza es muy, muy útil cuando el estudiante puede usar el mismo código tanto en un archivo como en la línea de comandos.

Por "confirmación explícita de la función", quise decir que al definir la función, SML inmediatamente le dice el nombre de la función, los tipos de los argumentos y el tipo de retorno. En Haskell tienes que usar el :type comando y luego se obtiene la notación curry algo confuso.

Una cosa más interesante sobre Haskell this esta es una definición de función válida:

fac 0 = 1
fac (n+1) = (n+1) * fac n

De nuevo, esto coincide con una definición que podrían encontrar en el libro de texto. ¡No puedo hacer eso en SML!

Author: nbro, 2009-05-01

8 answers

Por mucho que me guste Haskell, aquí están las razones por las que preferiría SML para una clase de matemáticas discretas y estructuras de datos (y la mayoría de las otras clases para principiantes):

  • Los costos de tiempo y espacio de los programas Haskell pueden ser muy difíciles de predecir, incluso para los expertos. SML ofrece formas mucho más limitadas de soplar la máquina.

  • La sintaxis para la definición de funciones en un intérprete interactivo es idéntica a la sintaxis utilizada en un archivo, por lo que puede cortar y pegar.

  • Aunque la sobrecarga del operador en SML es totalmente falsa, también es simple. Va a ser difícil enseñar una clase entera en Haskell sin tener que entrar en clases tipo.

  • El estudiante puede depurar usando print. (Aunque, como señala un comentarista, es posible obtener casi el mismo efecto en Haskell usando Debug.Trace.trace.)

  • Estructuras de datos infinitas soplan la mente de la gente. Para los principiantes, es mejor que definan un tipo de transmisión completo con celdas de referencia y pulsos, para que sepan cómo funciona:

    datatype 'a thunk_contents = UNEVALUATED of unit -> 'a
                               | VALUE of 'a
    type 'a thunk = 'a thunk_contents ref
    val delay : (unit -> 'a) -> 'a thunk
    val force : 'a thunk -> 'a
    

    Ahora ya no es magia, y puedes ir de aquí a streams (listas infinitas).

  • El diseño no es tan simple como en Python y puede ser confuso.

Hay dos lugares en los que Haskell tiene una ventaja:

  • En core Haskell puedes escribir la firma de tipo de una función justo antes de su definición. Esto es muy útil para los estudiantes y otros principiantes. Simplemente no hay buena manera de lidiar con las firmas de tipo en SML.

  • Haskell tiene una mejor sintaxis concreta. La sintaxis de Haskell es una mejora importante sobre la sintaxis de ML. He escrito una breve nota sobre cuándo usar paréntesis en un programa ML; esto ayuda un poco.

Finalmente, hay una espada que corta en ambos sentidos:

  • El código de Haskell es puro por defecto, por lo que es poco probable que sus estudiantes tropiecen con construcciones impuras (mónada IO, mónada estado) por accidente. Pero de la misma manera, no pueden imprimir, y si quieres hacer E/S entonces al mínimo tienes que explicar do notación, y return es confuso.

En un tema relacionado, aquí hay algunos consejos para la preparación de su curso: no pase por alto Puramente Estructuras de datos Funcionales por Chris Okasaki. Incluso si no hace que sus estudiantes lo usen, definitivamente querrá tener una copia.

 83
Author: Norman Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-13 23:57:36

Enseñamos a Haskell a los primeros años en nuestra universidad. Mis sentimientos sobre esto son un poco mezclados. Por un lado enseñar Haskell a los primeros años significa que no tienen que desaprender el estilo imperativo. Haskell también puede producir código muy conciso que las personas que tenían algo de Java antes pueden apreciar.

Algunos problemas que he notado que los estudiantes a menudo tienen:

  • La coincidencia de patrones puede ser un poco difícil, al principio. Los estudiantes inicialmente tuvieron algunos problemas para ver cómo el valor la construcción y la coincidencia de patrones están relacionados. También tenían algunos problemas para distinguir entre abstracciones. Nuestros ejercicios incluyeron funciones de escritura que simplifican la expresión aritmética y algunos estudiantes tuvieron dificultades para ver la diferencia entre la representación abstracta (por ejemplo, Const 1) y la representación en meta-lenguaje (1).

    Además, si se supone que sus estudiantes deben escribir funciones de procesamiento de listas por sí mismos, tenga cuidado al señalar la diferencia entre patrones

    []
    [x]
    (x:xs)
    [x:xs]
    

    Dependiendo de la cantidad de programación funcional que desee enseñarles en el camino, puede simplemente darles algunas funciones de biblioteca y dejar que jueguen con eso.

  • No enseñamos a nuestros estudiantes sobre funciones anónimas, simplemente les dijimos sobre las cláusulas where. Para algunas tareas esto fue un poco detallado, pero funcionó bien por lo demás. Tampoco les dijimos sobre aplicaciones parciales; esto es probablemente bastante fácil de explicar en Haskell (debido a su forma de tipos de escritura) por lo que podría valer la pena mostrarles.

  • Descubrieron rápidamente las comprensiones de listas y las prefirieron sobre funciones de orden superior como filter, map, zipWith.

  • Creo que nos perdimos un poco en enseñarles cómo dejarlos guiar sus pensamientos por los tipos. No estoy muy seguro, sin embargo, si esto es útil para los principiantes o no.

  • Los mensajes de error generalmente no son muy útiles para los principiantes, es posible que ocasionalmente necesiten ayuda con esto. No lo he probado yo mismo, pero hay un compilador de Haskell específicamente dirigido a los recién llegados, principalmente por medio de mejores mensajes de error: Helium

  • Para los programas pequeños, cosas como posibles fugas de espacio no eran un problema.

En general, Haskell es un buen idioma de enseñanza, pero hay algunos escollos. Dado que los estudiantes se sienten mucho más cómodos con las comprensiones de listas que con las funciones de orden superior, esta podría ser la argumento que necesita. No se cuanto dura tu curso o cuanta programación quieres enseñarles, pero planifica algo de tiempo para enseñarles conceptos básicos they ellos lo necesitarán.

 28
Author: nominolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-01 13:11:49

POR cierto,

# SML tiene una intérprete en el que las funciones pueden ser tanto definido como utilizado. En Haskell, las funciones deben definirse en un archivo separado y compilado antes se utiliza en el shell interactivo.

Es inexacto. Use GHCi:

Prelude> let f x = x ^ 2
Prelude> f 7
49
Prelude> f 2
4

También hay buenos recursos para Haskell en educación sobre el haskell.org edu. página, con experiencias de diferentes profesores. http://haskell.org/haskellwiki/Haskell_in_education

Finalmente, podrás enseñarles paralelismo multinúcleo solo por diversión, si usas Haskell: -)

 13
Author: Don Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-01 17:20:39

Muchas universidades enseñan Haskell como un primer lenguaje funcional o incluso un primer lenguaje de programación, así que no creo que esto sea un problema.

Habiendo hecho parte de la enseñanza en uno de esos cursos, no estoy de acuerdo en que las posibles confusiones que usted identifica sean tan probables. Las fuentes más probables de confusión temprana son los errores de análisis causados por un mal diseño y los mensajes misteriosos sobre las clases de tipo cuando los literales numéricos se usan incorrectamente.

También estaría en desacuerdo con cualquier sugerencia de que Haskell no se recomienda para principiantes que comienzan con FP. Ciertamente es el enfoque del big bang en formas que los lenguajes estrictos con mutación no lo son, pero creo que es un enfoque muy válido.

 10
Author: Ganesh Sittampalam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-01 07:14:38
  • SML tiene un intérprete verdaderamente interactivo en el que las funciones pueden ser definidas y usadas. En Haskell, las funciones deben ser definidas en un archivo separado y compiladas antes de ser usadas en el shell interactivo.

Mientras que los abrazos pueden tener esa limitación, GHCi no:

$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let hello name = "Hello, " ++ name
Prelude> hello "Barry"
"Hello, Barry"

Hay muchas razones por las que prefiero GHC(i) a los abrazos, esta es solo una de ellas.

  • SML da confirmación explícita del argumento de la función y devuelve tipos en una sintaxis fácil de entender. Por ejemplo: val foo = fn : int * int -> int. La sintaxis implícita de curry de Haskell es un poco más obtusa, pero no totalmente extraña. Por ejemplo: foo :: Int -> Int -> Int.

SML también tiene lo que se llama sintaxis "curry implícito".

$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- fun add x y = x + y;
val add = fn : int -> int -> int

Esencialmente, SML y Haskell son aproximadamente equivalentes. Me inclino hacia Haskell porque me encanta la lista de comprensiones y listas infinitas en Haskell. Pero me preocupa que el extenso número de símbolos en la sintaxis compacta de Haskell podría causar problemas a los estudiantes. Por lo que he reunido leyendo otros posts en SO, Haskell no se recomienda para principiantes que comienzan con FP. Pero no vamos a construir aplicaciones completas, solo probaremos algoritmos simples.

Me gusta usar Haskell mucho más que SML, pero todavía enseñaría SML primero.

  • Secundando los pensamientos de nominolo, las comprensiones de la lista hacen parecen retrasar a los estudiantes de llegar a algunas funciones de orden superior.
  • Si quieres pereza y listas infinitas, es instructivo implementarlas explícitamente.
  • Debido a que SML se evalúa con entusiasmo, el modelo de ejecución es mucho más fácil de comprender, y la "depuración a través de printf" funciona mucho mejor que en Haskell.
  • El sistema de tipos de SML también es más simple. Si bien es probable que su clase no los use de todos modos, las clases tipográficas de Haskell siguen siendo un obstáculo adicional para superar getting para que entiendan el 'a versus ''a la distinción en SML es bastante dura.
 8
Author: ephemient,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-01 15:08:48

La mayoría de las respuestas fueron técnicas, pero creo que deberías considerar al menos una que no lo es: Haskell (como OCaml), en este momento, tiene una comunidad más grande que la usa en una gama más amplia de contextos. También hay una gran base de datos de bibliotecas y aplicaciones escritas con fines de lucro y diversión en Hackage. Eso puede ser un factor importante para mantener a algunos de sus estudiantes usando el idioma después de que su curso haya terminado, y tal vez probar otros idiomas funcionales (como ML estándar) más tarde.

 6
Author: Maurício C Antunes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-01 23:28:38

Me sorprende que no esté considerando OCaml y F# dado que abordan muchas de sus preocupaciones. Seguramente los entornos de desarrollo decentes y útiles son una alta prioridad para los estudiantes? SML está muy por detrás y F# está muy por delante de todos los otros FPLs en ese sentido.

Además, tanto OCaml como F# tienen comprensiones de lista.

 4
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-12 19:44:26

Haskell. Estoy por delante en mi clase de algos / teoría en CS debido a las cosas que aprendí usando Haskell. Es un lenguaje tan completo, y te enseñará un montón de CS, simplemente usándolo.

Sin embargo, SML es mucho más fácil de aprender. Haskell tiene características como la evaluación perezosa y las estructuras de control que lo hacen mucho más poderoso, pero con el costo de una curva de aprendizaje empinada(ish). SML no tiene tal curva.

Dicho esto, la mayoría de Haskell estaba desaprendiendo cosas de menos lenguajes científicos / matemáticos como Ruby, ObjC o Python.

 2
Author: Nate Symer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-31 00:46:32