The main differences between the three can be described along two axes: buffering/single-subscriber vs. non-buffering/multi-striver, and synchronous vs. asynchronous.
You don't really need three separate interfaces for this. Dart's Streams can cover all cases depending on how you create the source StreamController.
I asked some of the people behind the specs and they felt if was too complicated to have one interface cover the use cases. I tend to think it's more complicated now. I can't trivially write code to handle all interfaces without explicitly thinking and opting in to it.
You don't really need three separate interfaces for this. Dart's Streams can cover all cases depending on how you create the source StreamController.
I asked some of the people behind the specs and they felt if was too complicated to have one interface cover the use cases. I tend to think it's more complicated now. I can't trivially write code to handle all interfaces without explicitly thinking and opting in to it.