In addition to what araq wrote the following scenarios: You get user-input via a GUI widget and want to send that to another thread to do some computation. You are not the code that is generating the data. Therefore, you **can not** isolate what comes out of the widget, for all you know it is still retaining a reference. That is, unless you copy. At which point, why are you using channels etc. that requires you to isolate when you can just copy in the first place.
Therefore, in all scenarios where data you need to send comes from something you do not control, it won't help you. And those scenarios occur **a lot**. Further, even _if_ you control the data, the ergonomics are pretty rough. You can't do a computation with the data first for something unrelated and _then_ isolate for sending across threads (at least I couldn't figure that one out), which also can be quite often a scenario you run into. Lastly, the ergonomics are rough. Isolate fundamentally that is only something that matters for the _technical_ problem-domain of pushing data-across threads. But given the way you need to use it at the spawn-site of whatever data you want to send across threads, you now have that littered all throughout your codebase and you can't really ecapsulate that in a single module that cares about cross-thread-data-transfer because the isolation type must be everywhere and you need to think about it everywhere that you use that data. These three reasons were ultimately why my multithreading experiments will just rely on copying. It's just simpler and less of a headache.