Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > Haskell
Haskell Forum d'entraide sur la programmation en langage fonctionnel Haskell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 18/12/2009, 16h47   #1
limestrael
Nouveau Membre du Club
 
Avatar de limestrael
 
Inscription : juin 2009
Messages : 86
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 86
Points : 30
Points : 30
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.
limestrael est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/12/2009, 10h38   #2
Jedai
Expert Confirmé Sénior
 
Avatar de Jedai
 
Étudiant
Inscription : avril 2003
Messages : 6 068
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2003
Messages : 6 068
Points : 8 209
Points : 8 209
Envoyer un message via Yahoo à Jedai
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ï
Jedai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2009, 09h35   #3
limestrael
Nouveau Membre du Club
 
Avatar de limestrael
 
Inscription : juin 2009
Messages : 86
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 86
Points : 30
Points : 30
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.


Citation:
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.

Citation:
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...
limestrael est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2009, 11h43   #4
Jedai
Expert Confirmé Sénior
 
Avatar de Jedai
 
Étudiant
Inscription : avril 2003
Messages : 6 068
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2003
Messages : 6 068
Points : 8 209
Points : 8 209
Envoyer un message via Yahoo à Jedai
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ï
Jedai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2009, 17h30   #5
limestrael
Nouveau Membre du Club
 
Avatar de limestrael
 
Inscription : juin 2009
Messages : 86
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 86
Points : 30
Points : 30
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...
limestrael est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/12/2009, 19h42   #6
Ubiquité
Membre éprouvé
 
Inscription : avril 2006
Messages : 422
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 422
Points : 442
Points : 442
Envoyer un message via MSN à Ubiquité
Haskell est dur a apprendre. En tout cas pour quelqu'un comme moi qui ne connait que l'objet et le procédural.
Ubiquité est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/12/2009, 20h33   #7
limestrael
Nouveau Membre du Club
 
Avatar de limestrael
 
Inscription : juin 2009
Messages : 86
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 86
Points : 30
Points : 30
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.
limestrael est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/12/2009, 20h47   #8
Ubiquité
Membre éprouvé
 
Inscription : avril 2006
Messages : 422
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 422
Points : 442
Points : 442
Envoyer un message via MSN à Ubiquité
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).
Ubiquité est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2010, 16h08   #9
DigitalGuru
Membre du Club
 
Maxime Gaudin
Inscription : novembre 2005
Messages : 17
Détails du profil
Informations personnelles :
Nom : Maxime Gaudin

Informations forums :
Inscription : novembre 2005
Messages : 17
Points : 60
Points : 60
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
DigitalGuru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2010, 09h13   #10
gasche
Membre Expert
 
Inscription : avril 2007
Messages : 829
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 829
Points : 1 007
Points : 1 007
- 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.
gasche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2010, 16h20   #11
Dim Me As New Idiot
Membre du Club
 
Homme
Inscription : janvier 2010
Messages : 46
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : janvier 2010
Messages : 46
Points : 48
Points : 48
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.
Dim Me As New Idiot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2010, 19h27   #12
gasche
Membre Expert
 
Inscription : avril 2007
Messages : 829
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 829
Points : 1 007
Points : 1 007
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).
gasche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2010, 16h34   #13
dividee
Membre Expert
 
Homme
Inscription : mars 2007
Messages : 852
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : mars 2007
Messages : 852
Points : 1 184
Points : 1 184
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).
dividee est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2010, 17h22   #14
gasche
Membre Expert
 
Inscription : avril 2007
Messages : 829
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 829
Points : 1 007
Points : 1 007
Citation:
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.
gasche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2010, 17h59   #15
SpiceGuid
Rédacteur
 
Avatar de SpiceGuid
 
Homme Damien Guichard
Inscription : juin 2007
Messages : 1 514
Détails du profil
Informations personnelles :
Nom : Homme Damien Guichard
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : juin 2007
Messages : 1 514
Points : 2 498
Points : 2 498
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 projet, le blog dvp et le jeu vidéo.
Avant de poser une question je lis les règles du forum.
SpiceGuid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2010, 18h20   #16
gasche
Membre Expert
 
Inscription : avril 2007
Messages : 829
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 829
Points : 1 007
Points : 1 007
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 ?
gasche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2010, 18h47   #17
SpiceGuid
Rédacteur
 
Avatar de SpiceGuid
 
Homme Damien Guichard
Inscription : juin 2007
Messages : 1 514
Détails du profil
Informations personnelles :
Nom : Homme Damien Guichard
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : juin 2007
Messages : 1 514
Points : 2 498
Points : 2 498
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 projet, le blog dvp et le jeu vidéo.
Avant de poser une question je lis les règles du forum.
SpiceGuid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2010, 10h43   #18
Jedai
Expert Confirmé Sénior
 
Avatar de Jedai
 
Étudiant
Inscription : avril 2003
Messages : 6 068
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2003
Messages : 6 068
Points : 8 209
Points : 8 209
Envoyer un message via Yahoo à Jedai
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 :
Citation:
- 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.

Citation:
- 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).

Citation:
- 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ï
Jedai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2010, 11h52   #19
limestrael
Nouveau Membre du Club
 
Avatar de limestrael
 
Inscription : juin 2009
Messages : 86
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 86
Points : 30
Points : 30
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 ?
limestrael est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/03/2010, 06h49   #20
gasche
Membre Expert
 
Inscription : avril 2007
Messages : 829
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 829
Points : 1 007
Points : 1 007
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".
gasche est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 10h14.


 
 
 
 
Partenaires

Hébergement Web