Question

Je vais enseigner un cours de division inférieure dans des structures discrètes. J'ai sélectionné le livre de texte Structures discrètes, logique et calculabilité , en partie parce que contient des exemples et des concepts propices à la mise en œuvre avec un langage de programmation fonctionnel. (Je pense aussi que c'est un bon manuel.)

Je veux un langage de PF facile à comprendre pour illustrer les concepts DS et que les étudiants peuvent utiliser. La plupart des étudiants n'auront eu au mieux qu'un ou deux semestres de programmation en Java. Après avoir examiné Scheme, Erlang, Haskell, Ocaml et SML, j'ai choisi Haskell ou Standard ML. Je me penche vers Haskell pour les raisons exposées ci-dessous, mais j'aimerais connaître l'opinion de ceux qui sont des programmeurs actifs dans l'un ou l'autre.

  • Haskell et SML ont tous deux une correspondance de modèle qui fait de la description d'un algorithme récursif un cinch.
  • Haskell a une bonne compréhension des listes qui correspond bien à la façon dont ces listes sont exprimées mathématiquement.
  • Haskell a une évaluation paresseuse. Idéal pour construire des listes infinies en utilisant la technique de compréhension de liste.
  • SML dispose d’un interpréteur véritablement interactif dans lequel les fonctions peuvent être définies et utilisées. Dans Haskell, les fonctions doivent être définies dans un fichier séparé et compilées avant d’être utilisées dans le shell interactif.
  • SML donne une confirmation explicite de l'argument de la fonction et renvoie les types dans une syntaxe facile à comprendre. Par exemple: val foo = fn: int * int - > int. La syntaxe implicite au curry de Haskell est un peu plus obtuse, mais pas totalement étrangère. Par exemple: foo :: Int - > Int - > Int.
  • Haskell utilise par défaut des entiers de précision arbitraire. C'est une bibliothèque externe en SML / NJ. Et SML / NJ tronque la sortie à 70 caractères par défaut.
  • La syntaxe lambda de Haskell est subtile - elle utilise une simple barre oblique inversée. SML est plus explicite. Je ne sais pas si nous aurons un jour besoin de lambda dans cette classe.

Essentiellement, SML et Haskell sont à peu près équivalents. Je me penche vers Haskell parce que j'aime les compréhensions de liste et les listes infinies de Haskell. Mais je crains que le grand nombre de symboles de la syntaxe compacte de Haskell ne pose problème à ses étudiants. D'après ce que j'ai lu d'autres articles sur SO, Haskell n'est pas recommandé aux débutants qui commencent avec la PF. Mais nous n'allons pas créer d'applications à part entière, mais simplement essayer des algorithmes simples.

Qu'en pensez-vous?

Éditer: Après avoir lu certaines de vos bonnes réponses, je devrais clarifier certains de mes points.

En SML, il n’existe aucune distinction syntaxique entre la définition d’une fonction dans l’interpréteur et sa définition dans un fichier externe. Disons que vous voulez écrire la fonction factorielle. En Haskell, vous pouvez mettre cette définition dans un fichier et la charger dans GHCi:

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

Pour moi, c'est clair, succinct et correspond à la définition mathématique du livre. Mais si vous voulez écrire directement la fonction dans GHCi, vous devez utiliser une syntaxe différente:

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

Lorsque vous travaillez avec des interprètes interactifs, d’un point de vue pédagogique, il est très utile que l’élève puisse utiliser le même code dans un fichier et en ligne de commande.

Par "confirmation explicite de la fonction", " Je voulais dire que lors de la définition de la fonction, SML vous indique immédiatement le nom de la fonction, les types des arguments et le type de retour. En Haskell, vous devez utiliser la commande : type , puis vous obtenez la notation curry quelque peu déroutante.

Encore une chose sympa à propos de Haskell - c'est une définition de fonction valide:

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

Encore une fois, cela correspond à une définition qu'ils pourraient trouver dans le manuel. Ne peut pas faire ça dans SML!

Était-ce utile?

La solution

Même si j'aime beaucoup Haskell, voici les raisons pour lesquelles je préférerais utiliser SML pour un cours sur les structures discrètes de calcul et de données (et sur la plupart des cours pour débutants):

  • Les coûts en termes de temps et d'espace des programmes Haskell peuvent être très difficiles à prévoir, même pour les experts. SML & propose des moyens beaucoup plus limités de faire sauter la machine.

  • La syntaxe pour la définition de la fonction dans un interpréteur interactif est identique à la syntaxe utilisée dans un fichier, vous pouvez donc couper et coller.

  • Bien que la surcharge d'opérateurs dans SML soit totalement fausse, elle est également simple. Il sera difficile d'enseigner une classe entière à Haskell sans avoir à entrer dans des classes de type.

  • L'étudiant peut déboguer à l'aide de print . (Bien que, comme le souligne un commentateur, il est possible d'obtenir presque le même effet dans Haskell en utilisant Debug.Trace.trace .)

  • Les structures de données infinies époustouflent les esprits. Pour les débutants, il est préférable de leur demander de définir un type de flux avec des cellules de référence et des thunks, afin qu'ils sachent comment cela fonctionne:

    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
    

    Maintenant, ce n'est plus magique, et vous pouvez aller d'ici aux flux (listes infinies).

  • La mise en page n'est pas aussi simple qu'en Python et peut prêter à confusion.

Il y a deux endroits où Haskell a un bord:

  • Dans Haskell, vous pouvez écrire la signature de type d'une fonction juste avant sa définition. Ceci est extrêmement utile pour les étudiants et autres débutants. Il n’existe aucun moyen intéressant de traiter les signatures de type dans SML.

  • Haskell a une meilleure syntaxe concrète. La syntaxe Haskell constitue une amélioration majeure par rapport à la syntaxe ML. J'ai & nbsp; ecrit une remarque sur le moment d'utiliser des parenthèses dans une Programme ML ; cela aide un peu.

Enfin, il existe une épée qui coupe dans les deux sens:

  • Le code Haskell étant pur par défaut, vos étudiants ne risquent pas de trébucher sur des constructions impures (monade IO, monade d'état) par accident. Mais du même coup, ils ne peuvent pas imprimer, et si vous voulez faire des E / S, alors au minimum, vous devez expliquer la notation do , et return est déroutant.

Sur un sujet connexe, voici quelques conseils pour préparer votre cours: n'oubliez pas Structures de données purement fonctionnelles par Chris Okasaki. Même si vos élèves ne l'utilisent pas, vous voudrez certainement en avoir une copie.

Autres conseils

Nous enseignons Haskell aux premières années de notre université. Mes sentiments à ce sujet sont un peu mitigés. D'une part, enseigner Haskell aux premières années signifie qu'ils ne doivent pas désapprendre le style impératif. Haskell peut également produire un code très concis que les utilisateurs de Java pourraient apprécier.

Certains problèmes que j'ai remarqués souvent chez les étudiants:

  • La correspondance des modèles peut être un peu difficile, au début. Au départ, les étudiants ont eu du mal à comprendre les liens qui unissent construction de valeur et correspondance de motifs. Ils ont également eu quelques problèmes pour distinguer les abstractions. Nos exercices comprenaient des fonctions d'écriture simplifiant l'expression arithmétique et certains étudiants ont eu du mal à voir la différence entre la représentation abstraite (par exemple, Const 1 ) et la représentation en méta-langage ( 1 ) .

    De plus, si vos étudiants sont supposés écrire eux-mêmes les fonctions de traitement de liste, faites bien attention à la différence entre les motifs

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

    En fonction de la programmation fonctionnelle que vous souhaitez leur enseigner, vous pouvez leur donner quelques fonctions de bibliothèque et les laisser jouer avec cela.

  • Nous n'avons pas enseigné à nos étudiants les fonctions anonymes, nous leur avons simplement parlé des clauses . Pour certaines tâches, c'était un peu prolixe, mais cela a bien fonctionné autrement. Nous ne leur avons pas non plus parlé d’applications partielles; c'est probablement assez facile à expliquer en Haskell (en raison de la forme de ses types d'écriture), donc il pourrait être intéressant de le leur montrer.

  • Ils ont rapidement découvert les listes de compréhension et les ont préférées aux fonctions d'ordre supérieur telles que filtre , carte , zipWith .

  • Je pense que nous avons un peu manqué de leur apprendre à les laisser guider leurs pensées par types. Cependant, je ne suis pas tout à fait sûr que cela soit utile aux débutants.

  • Les messages d'erreur ne sont généralement pas très utiles pour les débutants, ils ont parfois besoin d'aide pour les résoudre. Je n'ai pas essayé moi-même, mais il existe un compilateur Haskell spécifiquement destiné aux nouveaux arrivants, principalement au moyen de meilleurs messages d'erreur: Hélium

  • Pour les petits programmes, des problèmes tels que les fuites d'espace possibles n'étaient pas un problème.

Dans l’ensemble, le haskell est une bonne langue d’enseignement, mais il existe quelques pièges. Étant donné que les étudiants se sentent beaucoup plus à l'aise avec la compréhension de listes que les fonctions d'ordre supérieur, cela pourrait être l'argument dont vous avez besoin. Je ne sais pas combien de temps dure votre cours ni quelle programmation vous voulez enseigner, mais prévoyez du temps pour leur enseigner les concepts de base - ils en auront besoin.

BTW,

  

# SML a un environnement vraiment interactif   interprète dans lequel les fonctions peuvent être   à la fois défini et utilisé. À Haskell,   les fonctions doivent être définies dans un   fichier séparé et compilé avant   utilisé dans le shell interactif.

est inexact. Utilisez GHCi:

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

Il existe également de bonnes ressources pour Haskell en matière d’éducation sur le haskell.org edu. page, avec des expériences de différents enseignants. http://haskell.org/haskellwiki/Haskell_in_education

Enfin, vous pourrez leur apprendre le parallélisme multicœur juste pour le fun, si vous utilisez Haskell: -)

De nombreuses universités enseignent Haskell comme premier langage fonctionnel ou même comme premier langage de programmation. Je ne pense donc pas que cela posera de problème.

Après avoir enseigné un de ces cours, je ne pense pas que les confusions possibles que vous identifiez soient probables. Les sources de confusion les plus fréquentes sont les erreurs d’analyse dues à une mauvaise mise en page et les messages mystérieux concernant les classes de types lorsque les littéraux numériques sont utilisés de manière incorrecte.

Je suis également en désaccord avec toute suggestion selon laquelle Haskell n'est pas recommandé pour les débutants qui commencent avec la PF. C’est certainement l’approche du big bang qui fait que les langues strictes avec mutation ne le sont pas, mais je pense que c’est une approche très valable.

  
      
  • SML dispose d’un interpréteur véritablement interactif dans lequel les fonctions peuvent être définies et utilisées. Dans Haskell, les fonctions doivent être définies dans un fichier séparé et compilées avant d’être utilisées dans le shell interactif.
  •   

Bien que Hugs puisse avoir cette limitation, GHCi ne le fait pas:

$ 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"

Il y a plusieurs raisons pour lesquelles je préfère GHC (i) à Hugs, ce n’est que l’un d’eux.

  
      
  • SML donne une confirmation explicite de l'argument de la fonction et renvoie les types dans une syntaxe facile à comprendre. Par exemple: val foo = fn: int * int - > int. La syntaxe implicite au curry de Haskell est un peu plus obtuse, mais pas totalement étrangère. Par exemple: foo :: Int - > Int - > Int.
  •   

SML a ce que vous appelez "curry implicite". la syntaxe aussi bien.

$ 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
  

Essentiellement, SML et Haskell sont à peu près équivalents. Je me penche vers Haskell parce que j'aime les compréhensions de liste et les listes infinies de Haskell. Mais je crains que le grand nombre de symboles de la syntaxe compacte de Haskell ne pose problème à ses étudiants. D'après ce que j'ai lu d'autres articles sur SO, Haskell n'est pas recommandé aux débutants qui commencent avec la PF. Mais nous n'allons pas créer d'applications à part entière, mais simplement essayer des algorithmes simples.

J'aime utiliser Haskell beaucoup plus que SML, mais je l'enseignerais toujours en premier.

  • En souscrivant aux pensées de nominolo, la compréhension de la liste do semble ralentir la progression des étudiants vers certaines fonctions de niveau supérieur.
  • Si vous voulez de la paresse et des listes infinies, il est instructif de les implémenter explicitement.
  • Etant donné que SML est évalué avec impatience, le modèle d’exécution est beaucoup plus facile à comprendre et le débogage via printf " fonctionne beaucoup mieux que dans Haskell.
  • Le système de types de SML est également plus simple. Tandis que votre classe ne les utilisera probablement pas de toute façon, les classes-types de Haskell sont toujours une bosse supplémentaire à surmonter: leur faire comprendre la distinction 'a par rapport à ' 'a dans SML est assez robuste.

La plupart des réponses étaient techniques, mais je pense que vous devriez au moins en considérer une autre: Haskell (en tant qu'OCaml), à l'heure actuelle, dispose d'une communauté plus importante qui l'utilise dans un plus large éventail de contextes. Hackage propose également une grande base de données de bibliothèques et d'applications conçues pour générer du profit et du divertissement. Cela peut constituer un facteur important pour que certains de vos étudiants continuent d’utiliser la langue une fois votre cours terminé et d’essayer ultérieurement d’autres langages fonctionnels (comme Standard ML).

Je suis étonné que vous ne considériez pas OCaml et F #, car ils répondent à tant de vos préoccupations. Des environnements de développement décents et utiles sont certainement une priorité pour les apprenants? SML est loin derrière et F # est loin devant toutes les autres FPL à cet égard.

De plus, OCaml et F # ont tous deux une compréhension de liste.

Haskell. Je suis en avance dans mon cours d'algos / théorie en CS à cause de ce que j'ai appris en utilisant Haskell. C'est un langage si complet, et il va vous apprendre une tonne de CS, simplement en l'utilisant .

Cependant, SML est beaucoup plus facile à apprendre. Haskell présente des fonctionnalités telles que l'évaluation paresseuse et des structures de contrôle qui le rendent beaucoup plus puissant, mais avec le coût d'une courbe d'apprentissage abrupte (ish). SML n’a pas cette courbe.

Cela dit, la plupart des gens de Haskell étaient en train de désapprendre des langages moins scientifiques / mathématiques tels que Ruby, ObjC ou Python.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top