The core of the answer lies in Ben Lesh's laconic summary:
TL;DR: You want a HOT observable when you don’t want to create your
producer over and over again.
In direct answer to the question "What's a case where you would prefer or use a cold observable over a hot one?", I'll offer both a general answer and a specific example.
Generally, it is far more convenient to use a cold observable to model streams that are created each time they are required than to create a hot one and try to wrangle it.
Specifically, consider the following trivial example. Say you want to respond to a click on a button by counting down from 10. If the button is clicked again during the countdown, it starts again at 10. If click$ models the button events, you might have something like this:
const subscription = click$
.flatMapLatest(_ => Rx.Observable.interval(1000).take(10))
.select(x => 10 - x)
.subscribe(x => console.log('clicked: ' + x));
Consider how this would be modelled without a cold observable. How would you:
- Initialize a stream in advance so that appropriate values were available when required?
- Avoid having to deal with the fraction of a second between the interval ticks and the time of your subscription?
- Deal with ordinals that can start at any number rather than just 1?
- Manage clean up logic for the stream?
1 and 3 can be addressed pretty easily, but 2 and 4 are nasty.
In answer to your second question "Is it laziness?" I would argue that it is not. A cold observable can leave it until the moment of subscription to produce its values. A hot observable can leave it until the moment of subscription to hook the appropriate events. They are both lazy in their own way (or at least, can be). The key difference lies in what Ben Lesh said: do you want to create a producer each time? And sometimes, you really do.