[proposal] call __close at end of the function

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[proposal] call __close at end of the function

pocomane
I think that the current <close> semantic is not adequate for the use
in a sub-block. I could want to continue to use the object outside the
sub block (and before it is closed). Consider the code:

```
local instance
if condition then
  instance = my_obj_A()
  --... operations specific to A
else
  instance = my_obj_B()
  --... operations specific to B
end
local instance_c <close> = instance
--... operations common to A and B
```

In such cases <close> could be very far from the initialization, so it
has the same expressivity of a direct call to a close function.

Among the solutions I can think of [1], the best I can found is to
call __close at END OF THE FUNCTION [2] instead of the end of the
scope. So we can put <close> inside the block:

```
local instance
if condition then
  local obj <close> = my_obj_A()
  instance = obj
  --... operations specific to A
else
  local obj <close> = my_obj_B()
  instance = obj
  --... operations specific to B
end
--... operations common to A and B
-- PROPOSAL: __close should be call HERE
```

This also abstracts away the need of closing from the subsequent code.
So you can mix objects that need to be close with one that do not need
it (e.g. in the previous code, suppose to remove <close> from my_obj_A
and keep the one on my_obj_B).

It does not seems to break other use cases to me.

pocomane

[1] Another way to improve the usage in the discussed case could be to
drop some constraint of <close>, i.e. the implicit <const> and the
check of wrong assignment. This enables us to write:

```
local instance <close>
if condition then
  instance = my_obj_A()
  --...
else
  instance = my_obj_B()
  --...
end
--...
```

It is still not optimal, since I think the best place to put the <close> is near
the my_obj_A/B() call, but it make the code more readeable anyway.

However, removing <const> constraint results in some other wired behaviour:

```
local v <const>
v = my_obj_A()
v = my_obj_B() --[[ __close called on my_obj_A result ]]
v = nil --[[ __close called on my_obj_B result ]]
```

[2] Yes, this is the solution adopted by the Go defer.