Back to flin
flin

Reduce, Map, Filter : fonctions d'ordre supérieur

Comment FLIN implémente les fonctions d'ordre supérieur -- map, filter, reduce, flat_map, zip_with et plus -- comme méthodes intégrées sur les listes avec syntaxe lambda concise et inférence de types complète.

Juste A. Gnimavo (Thales) & Claude | March 26, 2026 4 min flin
EN/ FR/ ES
flinfunctionalmapfilterreducehof

La programmation fonctionnelle n'est pas un paradigme. C'est une boîte à outils. La capacité de passer des fonctions comme arguments, de les retourner depuis d'autres fonctions et de les composer en pipelines n'est pas un exercice académique -- c'est la manière la plus pratique de transformer des données dans une application web.

La Session 177 a apporté les fonctions d'ordre supérieur à FLIN. Pas comme un import de bibliothèque. Pas comme une extension fonctionnelle boulonnée. Comme des méthodes intégrées sur chaque liste, avec une syntaxe lambda concise et une inférence de types complète. Le résultat : des pipelines de transformation de données qui se lisent comme de l'anglais, s'exécutent comme du code natif et attrapent les erreurs de type à la compilation.

Les trois fondamentales : Map, Where, Reduce

map : transformer chaque élément

flinnumbers = [1, 2, 3, 4, 5]
doubled = numbers.map(n => n * 2)
// [2, 4, 6, 8, 10]

users = User.all
names = users.map(u => u.name)
// ["Juste", "Thales", "Claude"]

where : garder les éléments correspondants

FLIN utilise where au lieu de filter pour une raison délibérée : cela se lit plus naturellement en anglais. "Users where active" est une pensée complète. "Users filter active" ne l'est pas.

flinevens = numbers.where(n => n.is_even)
// [2, 4, 6, 8, 10]

adults = users.where(u => u.age >= 18)
active_admins = users.where(u => u.is_active and u.role == "admin")

reduce : réduire une liste à une seule valeur

flinnumbers = [1, 2, 3, 4, 5]
total = numbers.reduce(0, (acc, n) => acc + n)
// 15

// Construire un map de fréquences
frequency = words.reduce({}, (acc, word) => {
    count = acc.get(word, 0)
    acc.set(word, count + 1)
})

Au-delà des trois fondamentales

flin// flat_map : mapper et aplatir
users_orders = users.flat_map(u => u.orders)

// zip et zip_with : combiner deux listes
sentences = names.zip_with(ages, (name, age) => "{name} is {age}")

// partition : séparer en deux groupes
result = numbers.partition(n => n.is_even)
evens = result[0]   // [2, 4, 6, 8, 10]
odds = result[1]    // [1, 3, 5, 7, 9]

// group_by : catégoriser les éléments
by_role = users.group_by(u => u.role)

// chunk : découper en groupes de taille fixe
pages = items.chunk(3)
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

Chaînage de méthodes : le pattern pipeline

La vraie puissance des fonctions d'ordre supérieur émerge quand vous les chaînez :

flin// Trouver les 5 articles les plus chers achetés par des utilisateurs actifs ce mois-ci
result = orders
    .where(o => o.user.is_active)
    .where(o => o.created_at.is_after(now.start_of_month))
    .flat_map(o => o.items)
    .sort_by(item => item.price)
    .reverse
    .take(5)
    .map(item => {
        name: item.name,
        price: item.price.format(2)
    })

Cette chaîne se lit de haut en bas comme un flux de données. Chaque étape produit une nouvelle liste. Aucune étape ne modifie les données originales. Le pipeline entier est immuable, prévisible et facile à déboguer.

Les douze fonctions d'ordre supérieur

FonctionSignatureBut
map(T -> U) -> [U]Transformer chaque élément
where(T -> bool) -> [T]Garder les correspondants
reject(T -> bool) -> [T]Supprimer les correspondants
reduce(U, (U,T) -> U) -> URéduire à une seule valeur
flat_map(T -> [U]) -> [U]Mapper et aplatir
find(T -> bool) -> T?Première correspondance ou none
find_index(T -> bool) -> int?Index de la première correspondance
any(T -> bool) -> boolTrue si au moins un correspond
all(T -> bool) -> boolTrue si tous correspondent
none_match(T -> bool) -> boolTrue si aucun ne correspond
partition(T -> bool) -> [[T],[T]]Séparer en deux groupes
group_by(T -> K) -> map[K,[T]]Grouper par clé

Douze fonctions qui remplacent les boucles impératives dans 90 % du code de transformation de données. Chacune est une méthode intégrée sur chaque liste. Pas d'imports. Pas de bibliothèque de programmation fonctionnelle. Juste .map, .where et .reduce.


Ceci est la partie 78 de la série "How We Built FLIN", documentant comment un CEO à Abidjan et un CTO IA ont construit des fonctions d'ordre supérieur dans un langage de programmation avec inférence de types complète.

Navigation de la série : - [77] Introspection and Reflection at Runtime - [78] Reduce, Map, Filter: Higher-Order Functions (vous êtes ici) - [79] Validation and Sanitization Functions - [80] Error Tracking and Performance Monitoring

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude thales

Treize agents, quarante-trois minutes : la première session Workflow de Claude Fable 5, et ce qu'un script d'orchestration déterministe change aux builds multi-agents

Un prompt, treize agents, quarante-trois minutes : la première session de production avec Claude Fable 5 et l'outil Workflow de Claude Code a livré un site web de production complet de sept pages plus un endpoint backend de capture de leads, en un seul commit. Le carnet de bord : le script d'orchestration déterministe, le patron d'injection de contrat entre les phases, l'économie par agent du fan-out parallèle, et le suspense de la limite de session que le journal de reprise a transformé en non-événement.

23 min Jun 12, 2026
claude-fable-5claude-codeworkflow-toolmulti-agent +10
Thales & Claude casp

La porte a détecté sa propre dérive : une journée dans CASP avec Claude Fable 5

Nous avons confié au modèle Claude le plus autonome à ce jour les clés de CASP — le CLI open source qui garde les agents de code IA honnêtes face à git — avec l'autorité de rejeter notre propre roadmap. Il a rejeté cinq choses, trouvé deux vrais bugs dans le validateur en le dogfoodant, les a corrigés sous une porte à deux auditeurs, et a laissé casp check entièrement vert sur son propre dépôt pour la première fois. CASP 0.3.0 en est le résultat.

16 min Jun 10, 2026
caspzerosuiteworkflowai-cto +9
Thales & Claude zerosuite

La transplantation du CASP : comment la discipline des six fichiers est passée de Conductor à un ERP transport anti-fraude, ce que la compétence /next ajoute quand l'opérateur tape juste « next », et pourquoi le coût d'une dérive du CASP grimpe quand le projet, c'est l'argent des autres

La discipline du CASP qui a piloté trente-cinq sessions de Conductor est agnostique au produit. Le carnet de bord de sa transplantation sur KASSIA, un ERP transport anti-fraude pour un exploitant de flotte en Côte d'Ivoire : ce qui a migré, ce qui n'a pas migré (le validateur sur mesure — et ce que son absence coûte), ce que la compétence /next ajoute quand l'opérateur tape un seul mot, et là où le CASP s'arrête — le bug de déploiement qu'il ne pouvait pas voir parce qu'il enregistre l'intention, pas la réalité de l'infrastructure.

23 min Jun 8, 2026
kassiaerp-kassia-transport-logistiquezerosuiteCASP +15