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

  1. #41
    Expert éminent
    Citation Envoyé par el_slapper Voir le message
    La plupart des gens vont se gargariser de "programmation fonctionnelle" parce-qu’ils ont collé 3 misérables fonctions dans leur procédural (organisé dans des objets ou pas).

    D’où la confusion.
    Non pas forcément les lambdas (+ la notion de fermeture) et les fonctions d’ordre supérieur, c'est 1 partie de la programmation fonctionnelle.

  2. #42
    Expert confirmé
    Citation Envoyé par foetus Voir le message
    Non pas forcément les lambdas (+ la notion de fermeture) et les fonctions d’ordre supérieur, c'est 1 partie de la programmation fonctionnelle.
    Quelles sont les autres parties ? Tout le monde semble avoir sa propre définition.

  3. #43
    Expert éminent
    Citation Envoyé par SimonDecoline Voir le message
    Quelles sont les autres parties ? Tout le monde semble avoir sa propre définition.
    Cela a été dit avant tout est fonction (avec énormément de récessivité et d'imbrications d'appels), pas de variables mais utilisation de listes/ tuples, pas de types (**) ... et des fonctions essentielles comme map, filter, reduce, ...
    Des concepts très importants sont nécessaires : lambda/ fonctions anonymes, récursion terminale ("tail-recursive"), les fonctions d'ordre supérieur, [la transparence référentielle, les effets de bord, les fonctions pures, la composition de fonctions, la curryfication, l’arité (*)], ...
    Je me demande si le fait que ce soit des langages interprétés avec 1 environnement d'exécution est 1 condition valable

    Après vérification, Lisp a des variables, mais il me semble que c'est à l'exécution : passage de paramètres, récupération de résultat, ...


    * : trouvé sur 1 autre site, là je sèche - à prendre avec des pincettes.
    ** : effectivement certains langages fonctionnels ont 1 typage statique

  4. #44
    Expert confirmé
    Citation Envoyé par foetus Voir le message
    ...
    pas de types
    ...
    ok donc elm, ocaml, haskell, ce n'est pas du fonctionnel alors.

  5. #45
    Expert éminent
    Hmmm, après lecture de Wikipedia, je viens de comprendre la différence entre "programmation procédurale" et "programmation fonctionnelle"... et "POO"

    Seulement, j'avoue ne toujours pas comprendre !

    En effet...

    La POO englobe la programmation procédurale.

    Et la programmation fonctionnelle n'est qu'un paradigme parmi d'autres qui implique qu'une fonction ne peut pas modifier de données autres que locales.

    Je ne vois absolument pas en quoi c'est incompatible avec la POO !

    Tout du moins, si, je vois, mais rien n'empêche de travailler proprement avec les deux en même temps.

    J'ai appris en cours il y a longtemps qu'une "procedure fait quelque chose" (et donc modifie potentiellement les données passées en paramètre ou globales) tandis qu'une "fonction vaut quelque chose", et dans ce cas, autant elle retourne une valeur, autant elle ne modifie rien aux données autre que locales (faire de la programmation fonctionnelle revient donc à n'utiliser que des "fonction" répondant à cette définition).

    Ceci est vrai avec le langage ADA, qui a servit d'illustration à mes cours, mais aussi en T-SQL (langage procédurale de SQL Server).
    Il me semble que c'est vrai aussi avec le Pascal.
    VB par contre, non, rien n'empêche une fonction de modifier les données passées en paramètre, ou de modifier un objet. En revanche la procédure ne peut jamais rien retourner comme résultat.

    Après, la plupart des langages POO sont dérivées de près ou de loin du C, qui ne fait pas la différence entre procédure et fonction : il n'y a que des fonctions, et vogue la galère avec des fonctions qui valent et font à la fois des choses dans la plus grande impunité.

    Cependant, rien n'empêche d'imposer comme règle de développement d'effectuer la distinction entre "fonction" (fonction ou méthode qui retourne une valeur) et "procédure" (fonction ou méthode qui retourne void).
    Et à ce moment d'interdire à une "fonction" d'appeler une procédure ni de modifier quoi que ce soit d'autre que des variables locales.
    Je pense même qu'avec un peu de travail, il doit être possible de mettre en place des règles de validation du code qui s'en assurent, aussi bien dans Visual Studio que dans Eclipse.

    A partir de là, la programmation fonctionnelle est parfaitement possible en POO.
    Cependant, je ne vois pas comment on peut travailler sans jamais rien modifier... y'a bien un moment où le résultat des opérations doit être stocké quelque part, en lieu de place des données d'origine qui sont devenues caduques... un programme ne peut être composé que de fonctions, ou alors il ne fait rien (par définition, mais il vaut quelque chose, c'est déjà ça ).

    Y'a bien un moment où on devra utiliser une procédure, que ce soit pour mettre à jour les données dans une base, un fichier, ou à l'écran !
    On ne jouit bien que de ce qu’on partage.

  6. #46
    Expert confirmé
    Citation Envoyé par StringBuilder Voir le message
    Y'a bien un moment où on devra utiliser une procédure, que ce soit pour mettre à jour les données dans une base, un fichier, ou à l'écran !
    Pas forcément. Si le programme lui-même est une fonction, il peut prendre tout cet environnement comme paramètre, en entrée, et retourner un environnement modifié, en sortie.

  7. #47
    Expert éminent
    Citation Envoyé par SimonDecoline Voir le message
    ok donc elm, ocaml, haskell, ce n'est pas du fonctionnel alors.
    D'après la page wiki en anglais, Purely functional programming, le Lisp n'est pas un langage fonctionnel pur

    La "pureté" repose sur la non-mutabilité des données ("Purely functional programming may also be defined by forbidding changing-state and mutable data.") mais également sur des fonctions pures qui retournent la même chose pour 1 même argument (avec 1 idée de persistance et de désactiver les effets de bords)


    Citation Envoyé par StringBuilder Voir le message
    A partir de là, la programmation fonctionnelle est parfaitement possible en POO.
    Après vérifications, cela rejoint mon précédent message et tout ce que tu décris est lié aux fonctions pures.

    Mais pas forcément. En C++, langage objet, il faut utiliser le C++ moderne (>= C++11) pour avoir les lambdas et les fonctions d'ordre supérieure. Sinon, tu ne peux pas faire de programmation fonctionnelle.

  8. #48
    Expert confirmé
    Citation Envoyé par foetus Voir le message
    D'après la page wiki en anglais, Purely functional programming, le Lisp n'est pas un langage fonctionnel pur

    La "pureté" repose sur la non-mutabilité des données ("Purely functional programming may also be defined by forbidding changing-state and mutable data.") mais également sur des fonctions pures qui retournent la même chose pour 1 même argument (avec 1 idée de persistance et de désactiver les effets de bords)
    Ma remarque portait sur elm, ocaml et haskell, par rapport aux types.
    Donc en fait on peut avoir des types en fonctionnel alors.

  9. #49
    Expert éminent
    Citation Envoyé par SimonDecoline Voir le message
    Ma remarque portait sur elm, ocaml et haskell, par rapport aux types.
    Donc en fait on peut avoir des types en fonctionnel alors.
    Je ne connais pas ces langages , mais d'après ce que j'ai pu comprendre, le typage n'a rien à voir avec le paradigme fonctionnel
    Le typage statique permet 1 compilation et donc 1 détection de bogues (pas tous) - et donc c'est plus rassurant
    Mais je me demande si ces langages sont encore interprétés, si ce sont que des "scripts"

  10. #50
    Expert éminent
    Citation Envoyé par foetus Voir le message

    mais également sur des fonctions pures qui retournent la même chose pour 1 même argument
    N'est pas la définition d'une fonction déterministe ?
    Hmmm, oui, plus, ça doit être une "vraie" fonction dans la mesure où elle ne doit rien faire.



    Citation Envoyé par foetus Voir le message

    En C++, langage objet, il faut utiliser le C++ moderne (>= C++11) pour avoir les lambdas et les fonctions d'ordre supérieure. Sinon, tu ne peux pas faire de programmation fonctionnelle.
    Les lambdas ne sont-elles pas au final une simple écriture plus élégante des delegate ou même pointeur de fonction ? Si je ne m'abuse, cette dernière est bien plus ancienne que C++ 11 non ?
    On ne jouit bien que de ce qu’on partage.

  11. #51
    Expert éminent
    Citation Envoyé par StringBuilder Voir le message
    N'est pas la définition d'une fonction déterministe ?
    Hmmm, oui, plus, ça doit être une "vraie" fonction dans la mesure où elle ne doit rien faire.
    Je ne suis pas expert sur les termes , mais d'après ce que j'ai compris oui c'est 1 fonction déterministe (qui n'utilise pas 1 variable globale, statique ou saisie par l'utilisateur), et 1 fonction qui ne modifie pas ses paramètres.


    Citation Envoyé par StringBuilder Voir le message
    Les lambdas ne sont-elles pas au final une simple écriture plus élégante des delegate ou même pointeur de fonction ? Si je ne m'abuse, cette dernière est bien plus ancienne que C++ 11 non ?
    Avec les lambdas, tu as la notion de fermeture ("closure" en anglais) absent des pointeurs de fonction.

    Et n'oublie pas qu'en programmation fonctionnelle tout est fonction - donc cela va plus loin que coder des delegates mais passer 1 fonction en paramètre (par exemple exemple, multiplier par 2 tous les éléments d'1 liste), retourner 1 fonction (et ainsi la stocker dans 1 variable pour l'appeler avec différents paramètres).

    Ce genre de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function makeAdder(x) {
      return function(y) {
        return x + y;
      };
    }
    
    var add5  = makeAdder(5);
    var add10 = makeAdder(10);
    
    console.log( add5(2) );  // 7
    console.log( add10(2) ); // 12

    Édit : En C++ tu as les foncteurs - les classes dont on surcharge l'opérateur (), et qui permet de les appeler comme une fonction. 1 foncteur permet de faire des fonctions avec 1 contexte/ des états.
    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
    17
    18
    class makeAdder {
    public:
    
        makeAdder(int input_x = 0) : x(input_x) {}
    
        int operator() (int y) { return (y + x); }
    
    private:
    
        int x;
    };
    
    // ..
    
        makeAdder add5(5);
        makeAdder add10(10);
    
        std::cout << "5 + 2 = " << add5(2) << std::endl << "10 + 2 = " << add10(2) << std::endl;

  12. #52
    Expert confirmé
    Citation Envoyé par foetus Voir le message
    Édit : En C++ tu as les foncteurs - les classes dont on surcharge l'opérateur (), et qui permet de les appeler comme une fonction. 1 foncteur permet de faire des fonctions avec 1 contexte/ des états.
    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
    17
    18
    class makeAdder {
    public:
    
        makeAdder(int input_x = 0) : x(input_x) {}
    
        int operator() (int y) { return (y + x); }
    
    private:
    
        int x;
    };
    
    // ..
    
        makeAdder add5(5);
        makeAdder add10(10);
    
        std::cout << "5 + 2 = " << add5(2) << std::endl << "10 + 2 = " << add10(2) << std::endl;

    Exact, bien vu. Ca existe depuis les années 90 en fait, mais les lambda C++ 11 simplifient quand même beaucoup:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    std::function<int(int)> makeAdder2(int x) {
        return [x](int y) { return y + x; };
    }
    
    // ...
            auto add5 = makeAdder2(5);
            auto add10 = makeAdder2(10);
            std::cout << "5 + 2 = " << add5(2) << std::endl << "10 + 2 = " << add10(2) << std::endl;

  13. #53
    Expert éminent
    Citation Envoyé par foetus Voir le message
    J
    Ce genre de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function makeAdder(x) {
      return function(y) {
        return x + y;
      };
    }
    
    var add5  = makeAdder(5);
    var add10 = makeAdder(10);
    
    console.log( add5(2) );  // 7
    console.log( add10(2) ); // 12
    Le code de ta fonction "function(y)" me laisse perplexe.

    En effet, tu lui passes en paramètre y et elle retourne x + y.
    Par conséquent, elle utilise le paramètre x de makeAdder qu'elle n'a pas reçu : n'est-ce pas justement l'inverse d'une fonction pure ? Je ne vois aucune différence entre x ici et un membre readonly dans une classe.

    Aussi, et là je pige plus rien :
    add5 et add10 sont manifestement des variables.

    Quant à console.log() il s'agit de toute évidence d'une procédure et non d'une fonction : elle ne retourne pas de paramètre, et modifie l'état de la sortie écran.

    Enfin, je ne vois pas ce qui change (je parle fonctionnellement parlant, ou algorythmement parlant, pas syntaxiquement ou matériellement parlant) par rapport à un code objet classique :

    Code csharp :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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    using System;
     
    namespace Fonctionnel
    {
        class Program
        {
            static void Main()
            {
                Adder add5 = new Adder(5);
                Adder add10 = new Adder(10);
     
                Console.WriteLine($"5 + 2 = {add5.Add(2)}");
                Console.WriteLine($"10 + 2 = {add10.Add(2)}");
            }
        }
     
        class Adder
        {
            readonly int X;
            public Adder(int x)
            {
                X = x;
            }
     
            public int Add(int y)
            {
                return this.X + y;
            }
        }
    }


    Bon, j'imagine qu'avec un exemple plus complexe, c'est moins trivial, mais pour le coup, je ne vois pas du tout la moindre différence en termes de "sécurité" du code notamment.

    Si le débat ne concerne que la syntaxe, alors le débat est clos depuis la fin des années 70 quand les langages impératifs sont devenus objet et ont enterré les langages fonctionnels... justement à cause de la syntaxe indigeste et impossible à maintenir.
    On ne jouit bien que de ce qu’on partage.

  14. #54
    Expert confirmé
    Citation Envoyé par StringBuilder Voir le message
    En effet, tu lui passes en paramètre y et elle retourne x + y.
    Par conséquent, elle utilise le paramètre x de makeAdder qu'elle n'a pas reçu : n'est-ce pas justement l'inverse d'une fonction pure ? Je ne vois aucune différence entre x ici et un membre readonly dans une classe.
    C'est justement ça la notion de fermeture. La fonction "interne" est définie par rapport à la fonction englobante. On a donc une fonction qui construit et retourne une fonction (qui n'est donc pas toujours la même). Et ça on ne peut pas le faire de façon pure avec les pointeurs de fonction.

    Citation Envoyé par StringBuilder Voir le message
    Aussi, et là je pige plus rien :
    add5 et add10 sont manifestement des variables.
    Oui, mais ce sont aussi des fonctions. En fonctionnel, on dit que les fonctions sont des citoyens de première classe car elle sont une valeur comme une autre et peuvent donc être affectées à des variables.

    Citation Envoyé par StringBuilder Voir le message
    Quant à console.log() il s'agit de toute évidence d'une procédure et non d'une fonction : elle ne retourne pas de paramètre, et modifie l'état de la sortie écran.
    Oui, c'est une procédure. JavaScript n'est pas "pur" fonctionnel et fait des side-effects pour l'affichage.

    Citation Envoyé par StringBuilder Voir le message
    Enfin, je ne vois pas ce qui change (je parle fonctionnellement parlant, ou algorythmement parlant, pas syntaxiquement ou matériellement parlant) par rapport à un code objet classique :
    Déjà ton code est plus long et surtout tu perds la notion de "fonction appelable". Avec le foncteur, tu sais que tu peux l'appeler juste en mettant les paramètres entre parenthèse. Dans ton code, tu dois savoir quelle méthode appeler. Ca n'a l'air de rien mais c'est très important car un foncteur peut être passé en paramètre, de façon homogène, à une autre fonction, par exemple pour des fonctions map, filter ou reduce.

  15. #55
    Expert éminent
    J'avoue que ça ne me parle pas.

    En fait, je ne vois que des différences syntaxiques.

    Ca pourrait tout aussi bien être un débat "le BASIC c'est mieux que le C car y'a pas besoin de mettre des points virgule ni des accolades, c'est moins long à taper".

    Je ne vois pas ce qu'il est possible de faire/garantir en "fonctionnel" qu'on ne saurait faire avec les mêmes garanties en "POO".

    Je persiste et signe, j'ai surtout l'impression que le souci réside dans l'absence de différence entre "procédure" et "fonction", ainsi qu'entre "fonction déterministe ou non".

    En effet, en POO on peut parfaitement avoir une méthode Add() qui retourne le résultat d'une somme, mais aussi qui modifie l'objet. Parfois les deux, ce qui est d'autant plus déroutant.
    Mais à mon sens, le débat n'est pas de savoir s'il faut faire de la POO ou du fonctionnel, mais avant tout de se mettre d'accord sur des règles de codage et s'entendre sur la sémantique.

    Pour le reste, en effet, si demain ma touche ";" ne fonctionne plus sur mon clavier, en attendant d'en racheter un autre, j'utiliserai VB... Mais c'est pas une justification "valable" pour dire que VB est préférable à C#.

    Enfin, dire que :
    - moins de code c'est mieux
    - les expression lambda qui permettent de faire un ERP en une ligne c'est mieux
    - encapsuler sur 25 niveaux avec chacun 2 lignes c'est mieux que d'avoir 25 fonctions de même niveau de 2 lignes

    A mon sens c'est avant tout une question de goût (débat de syntaxe toujours).
    Et de mon point de vue perso, moins de code, c'est pas forcément mal, mais les lambas, les types anonymes ou implicites (var), et les encapsulations à gogo avec rappel du contexte parent, ce sont avant tout des usines à bug, que chaque personne qui devra débugger va devoir réécrire totalement faute de comprendre ce que l'auteur original à voulu faire.

    Autant un truc comme :
    Code csharp :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    decimal somme = MaList.Sum(a => a.Quantity * a.Price);

    Je trouve ça lisible et reste raisonnable, autant ça peut vite devenir un bordel impossible à comprendre (par exemple avec Linq en C# où tu peux arriver à des spaghettis indigestes)

    Code csharp :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var query = from product in db.Products
                where product.ProductId == productId
                select new { 
                    Product = product,
                    Approvers = product.Approvers.Where(pa => pa.Version == version)
                };

    => Là, sans relire toute la définition de la classe db, impossible de déterminer ce que ça va réellement me ramener... quant au type retourné, toujours pas pigé l'intérêt puisqu'après on ne peut rien en faire (pas de méthode, impossible de le passer en paramètre à une méthode qui ne saura pas quoi en faire, etc.)
    On ne jouit bien que de ce qu’on partage.

  16. #56
    Expert confirmé
    Citation Envoyé par StringBuilder Voir le message
    Et de mon point de vue perso, moins de code, c'est pas forcément mal, mais les lambas, les types anonymes ou implicites (var), et les encapsulations à gogo avec rappel du contexte parent, ce sont avant tout des usines à bug, que chaque personne qui devra débugger va devoir réécrire totalement faute de comprendre ce que l'auteur original à voulu faire.
    C'est exactement le sujet de l'article. Tu dis ça parce que tu as l'habitude du procédural/POO mais si tu avais l'habitude du fonctionnel, tu dirais exactement le contraire. Aujourd'hui on se lance dans de l'objet à la java/c++ par réflexe et l'article pose la question de savoir si c'est vraiment une bonne idée. Et quand on remarque que même les langages mainstream (java, c++, etc) intègrent du fonctionnel depuis quelques années (lambdas, etc), on peut penser que non ce n'est pas une bonne idée.

    Citation Envoyé par StringBuilder Voir le message
    => Là, sans relire toute la définition de la classe db, impossible de déterminer ce que ça va réellement me ramener... quant au type retourné, toujours pas pigé l'intérêt puisqu'après on ne peut rien en faire (pas de méthode, impossible de le passer en paramètre à une méthode qui ne saura pas quoi en faire, etc.)
    Justement l'idée du typage c'est de savoir ce qu'on manipule et de le vérifier automatiquement par le compilateur. Mais c'est un autre débat, un peu indépendant du fonctionnel.

  17. #57
    Expert éminent
    Citation Envoyé par SimonDecoline Voir le message
    C'est exactement le sujet de l'article. Tu dis ça parce que tu as l'habitude du procédural/POO mais si tu avais l'habitude du fonctionnel, tu dirais exactement le contraire. Aujourd'hui on se lance dans de l'objet à la java/c++ par réflexe et l'article pose la question de savoir si c'est vraiment une bonne idée. Et quand on remarque que même les langages mainstream (java, c++, etc) intègrent du fonctionnel depuis quelques années (lambdas, etc), on peut penser que non ce n'est pas une bonne idée.
    J'ai quand même l'impression qu'on est sur un débat universitaire sans lien avec la réalité du terrain.

    Personnellement, aussi bien en tant que développeur, que chef de projet, je vais choisir C# ou Java (et non C++ ou VB) pour deux raisons, et deux raisons seulement :
    - Ces langages, même si ce ne sont pas les plus adaptés à une problématique donnée, sauront apporter une réponse viable à ma problématique
    - Moi-même ou mes équipes maîtrisent suffisamment ces langages pour produire un code rapidement, fiable et maintenable

    Donc à aucun moment je ne choisirai F# ou LISP, non pas parce qu'ils sont fonctionnels, mais parce que :
    - Je ne suis pas certain qu'ils soient adaptés à la résolution de toutes les problématiques (probablement parce que je ne les connais pas)
    - Personne dans mon entourage n'est capable de pondre la moindre ligne de ces langages sans suivre 2 jours de tutoriels, et après ces deux jours, personne dans mon équipe n'aura le recul nécessaire pour justifier pourquoi il a écrit un code plutôt qu'un autre

    C'est pour ces mêmes raisons que je ne choisirai pas C++ ni VB (même si pour ce dernier j'ai l'expérience nécessaire, mais j'ai pas envie )

    En revanche, si demain j'utilise depuis mon programme C# ou Java une librairie externe, je serai indifférent à la techno "interne" de cette dernière du moment qu'elle est stable et fiable. Ca peut être du LISP, du C# ou même du JavaScript, du moment qu'elle fait ce que je lui demande, pas de souci.

    En revanche, jamais de la vie je ne vais dépenser plus de 2 minutes à me former moi-même ou mes équipes sur un langages particulier "parce qu'il peut être un peu mieux ou plus adapté pour certaines choses, mais pas tout le temps, et au final n'apporte franchement... rien ou presque".


    Finalement, pour en revenir à la syntaxe "fonctionnelle" qui intègre petit à petit la "POO", j'ai un avis très mitigé.
    Les expression Lambda par exemple peuvent être très intéressantes pour des opérations simples, mais peuvent aussi s'avérer être des usines à gaz.
    Par plus tard que la semaine dernière, je suis tombé sur ça dans un programme qui imprime une facture :
    Code csharp :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    decimal prixTotal = Produits.Sum(x => x.Quantite * x.PrixUnitaire);
    int quantiteTotale = Produits.Sum(x => x.Quantite);
    int nombreArticles = Produits.Sum(x => 1);


    Certes, ça aurait été plus long à taper, mais je m'attendais plutôt à ce code, qui est 3 fois plus rapide, à quelques pouillèmes près :
    Code csharp :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    decimal prixTotal = 0;
    int quantiteTotale = 0;
    int nombreArticles = Produits.Length;
     
    foreach (Produit p in Produits)
    {
       prixTotal += p.Quantite * p.PrixUnitaire;
       quantiteTotale += p.Quantite;
    }


    Donc les expressions Lambda c'est pas mal, mais ça dispense un peu de réfléchir, et ça peut vite nuire non pas à la lisibilité du code (quoique...) mais surtout à ces performances.
    Le souci, c'est que si au début le programme n'a besoin que du prix total, on va choisir en toute logique l'expression lamba, car plus rapide à écrire et plus lisible.
    Mais si ensuite on commande à demander de nouvelles évolutions, à quel moment doit-on faire le choix de réécrire toute une partie du programme, pour préserver les performances ?
    Bref, d'ici quelques années (enfin, déjà maintenant, nos téléphones ont plus de puissance de calcul que l'infra de tous les projets Apollo réunis, et rament rien que pour afficher un SMS) on va se retrouver avec des programmes qui se seront transformés en usine à gaz... pas sûr que ce soit un vrai gain au final.
    On ne jouit bien que de ce qu’on partage.

  18. #58
    Expert confirmé
    Citation Envoyé par StringBuilder Voir le message
    En revanche, jamais de la vie je ne vais dépenser plus de 2 minutes à me former moi-même ou mes équipes sur un langages particulier "parce qu'il peut être un peu mieux ou plus adapté pour certaines choses, mais pas tout le temps, et au final n'apporte franchement... rien ou presque".
    Je pense que c'est encore cette question d'habitude. Je n'ai pas connu cette époque mais j'imagine que quand la POO est apparue dans les années 70/80, beaucoup de devs fortran se sont dit qu'ils n'en voyaient pas l'intérêt et que ça n'apportait rien au final.

    Citation Envoyé par StringBuilder Voir le message
    Par plus tard que la semaine dernière, je suis tombé sur ça dans un programme qui imprime une facture :
    Code csharp :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    decimal prixTotal = Produits.Sum(x => x.Quantite * x.PrixUnitaire);
    int quantiteTotale = Produits.Sum(x => x.Quantite);
    int nombreArticles = Produits.Sum(x => 1);

    ...
    Bref, d'ici quelques années (enfin, déjà maintenant, nos téléphones ont plus de puissance de calcul que l'infra de tous les projets Apollo réunis, et rament rien que pour afficher un SMS) on va se retrouver avec des programmes qui se seront transformés en usine à gaz... pas sûr que ce soit un vrai gain au final.
    Dans un "vrai langage fonctionnel", on écrirait plutôt quelque chose comme ça. Et avec un peu d'habitude, on voit le "reduce" et on a tout de suite une bonne idée de ce que ça fait.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    calcul = p (prix, quantite) => (prix + p.PrixUnitaire*p.Quantite, quantite + p.Quantite)
    (prixTotal, quantiteTotal) = reduce(Produits, (0, 0), calcul)

  19. #59
    Expert éminent sénior
    Citation Envoyé par StringBuilder Voir le message
    J'ai quand même l'impression qu'on est sur un débat universitaire sans lien avec la réalité du terrain.
    Non parce que lambda + closures + currying + partial application = un formidable moins natif d'effectuer de l'injection de dépendance.

    Tu passes des fonctions qui font des I/O en paramètre et tu te retrouves avec un mécanisme d'injection simple comme bonjour qui te facilite tellement l'écriture de tes tests que ça devient simple comme bonjour.
    Un problème avec Git ? Essayez la FAQ, sinon posez votre question sur le forum.



    "Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
    Kenneth E. Boulding

    "Les richesses naturelles sont inépuisables, car, sans cela, nous ne les obtiendrions pas gratuitement. Ne pouvant être ni multipliées ni épuisées, elles ne sont pas l’objet des sciences économiques."
    Jean-Baptiste Say, Traité d'économie politique, 1803.

    "/home/earth is 102% full ... please delete anyone you can."
    Inconnu

  20. #60
    Expert éminent
    Citation Envoyé par SimonDecoline Voir le message

    Je pense que c'est encore cette question d'habitude. Je n'ai pas connu cette époque mais j'imagine que quand la POO est apparue dans les années 70/80, beaucoup de devs fortran se sont dit qu'ils n'en voyaient pas l'intérêt et que ça n'apportait rien au final.
    Ca me fait bizarre de dire ça, mais 41 ans, ça doit être un cap, je suis entrain de me transformer en dinosaure... Je pense qu'à ce époque, les développeurs Fortran n'ont pas vu l'intérêt de passer à la POO, car effectivement, ça n'apportait aucune solution à des problématiques qu'ils ne savaient déjà résoudre.
    A mon sens, le débat est le même ici (quoi que c'est pire, car on tente une espèce de fuite en arrière) : les langages fonctionnels apportent certaines solution élégantes pour résoudre certaines problématiques que la POO sait déjà résoudre, et à côté de ça imposent des restrictions pour d'autres traitements que la POO résout de façon plus élégante.

    A partir de là, j'ai envie de dire que chacun choisi l'outil qui lui convient en fonction de son appétence pour l'une ou l'autre des solutions.
    Je n'irais pas dire que l'un est mieux que l'autre, simplement que je ne vois pas l'intérêt d'imposer l'un contre l'autre.

    Le Fortran est mort principalement parce qu'il a arrêté d'évoluer, et que "politiquement" il a été décidé qu'il fallait le mettre au placard.

    Microsoft a inventé le Basic à peu près à la même époque, et pourtant VB.NET est toujours très utilisé. Alors oui, je suis d'accord, ça n'a rien à voir ou presque avec le BASIC de l'époque... Mais rien n'aurait empêché d'avoir un Fortran.NET ou autre, qui aurait implémenté des évolutions supportant la comparaison avec C++ ou Java, ce qu'a fait Microsoft en portant VB sur son Framework .NET.
    Et quand on y regarde bien, C++ 11 n'a plus rien à voir sur bien des points avec la première mouture, et un programme en C des années 80 ne compilera pas sur un gcc flambant neuf (alors que le *.exe généré à l'époque peut parfaitement encore tourner sous certaines conditions).

    Citation Envoyé par Marco46 Voir le message
    Non parce que lambda + closures + currying + partial application = un formidable moins natif d'effectuer de l'injection de dépendance.
    Je ne parlais pas de ce débat, mais celui de décider d'abandonner un langage (et toute une méthodologie) au profit d'un autre sous prétexte que pour faire ça ou ça, parfois c'est plus adapté.

    Si tu as des équipes de 200 personnes, tu peux te permettre d'en former 10, 15, 20% sur une dizaine de langages/technos différentes, puis "faire tes courses" en fonction d'un besoin précis (à condition que toi-même ait suffisamment de recul sur chaque langage/techno pour faire un choix qui tienne la route).
    Mais la réalité est généralement autre, les équipes sont souvent bien plus réduites, et le chef de projet est mono ou bi-techno maxi. Donc habitude ou non, il n'a pas vraiment d'autre choix que d'utiliser les outils qu'il a à disposition et que son équipe sait utiliser.
    On ne jouit bien que de ce qu’on partage.

###raw>template_hook.ano_emploi###