Rename split-loop-with-lambda to slice-with-lambda

The refactoring is now published as Slice on sammancoaching.org:
https://sammancoaching.org/refactorings/slice.html

- git mv ideas/split-loop-with-lambda -> ideas/slice-with-lambda
- rename learning-hour file and update frontmatter name
- update paths in tools/rehearse scripts and report title
- update prose: 'Split Loop with Lambda' -> 'Slice with Lambda'
  in learning hour, exercise READMEs, storyboard, solution comments
- link the published Slice refactoring from the pattern draft
This commit is contained in:
Your Name
2026-09-29 15:47:30 +00:00
parent 125bb7ad01
commit 77ae05c28c
114 changed files with 21 additions and 20 deletions
@@ -1,4 +1,4 @@
# Exercise folder — Split Loop with Lambda (learning hour) # Exercise folder — Slice with Lambda (learning hour)
Contents: Contents:
@@ -1,4 +1,4 @@
# IceCreamForecasting — Split Loop with Lambda (exercise) # IceCreamForecasting — Slice with Lambda (exercise)
Pre-factored variant of [IceCreamForecasting-Refactoring-Kata](https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata): Pre-factored variant of [IceCreamForecasting-Refactoring-Kata](https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata):
the Q1/Q4 dead branch is stripped and the hardcoded dates are a constant now. the Q1/Q4 dead branch is stripped and the hardcoded dates are a constant now.
@@ -14,7 +14,7 @@ Get it under test:
1. First get any test running that calls `longRangeForecast()` — 1. First get any test running that calls `longRangeForecast()` —
it will fail or be flaky, because of the dependency on `Scorer`. it will fail or be flaky, because of the dependency on `Scorer`.
2. Then use the **Split Loop with Lambda** mechanics (6 steps, on the handout) 2. Then use the **Slice with Lambda** mechanics (6 steps, on the handout)
so that the weather collection becomes an extracted method that takes the so that the weather collection becomes an extracted method that takes the
weather-reading as a **lambda parameter**. weather-reading as a **lambda parameter**.
3. Stop when you have an extracted method that takes the lambda as a parameter, 3. Stop when you have an extracted method that takes the lambda as a parameter,
@@ -1,7 +1,7 @@
# Rehearsal of the exercise with coding agents — full summary # Rehearsal of the exercise with coding agents — full summary
**Date:** 2026-09-27 · **Harness:** `tools/rehearse/` · **Raw per-run artifacts:** [`rehearsal-runs/`](./) **Date:** 2026-09-27 · **Harness:** `tools/rehearse/` · **Raw per-run artifacts:** [`rehearsal-runs/`](./)
· **Exercise:** Split Loop with Lambda (IceCreamForecasting kata, `LongRangeForecasts`) · **Exercise:** Slice with Lambda (IceCreamForecasting kata, `LongRangeForecasts`)
Six scripted sub-agent runs did the refactoring under different tool rules and Six scripted sub-agent runs did the refactoring under different tool rules and
two models. Each run got a fresh workspace, a shared AGENTS.md (identical two models. Each run got a fresh workspace, a shared AGENTS.md (identical
@@ -7,7 +7,7 @@ import java.util.function.LongFunction;
/** /**
* Reference end state of the learning hour exercise (step 3 of the * Reference end state of the learning hour exercise (step 3 of the
* Split Loop with Lambda mechanics — stop here; step 4, moving the method * Slice with Lambda mechanics — stop here; step 4, moving the method
* to another class, is future work). * to another class, is future work).
* *
* Derived from https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata * Derived from https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata
@@ -1,4 +1,4 @@
# Exercise 3 — Buyers (Split Loop with Lambda, the pure rep) # Exercise 3 — Buyers (Slice with Lambda, the pure rep)
A third, minimal example in the same kata theme: the sellers exist A third, minimal example in the same kata theme: the sellers exist
(`DailyForecasts` — Steve, Julie, Francis), the buyers don't. This adds them: (`DailyForecasts` — Steve, Julie, Francis), the buyers don't. This adds them:
@@ -5,7 +5,7 @@ namespace IceCreamBuyers
{ {
/// <summary> /// <summary>
/// Reference end state of exercise 3 (extract lambda, slide, extract method /// Reference end state of exercise 3 (extract lambda, slide, extract method
/// with a function parameter — the pure rep of Split Loop with Lambda). /// with a function parameter — the pure rep of Slice with Lambda).
/// </summary> /// </summary>
public class Buyers public class Buyers
{ {
@@ -1,15 +1,15 @@
--- ---
theme: refactoring theme: refactoring
title: Split Loop with Lambda — when the variable you slide is a function title: Slice with Lambda — when the variable you slide is a function
name: split-loop-with-lambda name: slice-with-lambda
kata: IceCreamForecasting-Refactoring-Kata (pre-factored "prefactored-longrange" variant) kata: IceCreamForecasting-Refactoring-Kata (pre-factored "prefactored-longrange" variant)
difficulty: 4 difficulty: 4
author: Willem van den Ende author: Willem van den Ende
affiliation: QWAN affiliation: QWAN
tags: refactoring java split-loop lambda testability composed-method tags: refactoring java slice lambda testability composed-method
--- ---
# Split Loop with Lambda # Slice with Lambda
You know Split Loop: separate the loops that compute from the loops that You know Split Loop: separate the loops that compute from the loops that
collect, using *introduce variable* and *slide statement*. But sometimes the collect, using *introduce variable* and *slide statement*. But sometimes the
@@ -29,7 +29,7 @@ and end at a testable, pure seam.
## Learning Goals ## Learning Goals
* Given a loop whose body needs an outside dependency, perform the six * Given a loop whose body needs an outside dependency, perform the six
Split-Loop-with-Lambda mechanics (introduce lambda → slide → extract Slice mechanics (introduce lambda → slide → extract
method with function parameter) on unfamiliar code, without the handout method with function parameter) on unfamiliar code, without the handout
open. open.
* Recognize when plain Split Loop is not enough — the variable you need to * Recognize when plain Split Loop is not enough — the variable you need to
@@ -61,7 +61,8 @@ one concern loose even when Split Loop alone cannot.*
## Concept - The six mechanics ## Concept - The six mechanics
Walk the pattern (handout: `zeroth-draft-of-refactoring-pattern.md`): Walk the pattern — the handout is `zeroth-draft-of-refactoring-pattern.md`;
there is also a published description, [Slice](https://sammancoaching.org/refactorings/slice.html):
1. **Extract the dependency-using code into a lambda** — no tool does this; 1. **Extract the dependency-using code into a lambda** — no tool does this;
it is a small manual edit. it is a small manual edit.
@@ -1,6 +1,6 @@
# Example 3 — Buyers: extract lambda in its purest form # Example 3 — Buyers: extract lambda in its purest form
Third rep of the Split Loop with Lambda mechanics, in C#. Example 1 Third rep of the Slice with Lambda mechanics, in C#. Example 1
(`longRangeForecast`) had a drift trap and a dead call; the demo (`longRangeForecast`) had a drift trap and a dead call; the demo
(`printSalesForecasts`) had three dependencies and grew into a role interface. (`printSalesForecasts`) had three dependencies and grew into a role interface.
This one has **one loop and one lambda-able expression, and nothing else** — This one has **one loop and one lambda-able expression, and nothing else** —
@@ -1,6 +1,6 @@
# Demo script — printSalesForecasts # Demo script — printSalesForecasts
This is what I demo in the Split Loop with Lambda learning hour. I demo on This is what I demo in the Slice with Lambda learning hour. I demo on
`DailyForecasts.printSalesForecasts()` — the messier sibling of the method the pairs `DailyForecasts.printSalesForecasts()` — the messier sibling of the method the pairs
will refactor in the exercise. Same pattern, but this loop has three unwanted will refactor in the exercise. Same pattern, but this loop has three unwanted
dependencies: `Scorer` (with a static field for extra credit), `System.out`, and the dependencies: `Scorer` (with a static field for extra credit), `System.out`, and the
@@ -5,7 +5,7 @@ step, each step followed by the exact code (full before/after, highlights as `
comments). Written to be sliced into slides later; until then it works as a handout. comments). Written to be sliced into slides later; until then it works as a handout.
Sources: `../zeroth-draft-of-refactoring-pattern.md` (the mechanics), Sources: `../zeroth-draft-of-refactoring-pattern.md` (the mechanics),
`../split-loop-with-lambda-learning-hour.md` (where we stop: after step 3 + the test), `../slice-with-lambda-learning-hour.md` (where we stop: after step 3 + the test),
`../exercise/rehearsal-findings.md` (the drift anti-pattern and the "both calls!" `../exercise/rehearsal-findings.md` (the drift anti-pattern and the "both calls!"
caution). Java only. Pristine start: `../exercise/java`, end state: `../exercise/solution`. caution). Java only. Pristine start: `../exercise/java`, end state: `../exercise/solution`.
C# demo examples live at `../exercise/csharp/` (MetaphorFree.cs, WeatherStation.cs, IceCreamShop.cs); the slides are at `~/qwan/slides-rjs/decks/refactoring/slice-with-lambda/slides.md`, served at http://localhost:9001/#/refactoring/slice-with-lambda. C# demo examples live at `../exercise/csharp/` (MetaphorFree.cs, WeatherStation.cs, IceCreamShop.cs); the slides are at `~/qwan/slides-rjs/decks/refactoring/slice-with-lambda/slides.md`, served at http://localhost:9001/#/refactoring/slice-with-lambda.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More