Why is my implementation of Iterable not lazy

I see what you did there. But I had to take another look anyway.

The problem is indeed what map builds. In 2.12 map is strict so you’d have to override it with a lazy implementation and provide a sensible CanBuildFrom instance, too. In 2.13 map supports lazy building but the default Iterable, as @som-snytt points out, is List, so it’s not lazy. It works (in 2.13.0-M4) if you override the iterableFactory to build a lazy collection:

val counter3 = new Iterable[Int] {
  override def iterator: Iterator[Int] = ...
  override def iterableFactory = Stream
}