> Have it so that if the promise generates something complicated, like a sequence, that the promise only generates as much of that something as is accessed (and maybe only a little bit beyond that).
What about when you start composing Promises? For example, say I have a top-level promise that just returns a value. But under the hood, it needs a promise that generates an array. Even if the under-the-hood promise generates the array piece by piece, the caller of the larger promise is only even going to get a single value, so they lose the ability to "stop".
(You might imagine that the composed-over promises are network I/O, for example.)
In that case, one thing we can do is that the under the hood promise is not forced at all if the wrapping promise's value isn't forced yet. Then we don't have any async behavior, unfortunately; no calculation begins until the promise is called in. We can do part of the calculation ahead of time, but then stop and don't complete it until there is an indication that the value is required. That is fudgy though: how far is far enough to reap the async benefit without the downsides.
How about this alternative: instead of .cancel() on promises have a .commit(). This is called if you're sure that you will eventually need that value. The calculation then proceeds full steam ahead: no going back.
You can ask for the value with or without .commit(); it is just a hint. But if you ask without .commit(), you may have to wait for a completion that was deliberately stalled due to your lack of commitment.
Without .commit(), async promises will still proceed on their own to some extent based on some fudge factor; we don't want programmers automatically calling .commit() on every promise they make to get the async benefit, which defeats the purpose.
Uncommitted promises could be identifiable to the garbage collector and subject to an internal cancelation protocol between GC and the promises. That protocol basically helps the promise's thread vacate the object so it can be reclaimed.
Promises could have some sort of hint about how far to proceed before requiring commitment. This would have to be well thought out: such hints tend to be too system and workload specific. Automatic tuning is better. The promise system could keep some statistics about how soon various kinds of promises are called in after being initiated, and how often they are called in at all, and then uncommitted promises could decide based on that how far to compute.
What about when you start composing Promises? For example, say I have a top-level promise that just returns a value. But under the hood, it needs a promise that generates an array. Even if the under-the-hood promise generates the array piece by piece, the caller of the larger promise is only even going to get a single value, so they lose the ability to "stop".
(You might imagine that the composed-over promises are network I/O, for example.)