dart-lang / dart-lang/language
Consider adding RAII
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
I would like to propose new semantics for RAII in Dart.
For a class to be a resource, it should be annotated as `resource`, which requires the `dispose` method. For a variable to hold a resource, it must be annotaded with `using`. This is necessary for two reasons: The binding needs to be final; binding a new value to the variable would cause a resource leak. The second reason is that the resource cannot escape its scope. That means the reference (after all, classes are reference types) cannot be copied to a variable outside the resource's scope. Copying the reference is only legal within the scope. At the end of the scope, all resources should get destroyed in reverse order and the dispose methods should be called.
```Dart
resource SomeResource {
// other methods
void _dispose() {
// some cleanup
}
}
void usingResource() {
using resource = new SomeResource();
{
using anotherResource = new SomeResource();
}
// anotherResource gets destroyed
}
// resource gets destroyed
```
Of course there are cases where a resource must escape its scope, for example when it gets returned by a function. In this case the responsability of disposing the resource shifts from the function to the caller:
```Dart
SomeResource returningResource() {
using resource = new SomeResource();
return resource;
}
// caller
void main() {
using resource = returningResource();
}
// resource's dispose method gets called
```
On the caller's side the same rules apply: He needs to annotate the receiving variable with `using` and when it hits the end of the scope it gets destroyed. Resources which are function arguments of course outlive the function's scope and cannot be destroyed within the function.
Another case where a resource needs to escape is when it is part of another resource. Resources can only be part of other resources! They cannot be part of other classes because that would mean resource leaks. When the encapsulating resource gets destroyed, all encapsulated resources get destroyed as well, even without explicitly calling their dispose method. This ensures that encapsulated resources will get destroyed (at the latest) when the encapsulating resource gets destroyed itself. But it can also be done manually.
This of course raises the question what to do when a resource ist part of several other resources. Two possible solutions would be reference counting and weak references. Which is the right one depends on the use case.
I hope this is helpful and sparks new ideas.
Contributor guide
Assessment
This issue has not been assessed yet.