Now make Request and Response generic so that you can tell different requests and responses apart.
Then make Future generic so that you can use all the existing combinators out there, like `sequence` which turns `List[Future[Response]]` into a Future[List[Response]]`.
Your reply actually highlights one of the key features of Go: if you design it right using channels, constructs like Futures and Promises aren't necessary.
> design it right using channels, constructs like Futures and Promises aren't necessary
Careful implying that using futures and promises are incorrect unless you can prove that channels can do anything futures and promises can do while doing it better.
In Go they are incorrect at worst, not idiomatic at best. That's due to the nature of the language as channels are built-in primitives capable of fulfilling the roles of either, not a slight on the efficacy of the constructs themselves.
Then make Future generic so that you can use all the existing combinators out there, like `sequence` which turns `List[Future[Response]]` into a Future[List[Response]]`.