Publicité
+ Répondre à la discussion
Page 1 sur 2 12 DernièreDernière
Affichage des résultats 1 à 20 sur 31
  1. #1
    Nouveau Membre du Club Avatar de limestrael
    Inscrit en
    juin 2009
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : juin 2009
    Messages : 86
    Points : 34
    Points
    34

    Par défaut Si vous aviez quelque chose à reprocher à Haskell

    Haskell est un langage excellent, bien pensé et qui a de grande qualités, mais rien n'est parfait si on essaie d'avoir un regard critique, et je pense qu'il est bien de voir tous les aspects.
    Du coup, si vous aviez des choses (petites ou grosses) à lui reprocher, ça serait quoi ?

    Pour ma part, ça tient du détail, mais je pense qu'un système de namespaces aurait été le bienvenu. On peut s'en rapprocher avec les imports qualifiés, mais c'est moins flexible.

  2. #2
    Expert Confirmé Sénior
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2003
    Messages
    6 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2003
    Messages : 6 180
    Points : 8 322
    Points
    8 322

    Par défaut

    Citation Envoyé par limestrael Voir le message
    Pour ma part, ça tient du détail, mais je pense qu'un système de namespaces aurait été le bienvenu. On peut s'en rapprocher avec les imports qualifiés, mais c'est moins flexible.
    Là, quelque chose m'échappe, en quoi le système de module hiérarchique et divers mode d'import d'Haskell est "moins flexible" qu'un système de namespace (et d'abord quelle est la différence ? A priori j'aurais appelé ça un système de namespaces).


    Pour ce qui est des reproches à adresser à Haskell... J'aimerais un système de type plus puissant ! On peut faire des choses très impressionnante avec l'actuel mais je suis convaincu qu'on peut faire encore mieux sans perdre en flexibilité. J'aimerais également un meilleur moyen de combiner les monades que les transformateurs de monades. Et il serait pratique de pouvoir traduire automatiquement du code vers une écriture monadique.

    J'ai d'autres reproches qui ne me reviennent pas sur l'instant.

    --
    Jedaï

  3. #3
    Nouveau Membre du Club Avatar de limestrael
    Inscrit en
    juin 2009
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : juin 2009
    Messages : 86
    Points : 34
    Points
    34

    Par défaut

    Citation Envoyé par Jedai Voir le message
    Là, quelque chose m'échappe, en quoi le système de module hiérarchique et divers mode d'import d'Haskell est "moins flexible" qu'un système de namespace (et d'abord quelle est la différence ? A priori j'aurais appelé ça un système de namespaces).
    J'aurais aimé que l'auteur d'un module ait la capacité de définir un truc genre "namespace NS where" (un peu comme on le fait en C++).
    Le souci quand on développe un code Haskell est qu'on se retrouve très rapidement avec beaucoup de fonctions, certaines ayant souvent des noms très proches (cf. certaines fonctions, genre de Data.Map, qui ont le même nom que des fonctions du Prelude) et que j'aurais aimé un moyen en plus des imports qualifiés pour répartir et retrouver mes fonctions.

    Avec seulement les imports qualifiés, les problèmes sont les suivants :
    - Pas moyen de définir un nom d'import standard pour un module. Ex: Je peux importer Data.Map en tant que M, mais quelqu'un d'autre pourra l'importer en tant que Map ou DM ou n'importe quoi d'autre. Ca n'aide pas pour s'y retrouver quand au sein d'un même projet on a plusieurs fois le même module, mais importé sous des noms différents. Avec un namespace Map, tout le monde serait logé à la même enseigne.
    - Il faut indiquer à chaque fois les alias, alors qu'avec un namespace ce serait automatique.


    J'aimerais également un meilleur moyen de combiner les monades que les transformateurs de monades.
    C'est vrai qu'un simple combinateur qui prendrait une ou plusieurs monades serait plus simple... Mais dans ce cas cela requiert quelque chose qui n'existe pas dans le langage, alors que les transformateurs de monades ne requièrent rien de spécial de la part du compilateur.

    Et il serait pratique de pouvoir traduire automatiquement du code vers une écriture monadique.
    Faudrait développer un préprocesseur qui se chargerait de ça...

  4. #4
    Expert Confirmé Sénior
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2003
    Messages
    6 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2003
    Messages : 6 180
    Points : 8 322
    Points
    8 322

    Par défaut

    Citation Envoyé par limestrael Voir le message
    Avec seulement les imports qualifiés, les problèmes sont les suivants :
    - Pas moyen de définir un nom d'import standard pour un module. Ex: Je peux importer Data.Map en tant que M, mais quelqu'un d'autre pourra l'importer en tant que Map ou DM ou n'importe quoi d'autre. Ca n'aide pas pour s'y retrouver quand au sein d'un même projet on a plusieurs fois le même module, mais importé sous des noms différents. Avec un namespace Map, tout le monde serait logé à la même enseigne.
    - Il faut indiquer à chaque fois les alias, alors qu'avec un namespace ce serait automatique.
    En fait tu lui reproches sa flexibilité excessive non ? Par ailleurs, il y a un nom de base pour l'espace de nom de Data.Map... c'est Data.Map :
    Code Haskell :
    1
    2
    3
    import qualified Data.Map
    
    stuff = Data.Map.lookup blabla
    (c'est aussi valable sans le qualified d'ailleurs : tu peux toujours utiliser Data.Map.lookup pour éviter une ambiguité)
    Ce que "as" t'apporte de plus c'est la possibilité de définir un alias.


    Citation Envoyé par limestrael Voir le message
    C'est vrai qu'un simple combinateur qui prendrait une ou plusieurs monades serait plus simple... Mais dans ce cas cela requiert quelque chose qui n'existe pas dans le langage, alors que les transformateurs de monades ne requièrent rien de spécial de la part du compilateur.
    Ce n'est pas ce que je voulais dire : les transformateurs de monades tels qu'écrit actuellement sont fragiles (certaines combinaisons violent certaines lois de monades) et relativement ennuyeux à écrire, il y a des travaux pour rendre cela plus solide et simple (c'est une question de trouver la bonne abstraction, pas besoin de sortir du langage pour ça).

    Citation Envoyé par limestrael Voir le message
    Faudrait développer un préprocesseur qui se chargerait de ça...
    Plutôt du ressort de la refactorisation à mon avis.

    --
    Jedaï

  5. #5
    Nouveau Membre du Club Avatar de limestrael
    Inscrit en
    juin 2009
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : juin 2009
    Messages : 86
    Points : 34
    Points
    34

    Par défaut

    Citation Envoyé par Jedai Voir le message
    En fait tu lui reproches sa flexibilité excessive non ? Par ailleurs, il y a un nom de base pour l'espace de nom de Data.Map... c'est Data.Map :
    Code Haskell :
    1
    2
    3
    import qualified Data.Map
    
    stuff = Data.Map.lookup blabla
    (c'est aussi valable sans le qualified d'ailleurs : tu peux toujours utiliser Data.Map.lookup pour éviter une ambiguité)
    Ce que "as" t'apporte de plus c'est la possibilité de définir un alias.
    Oui, mais là pour le coup Data.Map c'est un peu long à taper à chaque fois...

  6. #6
    Membre expérimenté
    Inscrit en
    avril 2006
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : avril 2006
    Messages : 431
    Points : 530
    Points
    530

    Par défaut

    Haskell est dur a apprendre. En tout cas pour quelqu'un comme moi qui ne connait que l'objet et le procédural.

  7. #7
    Nouveau Membre du Club Avatar de limestrael
    Inscrit en
    juin 2009
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : juin 2009
    Messages : 86
    Points : 34
    Points
    34

    Par défaut

    Explique-toi.
    Si Haskell est dur à apprendre parce qu'il fonctionne d'une manière très différente de ce que tu connais, ça ne peut pas être une critique. Si Haskell fonctionnait pareil que les langages mainstream, il aurait beaucoup moins d'intérêt. Il est intéressant avant justement tout parce qu'il propose un modo operandum et une logique différents.

    Si maintenant tu trouves qu'Haskell est dur à apprendre parce qu'il te semble que ses créateurs ne font pas d'effort pour aider les débutants (qui en d'autant plus besoin du fait de sa logique différente), ça c'est autre autre chose.
    Effectivement, les messages d'erreur de GHC sont assez opaques pour le newbie.

  8. #8
    Membre expérimenté
    Inscrit en
    avril 2006
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : avril 2006
    Messages : 431
    Points : 530
    Points
    530

    Par défaut

    Ben tu demandes si on a un reproche a faire a Haskell, moi j'en ai un.
    Après si il est impossible de corriger cette imperfection sans dénaturer totalement le langage, alors il faut trouver une autre réponse (le faire enseigner dans les université, écoles, par exemple).

  9. #9
    Membre du Club

    Profil pro Maxime Gaudin
    Inscrit en
    novembre 2005
    Messages
    17
    Détails du profil
    Informations personnelles :
    Nom : Maxime Gaudin

    Informations forums :
    Inscription : novembre 2005
    Messages : 17
    Points : 65
    Points
    65

    Par défaut

    Citation Envoyé par limestrael Voir le message
    Oui, mais là pour le coup Data.Map c'est un peu long à taper à chaque fois...
    Tu peux rajouter 'as' quand tu import :
    Code :
    1
    2
    import qualified Data.Map as DM

  10. #10
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 130
    Points
    1 130

    Par défaut

    - le compilateur GHC est trop compliqué, lourd, et long à compiler
    - rentre GHCi agréable à utiliser pour coder de petits exemples (quand on est habitué au toplevel OCaml, il y a un monde)

    - si on pouvait reconcevoir haskell aujourd'hui, j'essaierais d'enlever la paresse par défaut (par exemple, en ajoutant des spécifications d'appel sur les types des fonctions, où on choisit entre un traitement lazy ou strict de chaque paramètre, le défaut étant le strict)

    - essayer de concevoir un meilleur support pour les ambiguités de type classes : je veux pouvoir donner plusieurs structures de monoïde à l'ensemble des entiers naturels, sans devoir changer de type; cela passe sans doute par une réification de certains dictionnaires

    - ajouter un mot-clé "rec" ou un équivalent pour préciser les valeurs récursives; dans le cas par défaut, les noms déclarés ne seraient pas dans la portée de leur déclaration

    - un langage de contraintes plus puissant et plus composable (il y a un article à ce sujet : Haskell Type Constraints Unleashed)

    - arrêter de traiter la monade IO comme un gros blurb où on peut tout mettre (entrée-sortie, concurrence..)

    - des outils pour rendre plus facile la programmation au niveau des types, comme par exemple une couche de langage logique spécialisée, ou la définition d'un sous-ensemble de Haskell où aucune valeur ne diverge, pour pouvoir l'utiliser dans les types (mais sans forcément autoriser les types dépendants dans toute leur généralité, pour préserver la distinction typage/exécution)


    Edit : un petit point auquel j'avais déjà pensé, que j'ai oublié de mentionner, mais que je viens de retrouver très bien exprimé dans un post de Tim Sweeney : pas de différence entre la syntaxe (ou la sémantique) des déclarations toplevel et des déclarations locales.

  11. #11
    Membre du Club
    Homme Profil pro
    Inscrit en
    janvier 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : janvier 2010
    Messages : 46
    Points : 51
    Points
    51

    Par défaut

    Citation Envoyé par bluestorm Voir le message
    - rentre GHCi agréable à utiliser pour coder de petits exemples (quand on est habitué au toplevel OCaml, il y a un monde)
    Tu pourrais préciser ? Personnellement je préfère largement GHCi ne serait-ce que pour l'autocomplétion et la mémorisation des expressions entrées.

  12. #12
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 130
    Points
    1 130

    Par défaut

    Le fait que la syntaxe des déclarations dans GHCi et dans le Haskell classique soient très différentes est assez pénalisant. En pratique je n'arrive jamais à entrer des programmes de plus d'une ligne dans GHCi.

    En gros, il est impossible d'utiliser GHCi pour coder, même de petites choses : tout ce que j'arrive à lui demander, c'est le type ou la valeur d'expressions venant d'un programme externe. C'est pratique, mais ça limite sérieusement l'utilité d'un interpréteur interactif (par rapport par exemple à un éditeur qui donne des informations de typage si on lui demande gentiment).

    Ce sont des problèmes de surface, moins importants que d'autres (mais en même temps la syntaxe toplevel des déclarations Haskell doit contribuer à la difficulté de faire une REPL pratique à utiliser; mais on pourrait ajouter un opérateur pour dire "c'est la fin d'un bloc de déclarations", un peu comme le ';;' OCaml).

  13. #13
    Membre Expert
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 895
    Points : 1 300
    Points
    1 300

    Par défaut

    Citation Envoyé par bluestorm Voir le message
    - ajouter un mot-clé "rec" ou un équivalent pour préciser les valeurs récursives; dans le cas par défaut, les noms déclarés ne seraient pas dans la portée de leur déclaration
    Je serais intéressé de savoir en quoi c'est important. Pour moi, cela permet d'éliminer un mot-clé, et le seul désavantage que je vois est qu'on ne peut pas référencer une ancienne valeur liée à cet identifiant, ce qui me semble un mauvais style de toute façon (cela peut donner l'impression que la valeur est récursive si on ne fait pas assez attention).

  14. #14
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 130
    Points
    1 130

    Par défaut

    Pour moi, cela permet d'éliminer un mot-clé
    Et alors ? On parle de Haskell (qui a trois mots-clés pour les déclarations de type), pas d'un langage minimaliste, il n'y a pas de honte à ajouter un mot-clé s'il a une signification sémantique intéressante.

    L'intérêt de pouvoir accéder aux anciennes valeurs n'est en fait pas tellement le fait d'y accéder, mais surtout le fait de pouvoir les cacher. Dans un certain nombre de contextes, on a envie de mettre à jour une valeur, et on veut s'assurer que toutes les références suivantes se feront sur la nouvelle.

    Le cas typique est du style "let x = secure x in ..." : on veut cacher la définition de la valeur x, en la remplaçant par une valeur "sécurisée", et faire référence ensuite à la version sécurisée. En haskell on utilise des "... where x' = secure x", mais le risque est alors de se tromper et d'écrire x au lieu de x'. Si les deux valeurs ne sont pas du même type, le compilateur détecte l'erreur, mais ce n'est pas toujours le cas.

    Exemples trouvés dans du vrai code, par Google Code Search :
    Code :
    1
    2
    int8ToInt (I8 x) = if x' <= 0x7f then x' else x' - 0x100
     where x' = x `primAnd` 0xff
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    hash_fetchElem hv idx = do
            let idx' = encodeKey idx
            r <- liftIO $ H.lookup hv idx'
            case r of
                 Just sv -> return sv
                 Nothing -> do
                    sv <- newScalar undef
                    liftIO $ H.insert hv idx' sv
                    return sv
    Code :
    1
    2
    3
    4
    5
    6
    7
    > qualBindNestEnv x y (LocalEnv genv env)
    >   | isQualified x = error "internal error: qualBindNestEnv"
    >   | otherwise =
    >       case lookupEnv x' env of
    >         Just _ -> error "internal error: qualBindNestEnv"
    >         Nothing -> LocalEnv genv (bindEnv x' y env)
    >   where x' = unqualify x
    Dans aucun de ces codes on n'a besoin de conserver la référence à x (il y a des fois où on veut pouvoir accéder par la suite à la fois à l'ancienne valeur et la nouvelle), donc il n'y a aucune raison de ne pas cacher l'ancien binding.

    Il vaut mieux réserver ce style aux cas où justement, on a besoin de l'ancienne référence (ce sont en général des cas assez subtils où il faut faire bien attention, donc il est important de mettre l'accent sur l'utilisation à un endroit de x ou de x'), et cacher dans le reste des cas le binding, ce qui enlève un poids mental sur le programmeur en réduisant le nombre d'identifiants actifs, et le risque d'erreur.

    Il n'y a pas de risque de confondre cela avec une définition récursive, puisque les récursions seraient explicitement marquées par "rec". Il suffit de vérifier la présence ou non de "rec" pour savoir si une définition est récursive, et de toute façon tous les exemples que j'ai montrés sont évidemment non-récursifs (à part les petits malins qui s'amusent à faire du "Tying back the knot", personne de sain d'esprit n'écrirait "x = secure x" si c'était récursif).

    On a déjà discuté de ça par ici, et certains Haskelliens ont répondu, et je pense qu'ils n'ont pas forcément tort, que Haskell favorise le style récursif car il s'allie bien avec la paresse par défaut (l'idée plus ou moins vraie que tout ce qu'on définit est un cofixpoint). Dans ce cas, on pourrait imaginer un mot clé "nonrec" à mettre dans l'autre sens, pour permettre tout de même les idiomes que j'ai montrés. Je pense cependant que le style récursif est celui qu'il convient de marquer explicitement (même en Haskell la récursion n'est pas si courante, surtout avec l'emploi lourds de combinateurs tels que fold/map/etc.), surtout si on le combine avec mon idée d'explorer des possibilités de ne pas avoir la paresse par défaut.




    Enfin, il y a des situations en métaprogrammation où on a envie de générer des programmes en surveillant la portée des identifiants, pour empêcher certaines choses. Il est facile d'utiliser des déclarations locales pour éviter qu'un identifiant ne se propage en dehors d'un bloc, mais la syntaxe Haskell actuelle empêche de cacher un identifiant dans sa portée lexicale, ce qui peut être un problème.

    Par exemple, dans le papier "Comprehensive Comprehensions" (Wadler and Peyton Jones, 07), qui propose une syntaxe de list comprehension en Haskell avec des fonctionnalités empruntées de SQL, on trouve la proposition suivante pour GROUP BY :
    Code :
    1
    2
    3
    4
    5
    6
    the :: Eq a => [a] -> a
    the (x:xs) | all (x ==) xs = x
    
    [ (the dept, sum salary)
    | (name, dept, salary) <- employees
    , group by dept ]
    Dans ce code, (name, dept, salary) sont des champs extraits de la liste "employees", et l'opération "group by" les transforme en listes (GROUP BY dept renvoie une liste de classes d'équivalences pour la relation "être du même département"). Ensuite on récupère la valeur département et on fait la somme des salaires.

    Si on imagine qu'on traduit cette syntaxe vers du code Haskell standard, la redéfinition peut poser problème : il est possible que la nouvelle déclaration des variables comme liste utilise l'ancienne déclaration des variables comme éléments (surtout si les variables utilisées dans le code généré ne représentent pas les variables elles-même, mais une description abstraite des variables, comme on doit faire si on espère par exemple générer une requête SQL à la fin (ce qui n'est pas le cas dans l'article)). La syntaxe Haskell de haskell pose alors problème, et il faut faire des acrobaties diverses pour éviter les captures/récursions.

  15. #15
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 576
    Points : 2 710
    Points
    2 710

    Par défaut

    Citation Envoyé par limestrael
    Haskell est un langage excellent, bien pensé et qui a de grande qualités, mais rien n'est parfait si on essaie d'avoir un regard critique, et je pense qu'il est bien de voir tous les aspects.
    Du coup, si vous aviez des choses (petites ou grosses) à lui reprocher, ça serait quoi ?
    100% d'accord avec bluestorm (sauf sur l'évaluation stricte par défaut où je suis plus partagé).

    J'ajouterais un seul reproche :
    • pas de vérification de l'exhaustivité du filtrage


    Mais si j'avais à faire la liste des reproches à OCaml elle serait au moins aussi longue (pauvreté des types entiers de base, boxed floats, code mort dans les modules, pas de région-based memory-management,...,...).
    Du même auteur: le cours OCaml, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

  16. #16
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 130
    Points
    1 130

    Par défaut

    Je suis d'accord sur l'exhaustivité des filtrages, mais je pense qu'il faudrait une construction syntaxique pour la désactiver localement (car parfois on a envie de dire que seul un cas est possible).

    Pour les reproches à OCaml, je t'invite à créer un topic à ce sujet, ce serait certainement intéressant. D'ailleurs, j'ai du rater quelque chose car je ne comprends pas pourquoi tu reproches à Caml l'absence de régions, alors qu'à ma connaissance Haskell n'en a pas. Est-ce que Haskell en a déjà, ou tu penses que ce ne serait pas utile/pertinent dans ce langage ?

  17. #17
    Rédacteur
    Avatar de SpiceGuid
    Homme Profil pro Damien Guichard
    Inscrit en
    juin 2007
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Nom : Homme Damien Guichard
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : juin 2007
    Messages : 1 576
    Points : 2 710
    Points
    2 710

    Par défaut

    Je pense que tous les langages devraient avoir le region-based memory-management.
    À commencer par le D et autres prétendants à la succession du C.

    Citation Envoyé par bluestorm
    Pour les reproches à OCaml, je t'invite à créer un topic à ce sujet, ce serait certainement intéressant.
    Ça risquerait d'être plus cacophonique parce que les styles sont plus diversifiés en OCaml. Il y aurait les pour et les contre le return et on s'étriperait joyeusement pour rien du tout.
    Du même auteur: le cours OCaml, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

  18. #18
    Expert Confirmé Sénior
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2003
    Messages
    6 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2003
    Messages : 6 180
    Points : 8 322
    Points
    8 322

    Par défaut

    GHC permet déjà de vérifier l'exhaustivité des filtrages avec -fwarn-incomplete-patterns (ou -Wall), il y a aussi l'outil Catch qui est censé être capable dans certains cas de vérifier que des patterns partiels traitent correctement tous les cas possibles.

    @bluestorm :
    - le compilateur GHC est trop compliqué, lourd, et long à compiler
    D'un autre côté en tant que simple utilisateur, tu n'es pas censé le compiler par toi-même (évidemment, si tu tiens à développer GHC, la question est tout autre). Par trop compliqué, je suppose que tu parles du code source, car l'utilisation de GHC est très simple.

    - rentre GHCi agréable à utiliser pour coder de petits exemples (quand on est habitué au toplevel OCaml, il y a un monde)
    C'est une question d'habitude de travail, je trouve GHCi très pratique à utiliser en conjonction avec un bon éditeur de texte pour taper les fonctions longues. De plus si tu connais un peu la syntaxe explicite (sans layout), tu peux taper des fonctions complexes dans GHCi sans problème.
    Reste que GHCi ne permet pas de déclarer des nouveaux types ou instances, il serait intéressant de rendre cela possible (il n'y a pas a priori d'obstables techniques réels).

    - si on pouvait reconcevoir haskell aujourd'hui, j'essaierais d'enlever la paresse par défaut (par exemple, en ajoutant des spécifications d'appel sur les types des fonctions, où on choisit entre un traitement lazy ou strict de chaque paramètre, le défaut étant le strict)

    - ajouter un mot-clé "rec" ou un équivalent pour préciser les valeurs récursives; dans le cas par défaut, les noms déclarés ne seraient pas dans la portée de leur déclaration
    Tu peux parfaitement reconcevoir Haskell aujourd'hui, il me semble toutefois que la paresse par défaut est consubstantielle à Haskell, un langage qui n'aurait pas cela ne serait pas Haskell. Dans cette même optique, "rec" ne m'intéresse pas, bien que "nonrec" puisse avoir un petit intérêt ("case secure x of x -> ..." permet déjà de masquer une variable).

    Je suis d'accord avec le reste de tes remarques.

    --
    Jedaï

  19. #19
    Nouveau Membre du Club Avatar de limestrael
    Inscrit en
    juin 2009
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : juin 2009
    Messages : 86
    Points : 34
    Points
    34

    Par défaut

    Je pourrais aussi reprocher un léger manque de consistance au niveau de certains opérateurs (notamment la '->' qui est allègrement utilisée partout).

    Par exemple, une fonction se déclare ainsi:
    f x = 3*x
    Pourquoi une fonction lambda n'est-elle pas déclarée ainsi:
    \x = 3*x
    au lieu de \x -> 3*x ?

  20. #20
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 130
    Points
    1 130

    Par défaut

    Parce que la première ligne est une égalité (f, appliqué à x, égale 3 x), alors que dans la deuxième il n'y a rien d'égal : "\x = 3*x" suggèrerait au mieux que x = 3*x, donc une forme de récursion. Il s'agit ici d'une fonction : à x on associe 3x. Le "->" est d'ailleurs bien le même "->" que dans un motif ("case .. of") par exemple : si on reconnaît le motif "x", on renvoie "3*x".

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •