Et merde... 30% de mon salaire vient de mes enseignements à l'université... Mais bon, comme on dit, "Ceux qui savent font, les autres enseignent".
D'un autre côté j'ai été très crû... sûrement trop, p'tet pas la bonne journée :)
Avant de continuer je voulais mettre un truc au point. Ce n'est pas un cours d'introduction à Haskell,
Ce n'est pas un cours, je l'avais bien compris, mais cette phrase me faisait penser que ça serait moins difficile à lire:
L'idée c'est de vous présenter un peu Haskell et sa syntaxe à partir d'un exemple simple à partir d'une fonction simple, le tri.
Ca ne choque personne que le + soit utilisé en python ou en C++ pour concaténer des chaines de caractère
Ce n'est pas exact:
Another, more subtle, issue with operators is that certain rules from mathematics can be wrongly expected or unintentionally assumed. For example, the commutativity of + (i.e. that a + b == b + a) does not always apply; an example of this occurs when the operands are strings, since + is commonly overloaded to perform a concatenation of strings (i.e. "school" + "bag" yields "schoolbag", while "bag" + "school" yields "bagschool"). A typical counter[citation needed] to this argument comes directly from mathematics: While + is commutative on integers (and more generally any complex numbers), it is not commutative for other "types" of variable.
Tout n'est pas rose dans la surcharge d'opérateurs.
Moi c'était plutôt du genre 15+ en math et 2 en français et en physique, chacun son handicap ;)
Ça peut expliquer les affinités avec les paradigmes je suppose :)
Oui, toutes mes excuses, tu n'imagines pas le temps que j'ai passé à rajouter des paragraphs pour rendre mon histoire plus clair.
Ce qui est sûr, c'est que faire simple à toujours été la chose la plus complexe en ingéniérie. Surtout faire simple pour les autres.
Toi tu fais partie de ces étudiants qui n'aime pas comprendre l'ensemble et qui s'attachent aux points de détails. C'est intéressant ;) Ton "pourquoi" est vague donc je vais essayer de répondre à de nombreuses questions possibles :
Pourquoi non mutable ? C'est subjectif. Parce que on aime bien cela en fonctionnel et surtout en Haskell. Cela permet de ne pas se demander qui modifie quoi. Cela simplifie le parallélisme (personne ne va venir modifier ta donnée sans te prévenir) donc on préfère commencer non mutable et introduire de la mutabilité contrôlée quand c'est nécessaire. Cela rend aussi les tests plus simple (pas d'état caché) et le raisonnement sur le code plus simple, car il n'y a pas de modification d'état caché possible.
Pour être honnête, je suis un fanatique des paramètres et méthodes const, en C++. Et pas juste pour le parallélisme, de manière générale ça rend le code plus adaptable. Et ça permets au compilo de vérifier derrière moi.
La plupart des mes algos en Haskell sont en moyenne 2x plus lent que du c++ optimisés
Tout dépend de que tu appelles du C++ optimisé, après. Le C++, si on inclue la STL, à un gros défaut niveau perf: on n'a que peu de contrôle sur la consommation mémoire (oui, on connais toutes les complexités des algo, mais il est difficile d'estimer la RAM que ça va consommer, ce qui impacte potentiellement lourdement sur les caches L1/L2/L3.).
Essaye de te rappeler tes débuts en programmation et ce sur quoi tu bloquais et tu verras que rien n'est naturel ;) Mes bêtes noires à moi c'était la post et pré incrémentation (a++ ou ++a), les constructeurs en C++ et les boucles...
Mes 1ers langages de programmation, dans l'ordre:
Basic de TI82 (1ère 2nde générale)
QBasic (1ère 2nde générale)
ASM (2ème 2nde)
C (2ème 2nde)
C++ (BTS)
Le QBasic avait des fonctions mais je ne m'en suis pas servi dès le début, et quant à l'objet, j'ai lutté à comprendre comment ça marche, jusqu'à tomber sur un type qui montrait comment implémenter de l'objet en C... méthodes virtuelles & co.
Le truc, je pense, c'est qu'il faudrait arrêter de faire commencer les gens avec du C ou du Java, qui ne sont pas faits pour l'enseignement. Enfin, c'est mon opinion personnelle. Ce qui à aussi du beaucoup m'aider, c'est que je n'ai pas appris en cours (sauf pour mes 50 premières lignes de QB, un prof qui m'a filé le virus :D et le pire c'est que je l'aimais pas, mais bon), avec un rythme ou des exercices imposés. Sauf pour le C++, mais bon, une fois le déclic objet fait, ça à été tout seul.
Mais si tu y tient, voila l'implementation comparée de mon histoire de tri en Haskell et en C++... Je sais lequel est le plus naturel pour moi ;)
Juste deux petits points:
si tu veux un truc expressif, plutôt que performant, tu aurais pu utiliser un std::set: std::set<Etudiant,bool(*)(Etudiant const&,Etudiant const&)> etudiants({{"foo",20},{"bar",10}}, [](Etudiant const& e1, Etudiant const& e2){...;}. Bon, forcément, si on veut un autre tri à un autre moment, ça n'est peut-être pas le bon choix :) [1]
l'opérateur ternaire (?:) rend le code plus lisible parfois (mais ne pas en abuser): etu0.note == etu1.note ? etu0.nom < etu0.nom : etu0.note < etu1.note. Mais la notation Haskell est effectivement belle sur ce coup (doit être codable avec un peu de variadic templates je pense... faudrait tester tiens.).
for(auto &&item : etudiants), tu aurais pu écrire for(auto const& item : etudiants). C'est ce que j'aurai fait en fait. Ça aurait permis de pouvoir réutiliser la liste après les yeux fermés, parce que là j'ai un doute sur l'état des éléments de etudiants après coup.
J'espere que mes réponses t’intéresserons.
Beaucoup.
Quant aux '<<', c'est sûrement mon passé de C, mais je trouve ça immonde. J'aime pas les iostreams... un bon vieux printf c'est tellement plus lisible. En tout cas, tu aurais pu mettre les 2 'std::cout' sur la même ligne.
1:
Et la taille de cette ligne, c'est une des raisons qui font que quand j'utilise un conteneur STL, j'utilise TOUJOURS un typedef.
[^] # Re: Moi == pas doué, je suppose....
Posté par freem . En réponse au journal Haskell et le tri. Évalué à 2.
D'un autre côté j'ai été très crû... sûrement trop, p'tet pas la bonne journée :)
Ce n'est pas un cours, je l'avais bien compris, mais cette phrase me faisait penser que ça serait moins difficile à lire:
Ce n'est pas exact:
Tout n'est pas rose dans la surcharge d'opérateurs.
Ça peut expliquer les affinités avec les paradigmes je suppose :)
Ce qui est sûr, c'est que faire simple à toujours été la chose la plus complexe en ingéniérie. Surtout faire simple pour les autres.
Pour être honnête, je suis un fanatique des paramètres et méthodes const, en C++. Et pas juste pour le parallélisme, de manière générale ça rend le code plus adaptable. Et ça permets au compilo de vérifier derrière moi.
Tout dépend de que tu appelles du C++ optimisé, après. Le C++, si on inclue la STL, à un gros défaut niveau perf: on n'a que peu de contrôle sur la consommation mémoire (oui, on connais toutes les complexités des algo, mais il est difficile d'estimer la RAM que ça va consommer, ce qui impacte potentiellement lourdement sur les caches L1/L2/L3.).
Mes 1ers langages de programmation, dans l'ordre:
Le QBasic avait des fonctions mais je ne m'en suis pas servi dès le début, et quant à l'objet, j'ai lutté à comprendre comment ça marche, jusqu'à tomber sur un type qui montrait comment implémenter de l'objet en C... méthodes virtuelles & co.
Le truc, je pense, c'est qu'il faudrait arrêter de faire commencer les gens avec du C ou du Java, qui ne sont pas faits pour l'enseignement. Enfin, c'est mon opinion personnelle. Ce qui à aussi du beaucoup m'aider, c'est que je n'ai pas appris en cours (sauf pour mes 50 premières lignes de QB, un prof qui m'a filé le virus :D et le pire c'est que je l'aimais pas, mais bon), avec un rythme ou des exercices imposés. Sauf pour le C++, mais bon, une fois le déclic objet fait, ça à été tout seul.
Juste deux petits points:
std::set<Etudiant,bool(*)(Etudiant const&,Etudiant const&)> etudiants({{"foo",20},{"bar",10}}, [](Etudiant const& e1, Etudiant const& e2){...;}. Bon, forcément, si on veut un autre tri à un autre moment, ça n'est peut-être pas le bon choix :) [1]etu0.note == etu1.note ? etu0.nom < etu0.nom : etu0.note < etu1.note. Mais la notation Haskell est effectivement belle sur ce coup (doit être codable avec un peu de variadic templates je pense... faudrait tester tiens.).for(auto &&item : etudiants), tu aurais pu écrirefor(auto const& item : etudiants). C'est ce que j'aurai fait en fait. Ça aurait permis de pouvoir réutiliser la liste après les yeux fermés, parce que là j'ai un doute sur l'état des éléments de etudiants après coup.Beaucoup.
Quant aux '<<', c'est sûrement mon passé de C, mais je trouve ça immonde. J'aime pas les iostreams... un bon vieux printf c'est tellement plus lisible. En tout cas, tu aurais pu mettre les 2 'std::cout' sur la même ligne.
1:
Et la taille de cette ligne, c'est une des raisons qui font que quand j'utilise un conteneur STL, j'utilise TOUJOURS un typedef.