IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Doit on abuser des algo et des foncteurs?


Sujet :

SL & STL C++

  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut Doit on abuser des algo et des foncteurs?
    Tout est dans le titre.
    J'aimerais avoir vos avis.

    merci

  2. #2
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Ben, en C++, tant qu'on aura pas un support bien officiel dans le langage des fonctions lambda et closures, ce sera toujours lourd à l'écriture.

    Mais sinon, utiliser une fonction d'ordre supérieur, c'est toujours plus agréable que d'écrire la boucle à la main, et souvent plus élégant, tu évites les erreurs (même si dans le cas des boucles idiomatiques, c'est très rare), et on sait explicitement ce que tu fais, parce qu'une fonction d'ordre supérieur a un nom.

    L'avantage est qu'un foncteur est réutilisable, et qu'il peut maintenir un état.
    Puis, l'avantage par rapport à une fonction tout court, c'est que c'est plus facile d'inliner.

    Pour autant, je n'écris presque jamais de foncteur directement, parce que je trouve que le gain par l'inlining se justifie très peu souvent (EDIT : et au prix d'une écriture lourde).
    S'il faut maintenir un état pour la fonction, je préfère currifier mes fonctions (avec [std|boost]::bind).

    -------

    Dans un langage fonctionnel, il n'y aurait pas de question à se poser, on manipule toujours des fonctions d'ordre supérieur, le code est concis.

    Le problème vient de C++, c'est tout.

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Idem. Je dirais, en C++98/C++03 : Pas encore. En C++0x, très probablement.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 21
    Points : 24
    Points
    24
    Par défaut
    Pour moi, la lourdeur de l'écriture des algo et functor rend le code peut lisible.

    Cela peut devenir même illisible lorsqu'il s'agit de code écrit par quelqu'un d'autre !

    Le problème de la maintenance de ce type de construction est le plus critique. Lorsque le code est 'simple' classique, les adaptation et modification sont facile a faire, par contre, lorsque l'on doit modifier le comportement d'un morceau de code contenant 3 ou 4 algo combinés (plus tous les functors adapteurs nécessaires), la modification est quasiment impossible.

  5. #5
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Je ne sais pas trop, je pense que chacun à ses préférences, mais moi j'utilise des foncteurs de plus en plus. Et je crois que si les noms de ces foncteurs sont explicite, ça n'enlève rien à la compréhension du code, voire même ça peut l'améliorer.

    Je que je fais, c'est que je met mes foncteurs dans l'en-tête de la classe à laquelle avec laquelle ils sont en relation. Ca reste ainsi une même entité.

    Outre les avantages cités ci-dessus, je rejouterai que ça peut permettre de simplifier l'interface d'une classe (interface dans le sens: "ensemble des fonctions membres publiques"). En effet, l'utilisation de foncteurs permet d'écrire une fonctionalité complexe en une ligne (notemment pour l'utilisation des algorithmes de la STL). Sans foncteur, cette fonctionnalité va certainement nécessité une fonction membre supplémentaire.

    Je ne sais pas si je m'explique bien, je suis mal réveillé
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par r0d Voir le message
    Je ne sais pas trop, je pense que chacun à ses préférences, mais moi j'utilise des foncteurs de plus en plus.
    Pareil qué miguel.

    Citation Envoyé par r0d Voir le message
    Outre les avantages cités ci-dessus, je rejouterai que ça peut permettre de simplifier l'interface d'une classe (interface dans le sens: "ensemble des fonctions membres publiques"). En effet, l'utilisation de foncteurs permet d'écrire une fonctionalité complexe en une ligne (notemment pour l'utilisation des algorithmes de la STL). Sans foncteur, cette fonctionnalité va certainement nécessité une fonction membre supplémentaire.
    Tout pareil: en fait, cela permet aussi de déporter des traitements internes d'une classe dans une classe associée (le functor). Donc comme dit r0d, l'interface de la classe se réduit de plus en plus aux services proposées et est expurgées des méthodes internes de pur implémentation. Le graal étant d'avoir une classe avec que des méthodes publiques, les détails d'implémentation étant masqués.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ça me fait penser à un travail de réecriture que j'ai réalisé récemment.

    J'ai remplacé du code du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    marcel_bubble_t* bubble = 0;
    int max_load = -1; 
    marcel_entity_t* e;
    for_each_entity_in_bubble_begin(entities, e) {
      if(e->type == MA_ENTITY_BUBBLE) {
        marcel_bubble_t* b = marcel_bubble_entity(e);
        if(is_interesting_bubble(b)) {
          int load = ma_entity_load(e);
          if(load > max_load) {
            max_load = load;
            bubble = b;
          }
        }
      }
    }
    for_each_entity_in_bubble_end;
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bubble_ptr bubble = deref_def(max_element(
      entities
        | match<bubble_ptr>()
        | filtered(is_interesting_bubble),
      load(_1) < load(_2)
    ));
    Pour moi il est évident que la seconde forme est plus sûre, car idiomatique, et plus facile à maintenir, car à la fois concise et exprimant clairement ce qu'elle fait.
    Mais les développeurs, réticent à apprendre de nouvelles manières de programmer, ont préféré la première parce qu'ils ne comprenaient pas la deuxième, et qu'ils connaissaient pas les bibliothèques qu'elle exploitait.
    Boost ftw

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ça me fait penser à un travail de réecriture que j'ai réalisé récemment.

    J'ai remplacé du code du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    marcel_bubble_t* bubble = 0;
    int max_load = -1; 
    marcel_entity_t* e;
    for_each_entity_in_bubble_begin(entities, e) {
      if(e->type == MA_ENTITY_BUBBLE) {
        marcel_bubble_t* b = marcel_bubble_entity(e);
        if(is_interesting_bubble(b)) {
          int load = ma_entity_load(e);
          if(load > max_load) {
            max_load = load;
            bubble = b;
          }
        }
      }
    }
    for_each_entity_in_bubble_end;
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bubble_ptr bubble = deref_def(max_element(
      entities
        | match<bubble_ptr>()
        | filtered(is_interesting_bubble),
      load(_1) < load(_2)
    ));
    Pour moi il est évident que la seconde forme est plus sûre, car idiomatique, et plus facile à maintenir, car à la fois concise et exprimant clairement ce qu'elle fait.
    Aucune des deux ne me semblent idiomatique en C++. La première m'a l'air écrite en C, la deuxième... en Lisp (a part que fermer des parenthèses sur une ligne autrement vide ne se fait pas en Lisp). En C++, si elle a certainement dépassé le stade purement expérimental -- il y a une sous-communauté, apparemment grandissante et en tout cas influente pour laquelle ce genre d'écriture est la marque de fabrique --, elle n'est pas encore la manière coutumière d'écrire du code. Même si elle fini par s'imposer hors de sa province, ce qui n'est pas encore certain, je doute que ce soit avant que le C++ 0X soit bien répandu -- ce qui prendra encore quelques années.

    Mais les développeurs, réticent à apprendre de nouvelles manières de programmer, ont préféré la première parce qu'ils ne comprenaient pas la deuxième, et qu'ils connaissaient pas les bibliothèques qu'elle exploitait.
    Tu as l'air d'accord avec moi. Si c'est une nouvelle manière de programmer, ce n'est pas idiomatique (mais comme je l'ai déjà écrit, ça ressemble plus à du C qu'à du C++ quand même).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Doit on abuser des algo et des foncteurs?
    Abuser? Jamais. Si tu considères que c'est abuser, tu donnes déjà la réponse.

    Après, le degré d'utilisation qui fait dépasser le niveau de l'abus change suivant le contexte. Le C++ est trop utilisé pour qu'il n'y ait pas de variation à ce genre de choses suivant le contexte.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    C'est idiomatique dans la mesure où on met en place des idiomes et on les utilise.
    Écrire le code à la main, pour moi il n'y a pas d'idiome.

    Sinon, c'est juste une utilisation de Boost.RangeEx (qui est dans la review queue), qui fournit des adaptateurs de ranges avec une syntaxe infixe à l'aide de l'opérateur "pipe".
    Boost ftw

  11. #11
    screetch
    Invité(e)
    Par défaut
    La réponse est : cacahuète. Je veux dire, la réponse est dans la question; doit on en abuser ? la connotation négative de abuser dit tout

    Quand on a le choix, c'est toujours une erreur de se brider en se forcant a utiliser toujours l'une. donc, pas tout foncteur, pas tout boucle for.
    La limite dépend ensuite des personnes; certaines trouvent ca compliqué a lire, d'autres trouvent ca trop long a ecrire, une vieille boucle for faisant aussi le boulot.

    On a envie de faire comme en python des fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list = [1/i for i in list if i != 0]
    les foncteurs sont loins de cette qualité d'ecriture, mais parfois plus pratique que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(std::vector<int>::iterator it = list.begin(); it  != list.end(); ++it)
    {
     if(*it != 0) *it = 1/*it;
    }
    enfin, je ne sais pas, ca depend des gens.

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    C'est aussi une question de gymnastique. Si tu n'en connais pas les principes, alors tu comprends beaucoup moins le code mis en œuvre. Mais une fois que tu es familier avec les principes, alors en général, paradoxalement, le code gagne en clarté et la conception est plus cohérente. Pour moi, le seul bémol, c'est que c'est parfois un peu délicat à debugger lorsqu'on veut entrer dans les algos plus en détail.

  13. #13
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [1/i for i in list if i != 0]
    ça peut s'exprimer avec par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list | filtered(_1 != 0) | transformed(1/_1);
    Boost ftw

  14. #14
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [1/i for i in list if i != 0]
    ça peut s'exprimer avec par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list | filtered(_1 != 0) | transformed(1/_1);
    Par contre, comme d'habitude, si tu manipules des choses plus compliquées que des [int|float|double|char], comme des structures, on doit se taper des (&Type:: ) ?

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list | filtered(_1 != 0) | transformed(1/_1);
    Sait tu où je pourrais trouver des info sur boost.rang_ex? (c'est bien cette lib?)
    Je n'ai pas trouvé grand chose sur google...

  16. #16
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    http://boost-sandbox.sourceforge.net...tml/index.html

    Documentation pas à jour encore.

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par HanLee Voir le message
    C'est celle la que j'ai trouvé...
    Cette partie sera intégrer dans boost?

  18. #18
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Par contre, comme d'habitude, si tu manipules des choses plus compliquées que des [int|float|double|char], comme des structures, on doit se taper des (&Type:: ) ?
    Il faut fournir des foncteurs. Après tu te débrouilles comme tu veux pour les générer.
    L'idéal c'est quand même d'éviter les pointeurs vers les membres un maximum, c'est quand même super moche ces trucs-là (en plus d'être assez inefficace sur certains compilateurs et non polymorphe).
    Boost ftw

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/10/2009, 10h36
  2. Trigger pour mettre des droits sur des procedures et des vues
    Par briino dans le forum Développement
    Réponses: 3
    Dernier message: 23/09/2009, 09h44
  3. Réponses: 4
    Dernier message: 02/04/2008, 17h51
  4. Réponses: 3
    Dernier message: 13/09/2007, 18h11
  5. Réponses: 3
    Dernier message: 23/01/2007, 08h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo