This is an interesting case for error-handling, because a) it can happen virtually anywhere, so handling it with Result would add huge API overhead in terms of ergonomics (given that most code never really has to think about it), yet b) it's very important that it is able to be handled in certain kinds of system contexts, which panics are not designed to facilitate. Most error cases seem to fall neatly into one camp or the other (something you always want to explicitly handle, or something where you just want to abort), but this one doesn't.
handle_alloc_error seems to do well enough as a workaround, but (from my superficial reading of the GitHub thread) it feels like just a very specific "poor-man's try/catch" for this one particular case. It feels like a workaround.
In general I'm a big fan of Result/panic in place of traditional exceptions, but this usecase makes it really quite unideal
> This is an interesting case for error-handling, [...]
Part of the problem is that it's actually two different error cases: A, the data we're operating on is too large, versus B: the system as a whole doesn't have enough memory. Case A is obviously[0] a explicitly-handle error (just like "the data we're operating on is malformed"), whereas case B is obviously a just-give-up error (like "the system doesn't have a floating-point unit"). But there doesn't seem to be any practical way to reliably distinguish the two cases, and it's not clear they can be rigorously separated even in principle.
0: we might decide to 'handle' it by aborting, but that's not special to allocation
> This is an interesting case for error-handling, because
I think this is a very good articulation of this space, thank you.
> It feels like a workaround.
I agree, but the needed work to improve this has taken a very, very, very long time, and so I think workarounds are ultimately helpful. We'll get there...
I think it can honestly be traced down to just how wide a stretch of usecases Rust itself has managed to span. For systems, this arguably is "something you always want to explicitly handle", whereas for applications it's almost always "something where you just want to abort". The level of abstraction is very different, but a single language is spanning both. Or, more precisely, a single standard library.
Just spitballing: maybe one solution could be an alternate set of standard primitives, specifically for low-level work, that do return a Result for everything that might trigger OOM? Maybe those could be abstracted out of the current standard library, and the existing ("application-level") APIs could wrap them with a panic?
This is AFAICT essentially what wg-allocators is working on where you can directly specify an allocator in collections (and alloc() returns a Result): https://github.com/TimDiekmann/alloc-wg
From the readme it sounds like this has actually started to be upstreamed now?
handle_alloc_error seems to do well enough as a workaround, but (from my superficial reading of the GitHub thread) it feels like just a very specific "poor-man's try/catch" for this one particular case. It feels like a workaround.
In general I'm a big fan of Result/panic in place of traditional exceptions, but this usecase makes it really quite unideal