I’ve just finished reading through Modular: Structured Mojo Kernels Part 1 - Peak Performance, Half the Code, and I was wondering why context managers were chosen over using linear types for this. Context managers force a resources to be released in the opposite order they were required, which is often fairly sub-optimal, whereas using linear types, the simple “must release” types are easy to handle, can provide the same sequencing when combined with typestate, but allow for more flexibility around resource acquire/release ordering.
After looking into a lot of the types, many seem like they should be able to be handled with RAII in a similar manner to lock guards, for instance EpilogueWarpContext’s __exit__ is
@always_inline
fn __exit__(self):
self.dealloc_barrier.signal_complete()
As far as I can tell, there isn’t anywhere in the public kernels where this couldn’t be shoved into the __del__, and this appeared to be true for the other types I checked. I can see the argument that RAII makes it easy to accidentally drop resources, in which case linear types fill that gap nicely. Linear types also handle raising from a destructor, so that shouldn’t cause issues.
I’m clearly missing something, since I’d expect people to want to keep flexibility around resource management ordering or take advantage of ASAP RAII to clean things up as quickly as possible. Can someone explain the reasoning for this in a little more detail?