Pourquoi la programmation impérative est-elle préférée à la programmation fonctionnelle? [fermé]

13

Contexte: Je suis un partisan de la programmation fonctionnelle qui travaille dans une boutique VB.NET où le modèle mental dominant est la programmation impérative. Étant la base de notre système, c'est WinForms Je peux comprendre que nous n'allons pas nous éloigner complètement de la programmation impérative, mais j'essaie quand même d'utiliser FP (principalement via Linq) autant que possible parce que je crois en ses mérites.

Arguments et contre-arguments contre FP

  1. On pourrait remarquer que la fluidité de Linq est moins efficace que son homologue impératif en ce que ce style traite une séquence jusqu'à une autre séquence et la répète. Généralement, cela va prendre quelques passes de plus que l'approche impérative qui peut être mieux optimisée pour éviter les répétitions sur une séquence. Pour cette raison, le responsable ne comprenait pas pourquoi je choisirais une approche fonctionnelle clairement «moins efficace».

    • Contre-argument : J'ai soutenu que bien qu'il soit parfois moins efficace en termes de cycles CPU, je pensais qu'il était plus intelligible humainement et plus facile à suivre puisque chaque ligne ne faisait qu'une seule chose lors de son passage sur la séquence. Pour moi, c'est comme avoir une chaîne de montage où chaque personne dans sa station n'a qu'un seul travail à faire. Je pense que le compromis négligeable de l'efficacité est compensé par un code dont les préoccupations sont soigneusement séparées.
  2. Le prochain argument contre FP que j'entends dans ma boutique est qu'il est plus difficile à déboguer - ce qui est vrai. Il n'est pas facile de passer par-dessus le code Linq. Et je dois parfois démêler une chaîne de méthodes afin de mieux suivre et disséquer les problèmes que je ne peux pas détecter immédiatement.

    • _Contre-argument: Pour la plupart, bien que je n'ai pas de problème avec cela parce que je pense que le style fonctionnel est plus déclaratif dans la façon dont il se lit et lorsqu'une erreur est lancée dans une chaîne fonctionnelle, je peux généralement repérer le problème immédiatement.

Ma question

J'ai essayé de promouvoir le style fonctionnel dans notre boutique et je n'ai pas l'impression de faire des progrès. J'ai fait les deux styles de programmation et j'ai récemment essayé Haskell. Malgré des années d'expérience impérative, maintenant que j'utilise régulièrement la PF en JavaScript, cela a grandi sur moi. Cela fait sonner une note de justesse dans mon cœur quand je le compare à ce que j'aurais pu faire si je m'en tenais à un style impératif. J'ai recyclé mon cerveau vers la pensée fonctionnelle, vers la composition fonctionnelle.

Ce que je ne peux pas comprendre, c'est à quel point il a été difficile de convaincre les autres des mérites de FP.

Par exemple, les développeurs de ma boutique utilisent Linq, mais je pense qu'ils l'utilisent généralement dans le contexte du traitement des données de domaine. Je l'utilise dans un sens plus général et le préfère chaque fois que je traite des séquences / listes ou des structures de données persistantes. Je n'ai pas réussi à convaincre mes coéquipiers d'étendre leur utilisation de Linq.

Ce que j'essaie de comprendre, c'est ce qui fait qu'un développeur n'aime pas FP.

J'aimerais voir une réponse de quelqu'un qui a beaucoup d'expérience avec la PF mais qui a décidé en faveur du style impératif. Qu'est-ce qui a motivé la décision de rester avec l'impératif au lieu d'utiliser le fonctionnel?


Voici un exemple supplémentaire mettant en évidence les différences entre la programmation impérative et fonctionnelle.

J'ai écrit la SelectedRowsméthode de notre grille en Linq comme telle:

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Return Me.ugrBase.Selected.Rows.
            OfType(Of Infragistics.Win.UltraWinGrid.UltraGridRow)().
            Select(Function(ugr) ugr.ListObject).
            OfType(Of DataRowView)().
            Select(Function(drv) drv.Row).
            ToArray
    End Get

Cependant, ce style de code rend certains de nos développeurs mal à l'aise et notre responsable l'a donc réécrit pour le plus familier:

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Dim plstRows As New List(Of DataRow)
        For Each bugrLoop As Infragistics.Win.UltraWinGrid.UltraGridRow In Me.ugrBase.Selected.Rows
            If bugrLoop.ListObject IsNot Nothing Then
                plstRows.Add(CType(bugrLoop.ListObject, DataRowView).Row)
            End If
        Next
        Return plstRows.ToArray()
    End Get
Mario T. Lanza
la source
J'aime la programmation fonctionnelle, mais d'un coup d'œil au code, je préférerais l' approche «impérative» (j'appelle déclarative ). Il m'est beaucoup plus facile de lire - étant donné que cela pourrait être mon expérience et être un produit de mon environnement. Cela dit, à partir de 5 secondes rapides, je peux voir les étapes de préparation et ce qui est retourné. Je peux voir qu'il y a une boucle et je sais que des ajustements à ces données se produiraient probablement. Je n'ai pas besoin de retrouver les définitions des fonctions; c'est là, c'est simple. Mais FP est plus propre et une fois passé la courbe d'apprentissage, il serait probablement aussi rapide de coder.
vol7ron
C'est la courbe d'apprentissage qui est en cause, en particulier lorsque l'on travaille avec des gens qui ne connaissent «juste assez» que de nombreuses langues. Si je me spécialise dans une langue particulière, je suis sûr que la FP serait une meilleure première tentative. Ensuite, s'il y avait des inefficacités (performances des tests unitaires), on pourrait être plus explicite dans leurs implémentations.
vol7ron

Réponses:

11

La programmation fonctionnelle est tout simplement trop compliquée pour les programmeurs inexpérimentés . L'une des illustrations est celle-ci , où les élèves ont déclaré que le désordre 30-LOC était plus facile et plus intuitif à comprendre par rapport à l'analogue FP à quatre lignes.

(Il s'agit de la version originale de l'exemple FP, car la réponse dans le lien a été modifiée plus récemment pour la rendre légèrement plus facile à lire.)

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

La programmation fonctionnelle nécessite une façon différente de penser la façon dont nous codons et la façon dont ce code est exécuté. C'est rarement la façon dont les étudiants sont informés au collège, et une fois les mauvaises habitudes prises, il est difficile de les changer.

La programmation fonctionnelle a également ses propres caractéristiques spécifiques qui peuvent paraître risquées aux mains des débutants . L'évaluation paresseuse en fait partie, et il peut s'écouler des mois avant que l'on commence à comprendre pourquoi l'évaluation paresseuse est une excellente fonctionnalité et non une gêne.

C'est aussi pourquoi tant de débutants commencent à programmer avec des langages tels que PHP et non des langages comme Haskell.

Arseni Mourzenko
la source
8
J'ai eu l'expérience inverse dans une université où Scheme est utilisé pour le cours d'introduction. Lorsque les étudiants ont dû apprendre Java ou C #, la plupart se sont plaints que le programme était plus lisible
Daniel Gratzer
2
Cela prouve mon point. Les étudiants qui ont appris la programmation impérative et la POO pendant des années le trouveraient plus lisible. Les gens qui ont commencé avec la FP la trouveront plus lisible que la programmation impérative. Il serait intéressant de savoir ce qui se passe avec les étudiants qui connaissent aussi bien les paradigmes PF et non PF.
Arseni Mourzenko
1
Le principal problème est que les langages fonctionnels sont trop abstraits. Quand un Haskeller vous dit que vous avez manqué de mémoire parce que vous avez accumulé des thunks non évalués, il y a définitivement quelque chose qui ne va pas. De nombreux algorithmes ne sont pas efficaces lorsqu'ils sont écrits dans un style fonctionnel. Vous ne pouvez pas implémenter un implément Quicksort rapide. dans Haskell idiomatique. Chaque algorithme sur place finit par faire des tableaux d'E / S afin d'obtenir de bonnes performances. Les langages fonctionnels sont pour les puristes de la langue, les langages impératifs sont pour les gens qui veulent faire réfléchir à temps.
Kr0e
3
@ Kr0e: l'argument «trop d'abstraits» contre une langue ou un paradigme me semble toujours étrange. Le même argument a été utilisé contre toutes (ou la plupart) des langues; nous espérons que la plupart des logiciels ne sont pas écrits dans Assembler aujourd'hui.
Arseni Mourzenko
6
"Les langages fonctionnels sont pour les puristes de la langue, les langages impératifs sont pour les personnes qui veulent faire réfléchir à temps.": Selon mon expérience, ce n'est pas vrai. Je peux faire avancer les choses plus rapidement en utilisant des langages fonctionnels. Le style impératif est beaucoup plus verbeux et moins déclaratif et quand je dois utiliser un langage impératif, j'ai certainement besoin de plus d'itérations avant de bien faire les choses.
Giorgio