Une chaîne stricte alloue à chaque maillon — lazy diffère tout.A strict chain allocates at every link — lazy defers it all.
Le raffinement, dernier étage du volume. Une chaîne map.select.first est lisible, mais chaque maillon construit un tableau intermédiaire complet avant de passer le relais : map alloue tout, puis select alloue tout, et first n'en retient que cinq. Sur un million d'éléments, ce sont deux tableaux intermédiaires — un million de cases, puis encore plus de trois cent mille — pour cinq résultats ; sur une séquence infinie, c'est impossible — la première étape ne finit jamais. lazy renverse l'ordre : rien n'est calculé tant qu'on ne demande pas, et la donnée traverse alors la chaîne un élément à la fois, jusqu'à ce que first(5) dise stop. Le calcul suit la demande, pas la source.The refinement, the volume's top floor. A map.select.first chain is readable, but each link builds a full intermediate array before handing over: map allocates everything, then select allocates everything, and first keeps only five. On a million elements, that's two intermediate arrays — a million slots, then over three hundred thousand more — for five results; on an infinite sequence, it's impossible — the first step never finishes. lazy reverses the order: nothing is computed until you ask, and the data then crosses the chain one element at a time, until first(5) says stop. The computation follows the demand, not the source.
# strict : chaque maillon construit un Array COMPLET, puis le suivant (1..1_000_000) .map { |x| x * 2 } # alloue un Array d'un million… .select { |x| x % 3 == 0 } # … puis un autre Array… .first(5) # … pour n'en garder que CINQ # lazy : rien ne se calcule avant first(5), élément par élément (1..Float::INFINITY).lazy # une séquence INFINIE, sans broncher .map { |x| x * 2 } .select { |x| x % 3 == 0 } .first(5) # => [6, 12, 18, 24, 30] 5 éléments calculés
Strict avance par étage : il finit chaque méthode sur toute la collection avant la suivante. Lazy avance par élément : un seul descend toute la chaîne, puis le prochain — jusqu'à ce qu'on en ait assez.Strict advances by stage: it finishes each method over the whole collection before the next. Lazy advances by element: one goes down the whole chain, then the next — until you've had enough.
« Cette chaîne crée-t-elle des tableaux intermédiaires que lazy rendrait inutiles ? » Si la source est énorme ou infinie, et qu'on n'en consomme qu'une partie (un first, un find, un take), lazy évite des allocations massives. Sinon — c'est le piège — il coûte plus qu'il ne rapporte."Does this chain create intermediate arrays that lazy would make needless?" If the source is huge or infinite, and you consume only part of it (a first, a find, a take), lazy avoids massive allocations. Otherwise — that's the trap — it costs more than it saves.
On a fondé (un each débloque tout), composé (chaîner les transformations) ; voici le raffinement. lazy ne change pas ce que la chaîne calcule — seulement quand et combien. C'est la première fois du volume qu'on optimise, et fidèle à l'esprit de la série, on le fait pour une raison nommable : éviter des intermédiaires qui comptent, ou rendre l'infini calculable. Jamais par réflexe.We founded (one each unlocks all), composed (chaining transformations); here's the refinement. lazy doesn't change what the chain computes — only when and how much. It's the volume's first optimization, and true to the series' spirit, we do it for a nameable reason: avoiding intermediates that matter, or making the infinite computable. Never by reflex.