Good points, but as far as I can tell, there's nothing preventing you from spawning a bunch of Loom-thread backed `CompletableFuture`s and waiting on them.
True, but Loom won't really help you there since that already CompletableFuture.runAsync already uses a pooling scheduler. Same for cats-effect and zio, for that matter.
(And that's aside from CompletableFuture having its own separate problems, like the obtrude methods)
A bounded pooling scheduler. (The ForkJoinPool.commonPool.)
Loom, I believe, "dummies out" the ForkJoinPool.commonPool — ForkJoinTasks/CompletableFutures/etc. by default just execute on Loom's unbounded virtual-thread executor.
(Which happens to be built on top of a ForkJoinPool, because it's a good scheduler. Don't fix what ain't broke.)
(And that's aside from CompletableFuture having its own separate problems, like the obtrude methods)