Introduction à la programmation fonctionnelle en Swift
Swift est un langage de programmation multi-paradigme développé par Apple pour créer des applications pour iOS, macOS, watchOS et tvOS. En plus des approches orientée objet et orientée protocole, Swift supporte activement la programmation fonctionnelle. Ce style est basé sur l'utilisation de fonctions pures, l'immutabilité des données et le refus des effets secondaires.
La programmation fonctionnelle rend le code plus prévisible, testable et parallèlement sûr. Dans cet article, nous allons détailler les concepts clés de l'approche fonctionnelle en Swift : l'immutabilité, les fonctions d'ordre supérieur, les closures et les chaînes de méthodes. Vous verrez comment avec map, filter et reduce écrire un code concis et expressif.
Fondamentaux de l'approche fonctionnelle en Swift
Immutabilité
En programmation fonctionnelle, les données ne sont pas modifiées après leur création. Au lieu de modifier un objet existant, on en crée un nouveau. Swift encourage cette approche avec le mot-clé let pour déclarer des constantes.
// Valeur immuablelet numbers = [1, 2, 3, 4, 5]// numbers.append(6) // Erreur de compilation — numbers est immuable
// Création d'un nouveau tableaulet newNumbers = numbers + [6]print(newNumbers) // [1, 2, 3, 4, 5, 6]L'utilisation de let au lieu de var aide à éviter les modifications accidentelles d'état et simplifie le débogage.
Les fonctions comme objets de première classe
En Swift, les fonctions sont des objets de première classe. On peut les assigner à des variables, les passer comme arguments et les retourner depuis d'autres fonctions.
// Fonction assignée à une variablelet multiply: (Int, Int) -> Int = { $0 * $1 }print(multiply(3, 4)) // 12
// Fonction qui prend une autre fonction en paramètrefunc applyOperation(_ a: Int, _ b: Int, operation: (Int, Int) -> Int) -> Int { return operation(a, b)}
let result = applyOperation(10, 5, operation: multiply)print(result) // 50Les closures en Swift
Les closures sont des blocs de fonctionnalités autonomes qui peuvent capturer et conserver des références aux variables du contexte environnant. En Swift, les closures sont largement utilisées pour les callbacks et les transformations fonctionnelles.
// Closure simplelet greeting = { (name: String) -> String in return "Bonjour, \\(name)!"}print(greeting("Monde")) // Bonjour, Monde!
// Forme raccourcie avec paramètreslet numbers = [3, 1, 4, 1, 5, 9]let sorted = numbers.sorted { $0 < $1 }print(sorted) // [1, 1, 3, 4, 5, 9]Les closures rendent le code compact et expressif, surtout lorsqu'on travaille avec des collections.
Fonctions d'ordre supérieur : map, filter, reduce
Ce sont les trois piliers de la programmation fonctionnelle en Swift. Elles permettent de traiter des tableaux, dictionnaires et autres collections sans boucles explicites.
map — transformer chaque élément
La méthode map applique une closure à chaque élément d'une collection et retourne un nouveau tableau avec les résultats.
let prices = [100, 200, 300, 400]let discounted = prices.map { $0 * 0.9 }print(discounted) // [90.0, 180.0, 270.0, 360.0]
// Travail avec des chaîneslet names = ["Anna", "Boris", "Victor"]let uppercased = names.map { $0.uppercased() }print(uppercased) // ["ANNA", "BORIS", "VICTOR"]filter — sélectionner selon une condition
filter retourne un nouveau tableau contenant uniquement les éléments qui satisfont une condition donnée.
let scores = [45, 78, 92, 33, 88, 61]let passingScores = scores.filter { $0 >= 60 }print(passingScores) // [78, 92, 88, 61]
// Filtrage de chaîneslet words = ["Swift", "iOS", "macOS", "fonction"]let shortWords = words.filter { $0.count <= 4 }print(shortWords) // ["iOS", "macOS"]