54 votes

Programmation fonctionnelle en C++

Quelqu'un peut-il me guider dans la programmation fonctionnelle en C++ ? Existe-t-il un bon matériel en ligne auquel je peux me référer ?

Veuillez noter que je connais la bibliothèque FC++. Je veux savoir comment faire cela avec la bibliothèque standard C++ seule.

Merci.

20 votes

Il est préférable d'utiliser un langage de programmation fonctionnel (LISP, Haskell, Scheme, ...). De cette façon, vous êtes sûr que ce que vous faites est bien de la programmation fonctionnelle.

4 votes

Quel type de caractéristiques de la FP recherchez-vous ? Boost fournit quelques bibliothèques de type FP (mpl, function, lambda, etc) et certaines d'entre elles seront dans C++0x et sont déjà dans TR1.

0 votes

@Brian : Je veux juste avoir un aperçu de la FP sans apprendre un nouveau langage. Et pour l'instant, je ne connais que C++ et Java. Et je pense que Java serait une option encore pire pour la FP.

49voto

Derrick Turk Points 2693

Vous pouvez accomplir une quantité surprenante de style "programmation fonctionnelle" avec le C++ moderne. En fait, le langage s'est orienté dans cette direction depuis sa standardisation.

La bibliothèque standard contient des algorithmes analogues à map, reduce, etc (for_each, transform, adjacent_sum...). La prochaine révision, C++0x, contient de nombreuses fonctionnalités conçues pour permettre aux programmeurs de travailler avec ces algorithmes dans un style plus fonctionnel (expressions lambda, etc.).

Consultez les différentes bibliothèques Boost pour vous amuser davantage. Pour illustrer le fait que le C++ standard contient beaucoup de fonctionnalités, voici une fonction factorielle dans le style du passage par continuation en C++ standard.

#include <iostream>

// abstract base class for a continuation functor
struct continuation {
    virtual void operator() (unsigned) const = 0;
};

// accumulating continuation functor
struct accum_cont: public continuation {
    private:
        unsigned accumulator_;
        const continuation &enclosing_;
    public:
        accum_cont(unsigned accumulator, const continuation &enclosing)
            : accumulator_(accumulator), enclosing_(enclosing) {}; 
        virtual void operator() (unsigned n) const {
            enclosing_(accumulator_ * n);
        };
};

void fact_cps (unsigned n, const continuation &c)
{
    if (n == 0)
        c(1);
    else
        fact_cps(n - 1, accum_cont(n, c));
}

int main ()
{
    // continuation which displays its' argument when called
    struct disp_cont: public continuation {
        virtual void operator() (unsigned n) const {
            std::cout << n << std::endl;
        };
    } dc;

    // continuation which multiplies its' argument by 2
    // and displays it when called
    struct mult_cont: public continuation {
        virtual void operator() (unsigned n) const {
            std::cout << n * 2 << std::endl;
        };
    } mc;

    fact_cps(4, dc); // prints 24
    fact_cps(5, mc); // prints 240

    return 0;
}

Ok, j'ai un peu menti. C'est une factorielle foncteur . Après tout, les fermetures sont les objets du pauvre... et vice versa. La plupart des techniques fonctionnelles utilisées en C++ reposent sur l'utilisation de foncteurs (c'est-à-dire d'objets fonctionnels) - vous le verrez largement dans la STL.

1 votes

Bel exemple. Mais je dois dire que le choix des noms d'identifiants est très mauvais. Donc, si vous pouviez modifier votre message et utiliser de meilleurs noms d'identifiants. J'ai voté pour vous en passant. Merci ! :)

2 votes

"Après tout, les fermetures sont les objets du pauvre... et vice versa. Je ne suis pas d'accord. oui, vous pouvez implémenter l'un en utilisant l'autre... mais que se passe-t-il si vous voulez réimplémenter des objets basés sur des foncteurs ? un désordre hideux. et si vous réimplémentez des fermetures par-dessus des objets basés sur des fermetures ? cela se défait (presque) des concepts 'natifs'. Ainsi, je pense que les fermetures sont loin plus appropriés comme "primitives" que comme objets (et ne me lancez pas sur les objets basés sur des classes !)

0 votes

Merci, Jacob ! J'ai nettoyé un peu l'exemple. Il n'a jamais été destiné à être exposé au public ; je venais de lire Lambda : The Ultimate Imperative un jour et je voulais essayer CPS en C++. Mais ensuite, j'ai vu cette question et j'ai dû la partager...

26voto

Eli Bendersky Points 82298

Mise à jour en août 2014 : Cette réponse a été publiée en 2009. C++11 a considérablement amélioré les choses pour la programmation fonctionnelle en C++, donc cette réponse n'est plus exacte. Je la laisse ci-dessous à titre de référence historique.

Puisque cette réponse est restée la réponse acceptée, je la transforme en un Wiki communautaire. N'hésitez pas à l'améliorer de manière collaborative pour ajouter de vrais conseils sur la programmation de fonctions avec le C++ moderne.


Vous ne pouvez pas faire vrai la programmation fonctionnelle avec C++. Tout ce que l'on peut faire, c'est l'approcher avec beaucoup de difficultés et de complexité (bien qu'en C++11 ce soit un peu plus facile). Cette approche n'est donc pas recommandée. Le C++ supporte relativement bien d'autres paradigmes de programmation et, à mon avis, il ne devrait pas être adapté à des paradigmes qu'il supporte moins bien - au final, il en résultera un code illisible que seul l'auteur comprendra.

18 votes

C'est PAS programmation ludique de la FP en C++. Pour s'amuser à programmer la FP avec Lisp ou Haskell

1 votes

J'apprendrais sûrement la langue FP un jour. Mais maintenant, je n'ai pas le temps pour cela.

13 votes

Mais je me dois d'insister :-) Cela prendra moins de temps que d'apprendre à le faire en C++.

5voto

Javier Points 33134

Je ne pense pas que vous ne peut pas à la véritable programmation fonctionnelle en C++, mais ce n'est certainement pas la façon la plus simple ou la plus naturelle de l'utiliser. En outre, il se peut que vous n'utilisiez que quelques idiomes de type fonctionnel et non l'ensemble de la mentalité (c'est-à-dire le "style fluide").

Je vous conseille d'apprendre un langage fonctionnel, peut-être en commençant par Scheme, puis en passant à Haskell. Ensuite, utilisez ce que vous avez appris lorsque vous programmez en C++. Vous n'utiliserez peut-être pas un style fonctionnel évident, mais vous pourrez en tirer les plus grands avantages (par exemple, l'utilisation de structures immuables).

0 votes

En tant qu'apprenant de haskell, j'aimerais savoir pourquoi vous suggérez d'abord le schéma.

0 votes

J'ai déjà vu du code Scheme. Il me semble que c'est du chinois-japonais. :|

0 votes

Ok. Je vais vérifier le langage FP. Merci pour la réponse !

1voto

rvirding Points 13019

Il existe un livre intitulé Fonctionnement C de Pieter Hartel et Henk Muller qui pourrait vous aider. S'il est encore disponible. Voici un lien vers des informations sur ce livre aquí . Je crois que ce n'était pas si mal.

0 votes

Selon la description, ce livre enseigne la programmation impérative aux personnes venant des langages fonctionnels. Pas comment faire de la programmation fonctionnelle en C (ce qui serait un peu plus pénible que de le faire en C++, j'imagine).

0 votes

En apparence, c'est le cas, mais rien ne vous empêche de l'utiliser dans le sens inverse. Il fonctionne très bien pour cela et vous donne quelques indications sur la façon de programmer le C dans un style fonctionnel.

0voto

daven11 Points 1430

C'est probablement un peu tard mais pour tous ceux qui cherchent - j'utilise lua comme une extension de programmation fonctionnelle à C++ et c'est génial. lua

1 votes

Est-ce vraiment une suggestion d'utiliser une autre langue ?

0 votes

Cette réponse devrait expliquer comment Lua est bien intégré dans C++ (plus que la simple invocation d'un sous-programme/fonction/méthode/rose-par-un-autre-nom), en particulier pour permettre l'utilisation de Lua pour la FP tout en utilisant C++ pour la non-fFP dans une sorte d'interaction synergique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X