Files
learning-hour-maker/ideas/slice-with-lambda/exercise3/README.md
T
Your Name 77ae05c28c 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
2026-09-29 15:47:30 +00:00

43 lines
2.1 KiB
Markdown

# Exercise 3 — Buyers (Slice with Lambda, the pure rep)
A third, minimal example in the same kata theme: the sellers exist
(`DailyForecasts` — Steve, Julie, Francis), the buyers don't. This adds them:
`Buyers` computes a buyer's shopping-list total, and `PriceList` stands for an
external pricing service (it adds random surge pricing, so the test is flaky).
Written in **C#** (MSTest, .NET 10; verified with `dotnet test` on SDK
10.0.4xx — pristine test is flaky by design, solution is deterministic).
Run with `dotnet test test/BuyersTests.csproj`.
Contents:
- `csharp/` — pristine exercise repo: one loop, **one** lambda-able expression
(`priceList.PriceFor(flavour)`), nothing else. No printing, no conditionals,
no void calls.
- `solution/` — end state: extracted static method taking
`Func<IceCream, int> priceFor`, a no-arg overload passing the method group,
and a deterministic test with a pure lambda (`_ => 2`).
`IceCream.cs` is copied from
[IceCreamForecasting-Refactoring-Kata](https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata)
(same license as the kata applies).
## Where this sits in the sequence
| example | lambda | teaches |
|---|---|---|
| 1. `longRangeForecast` weather loop (Java) | `LongFunction<Boolean>` | the pattern + the drift trap |
| 3. `Buyers` shopping list (C#, this one) | `Func<IceCream, int>` | the move in its purest form: one expression, nothing else |
| demo/next: `printSalesForecasts` → `SalesScorer`, `PriceList` → `Pricing` | role interface | when one function isn't enough (two side-effectful methods to stub) |
Next-time arc: marketing adds surge discounts, `PriceList` grows
`DiscountFor(...)` — two methods to stub → extract a role interface
(`IPricing`) instead of two lambdas. See the demo script's closing note.
## Verified
Built and run with `dotnet test` (SDK 10.0.4xx): solution green deterministically,
pristine test flaky (failed 2 of 3 runs, passed 1 — both surges rolled 0).
MSTest bumped to 3.6.4 (kata ships 2.1.1, whose transitive Newtonsoft.Json trips
a NU1903 vulnerability warning).