Pour le dire simplement, les restrictions signifient qu'il y a moins de façons correctes de rassembler les choses, et les fonctions de première classe facilitent la factorisation de choses comme les structures de boucle. Prenez la boucle de cette réponse , par exemple:
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
iterator.remove();
}
}
Il se trouve que c'est le seul moyen impératif et sûr de Java pour supprimer un élément d'une collection pendant que vous l'itérez. Il existe de nombreuses façons qui semblent très proches, mais qui sont erronées. Les personnes qui ne connaissent pas cette méthode passent parfois par des moyens compliqués pour éviter le problème, comme une itération à travers une copie à la place.
Ce n'est pas très difficile de rendre ce générique, donc cela fonctionnera sur plus que des collections de Strings
, mais sans fonctions de première classe, vous ne pouvez pas remplacer le prédicat (la condition à l'intérieur du if
), donc ce code a tendance à être copié et collé et légèrement modifié.
Combinez des fonctions de première classe qui vous donnent la possibilité de passer le prédicat en tant que paramètre, avec la restriction de l'immuabilité qui le rend très ennuyeux si vous ne le faites pas, et vous obtenez de simples blocs de construction comme filter
, comme dans ce code Scala cela fait la même chose:
list filter (!_.isEmpty)
Pensez maintenant à ce que le système de type vérifie pour vous, au moment de la compilation dans le cas de Scala, mais ces vérifications sont également effectuées par les systèmes de type dynamiques la première fois que vous l'exécutez:
list
doit être une sorte de type qui prend en charge la filter
méthode, à savoir une collection.
- Les éléments de
list
doivent avoir une isEmpty
méthode qui renvoie un booléen.
- La sortie sera une collection (potentiellement) plus petite avec le même type d'éléments.
Une fois que ces choses ont été vérifiées, quelles sont les autres façons pour le programmeur de bousiller? J'ai oublié accidentellement !
, ce qui a provoqué une défaillance de cas de test extrêmement évidente. C'est à peu près la seule erreur disponible à faire, et je ne l'ai fait que parce que je traduisais directement à partir du code qui a testé la condition inverse.
Ce modèle se répète encore et encore. Les fonctions de première classe vous permettent de refaçonner les choses en petits utilitaires réutilisables avec une sémantique précise, des restrictions comme l'immuabilité vous donnent l'impulsion pour le faire, et la vérification du type des paramètres de ces utilitaires laisse peu de place pour les visser.
Bien sûr, tout cela dépend du programmeur sachant que la fonction de simplification comme filter
existe déjà, et capable de la trouver, ou de reconnaître l'avantage d'en créer une vous-même. Essayez de l'implémenter vous-même partout en utilisant uniquement la récursivité de la queue, et vous êtes de retour dans le même bateau de complexité que la version impérative, pire encore. Ce n'est pas parce que vous pouvez l' écrire très simplement que la version simple est évidente.