> Also most languages provide cleaner try-with-resources or RAII style lifetime management so you don't actually end up with that kind of spaghetti code unless you actively go out of your way to be bad at programming.
Context managers (try with resources) specifically don't work at all when release is conditional e.g. open a file, need some post processing, need to close the file if the post-processing fails but return it if it succeeds.
Defers don't either, unless you have a specialised one (e.g. zig's errdefer).
Actual RAII (aka affine types) does work, but adding that to a GC'd langage after the fact is a huge undertaking and increase in complexity, because the interaction between affine and normal types is fraught.
Context managers (try with resources) specifically don't work at all when release is conditional e.g. open a file, need some post processing, need to close the file if the post-processing fails but return it if it succeeds.
Defers don't either, unless you have a specialised one (e.g. zig's errdefer).
Actual RAII (aka affine types) does work, but adding that to a GC'd langage after the fact is a huge undertaking and increase in complexity, because the interaction between affine and normal types is fraught.