Ephemeral resource management
eduardoleon opened this issue · comments
An ephemeral resource is a runtime entity with nontrivial cleanup logic, which must be executed exactly once. Not more, not less. Examples of ephemeral resources are: file handles, network connections, GUI objects, etc. Java and C++ have dedicated language features (“finalizers” and “destructors”, respectively) for managing ephemeral resources. Standard ML doesn't provide any useful abstractions for this purpose, either in the core language or in the Basis Library. As a result, writing programs that don't leak ephemeral resources in Standard ML is just as hard as it is in C. What a disaster!
IMO, the most successful abstraction ever designed for managing ephemeral resources is ownership, which can be thought of as a stylized variant of substructural types. Several languages (all of which descend from C++) incorporate ownership in their design, but as far as I can tell, the only one that does so in a type-safe manner is Rust.
Of course, neither Standard ML nor Successor ML has substructural types. But that doesn't mean that we can't incorporate ownership support in some way or another. An ownership system for Successor ML must have the following properties:
- Cleanup logic is guaranteed to run exactly once for every ephemeral resource.
- It must be implemented entirely as a library. No radical changes to ML's type system are allowed - nothing like Rust's affine types and lifetimes.
Here's my very rough proposal:
- Unlike Rust, where ephemeral resources are owned by lexical scopes, in Successor ML, ephemeral resources shall be owned by threads. The first owner of an ephemeral resource is the thread that created it, but ownership can be transferred to another thread. When a thread terminates, whether successfully or with an error, it calls the cleanup function of every ephemeral resource it owns, in the reverse order of acquisition.
- Manually cleaning up ephemeral resources must still be possible. Successive attempts to clean up the same ephemeral resource shall do nothing. Then the ownership system only needs to guarantee that every cleanup function is called at least once.
- Since Successor ML doesn't have substructural types, we must content ourselves with raising exceptions in certain circumstances that Rust can prevent statically, like use after free.
This issue seems more appropriate for the Successor-ML page.