42 votes

Quels sont les problèmes les mieux / pires traités par la programmation fonctionnelle?

J'ai souvent entendu que la programmation fonctionnelle résout beaucoup de problèmes qui sont difficiles dans la procédure ou de la programmation impérative. Mais j'ai aussi entendu dire que ce n'est pas idéal à certains autres problèmes que la programmation procédurale est tout naturellement grand, à l'.

Avant de me casser mon livre sur Haskell et de plonger dans la programmation fonctionnelle, j'aimerais au moins une idée de base de ce que je peux vraiment utiliser pour (en dehors des exemples dans le livre). Alors, quels sont ces choses que la programmation fonctionnelle excelle? Quels sont les problèmes qu'il n'est pas bien adapté pour?

Mise à jour

J'ai de bonnes réponses à ce sujet jusqu'à présent. Je ne peux pas attendre pour commencer à apprendre Haskell maintenant, je dois juste attendre jusqu'à ce que je maitrise le C :)

Raisons pour lesquelles la programmation fonctionnelle est grande:

  • Très concis, il peut exprimer des idées complexes en bref, unobfuscated consolidés.
  • Est plus facile à vérifier que les langages impératifs, -- où la sécurité est essentielle.
  • La pureté des fonctions et de l'immuabilité de données, la programmation simultanée de plus en plus plausible.
  • Bien adapté pour le script et l'écriture de compilateurs (j'apprécierais de savoir pourquoi si).
  • Mathématiques liés à des problèmes sont résolus simplement et magnifiquement.

Les zones où la programmation fonctionnelle, les luttes:

  • Discutable: les applications web (même si je suppose que cela dépendra de l'application).
  • Les applications de bureau (bien que cela dépend de la langue sans doute, F# serait bon à ce jeu ne serait-il pas?).
  • Quand la performance est essentielle, comme les moteurs de jeu.
  • En ce qui concerne beaucoup de programme de l'état.

13voto

Alex Brown Points 15776

Programmation fonctionnelle excelle dans la concision, en raison de l'existence de fonctions de niveau supérieur (carte, lfold, grep) et l'inférence de type.

Il est aussi excellent à la programmation générique, pour les mêmes raisons, et que de nouvelles augmentations de la capacité à exprimer des idées complexes, dans un communiqué, sans dissimulation.

J'apprécie ces propriétés, car ils rendent la programmation interactive plausible. (par exemple, R, SML).

Je soupçonne que la programmation fonctionnelle peut aussi être vérifiée plus facilement que d'autres approches de programmation, ce qui est avantageux dans la sécurité des systèmes critiques (centrales Nucléaires et des Dispositifs Médicaux).

11voto

Hao Wooi Lim Points 1599

Je dirais que la programmation fonctionnelle convient à la résolution de problèmes, par exemple aux problèmes d'intelligence artificielle, de problèmes de maths (c'est beaucoup trop facile), de moteur de jeu mais pas très bien adaptée au développement de commandes personnalisées ou à une interface graphique nécessitant une interface graphique sophistiquée. Je trouve intuitif de penser de la manière suivante (même s’il est peut-être trop généralisant):

             Back-end   Front-end
Low-level   C          C++
High-level  FP         VB, C#
 

6voto

Juliet Points 40758

Il peut ne pas être directement liée à la programmation fonctionnelle, mais rien ne vaut les syndicats dans la conception et la mise en œuvre de structures de données. Nous allons comparer deux équivalent des morceaux de code:

F#:

type 'a pile = Cons of 'a * pile | Néant
let rec to_seq = fonction
 | Nil -> Seq.vide;
 | Cons(hd, tl) -> seq { rendement hd; le rendement! to_seq tl }
let rec ajouter x y =
 match x avec
 | Nil -> y
 | Cons(hd, tl) -> Cons(hd, ajouter tl y)
soit x = Cons(1, Cons(2, Cons(3, Cons(4, Nil))))
posons y = Cons(5, Cons(6, Cons(7, Cons(8, Nil))))
soit z = x y ajouter
to_seq z |> Seq.iter (fun x -> printfn "%i" x)

Java:

interface IStack<T> extends Iterable<T>
{
    IStack<T> Push(T value);
    IStack<T> Pop();
    T Peek();
    boolean IsEmpty();
}
final class EmptyStack<T> implements IStack<T>
{
    public boolean IsEmpty() { return true; }
    public IStack<T> Push(T value) { return Stack.cons(value, this); }
    public IStack<T> Pop() { throw new Error("Empty Stack"); }
    public T Peek() { throw new Error("Empty Stack"); }
    public java.util.Iterator<T> iterator()
    {
        return new java.util.Iterator<T>()
        {
            public boolean hasNext() { return false; }
            public T next() { return null; }
            public void remove() { }
        };
    }
}
final class Stack<T> implements IStack<T>
{
    public static <T> IStack<T> cons(T hd, IStack<T> tl) { return new Stack<T>(hd, tl); }
    public static <T> IStack<T> append(IStack<T> x, IStack<T> y)
    {
        return x.IsEmpty() ? y : new Stack(x.Peek(), append(x.Pop(), y));
    }
    private final T hd;
    private final IStack<T> tl;
    private Stack(T hd, IStack<T> tl)
    {
        this.hd = hd;
        this.tl = tl;
    }
    public IStack<T> Push(T value) { return new <T> Stack(value, this); }
    public IStack<T> Pop() { return this.tl; }
    public T Peek() { return this.hd; }
    public boolean IsEmpty() { return false; }
    public java.util.Iterator<T> iterator()
    {
        final IStack<T> outer = this;
        return new java.util.Iterator<T>()
        {
            private IStack<T> current = outer;
            public boolean hasNext() { return !current.IsEmpty(); }
            public T next()
            {
                T hd = current.Peek();
                current = current.Pop();
                return hd;
            }
            public void remove() { }
        };
    }
}
public class Main
{
    public static void main(String[] args)
    {
        IStack<Integer> x = Stack.cons(1, Stack.cons(2, Stack.cons(3, Stack.cons(4, new EmptyStack()))));
        IStack<Integer> y = Stack.cons(5, Stack.cons(6, Stack.cons(7, Stack.cons(8, new EmptyStack()))));
        IStack<Integer> z = Stack.append(x, y);

        for (Integer num : z)
        {
            System.out.printf("%s ", num);
        }
    }
}

6voto

Steve Wortham Points 11563

Programmation fonctionnelle serait bon pour la programmation parallèle. Le fait que vous n'êtes pas en s'appuyant sur les changements d'état avec la programmation fonctionnelle qui signifie que les différents processeurs/cœurs ne seront pas sur l'autre. Donc les types d'algorithmes qui prennent bien le parallélisme comme la compression, des effets graphiques, et d'autres plus complexes tâches mathématiques pourrait aussi être de bons candidats pour la programmation fonctionnelle. Et le fait que le multi-core CPU et les GPU ne sont plus en plus en popularité signifie également que la demande pour ce type de chose vont se développer.

4voto

boxofrats Points 692

Certains problèmes me semblent liés à la programmation fonctionnelle:

  • concurrence
  • compilateurs
  • script

Problèmes que je trouve personnellement pas très bien adaptés:

  • applications Web (mais ce n'est probablement que moi, Hacker News, par exemple, est implémenté dans LISP)
  • applications de bureau
  • moteurs de jeu
  • les choses où vous passez beaucoup d'état

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