Another take on <close> - or defer-ring instead

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Another take on <close> - or defer-ring instead

Dibyendu Majumdar
Hi,

The beta release of 5.4 prompted me to finally try something I have
been thinking about.
Instead of the <close> variable and __close metamethod, the approach I
have taken is this:

A new keyword 'defer' introduces a deferred function that will be
executed on block scope exit.
The function cannot be named, hence you cannot reference it in Lua code.
Under the cover the defer statement introduces a 'hidden' local
variable and generates op code to create an upvalue for it. The value
assigned to this must be a function.

I have a very early commit - based on Roberto's initial work on
toclose vars, in my git repository (link below). The implementation is
not complete and not working correctly yet.

https://github.com/dibyendumajumdar/ravi/commit/e8a5f2245c34d00fb6684ce235dbf52d908fa8a2

Example session:

> function x()
>>   defer function() print 'exit x' end
>> end
> x()
exit x
> function x()
>>    defer function() print 'exit x' end
>>    error('err')
>> end
> x()
exit x
stdin:3: err
stack traceback:
    [C]: in function 'error'
    stdin:3: in function 'x'
    (...tail calls...)
    [C]: in ?

Reply | Threaded
Open this post in threaded view
|

Re: Another take on <close> - or defer-ring instead

Dibyendu Majumdar
On Sat, 5 Oct 2019 at 21:00, Dibyendu Majumdar <[hidden email]> wrote:

> I have a very early commit - based on Roberto's initial work on
> toclose vars, in my git repository (link below). The implementation is
> not complete and not working correctly yet.
>

Since luaF_close() call can now lead to stack being resized, it is
necessary to protect such calls; i.e. the base pointer must be
refreshed. I had missed that in my first commit.

Have only tested with simple examples so far. Here is an example session:

> function x()
>>    for i=1,5 do
>>        defer function() print(i) end
>>    end
>> end
> x()
1
2
3
4
5
>

BTW syntax of defer could be simplified by omitting the 'function()'.

The JIT backends are not yet fully updated.

Anyway, if anyone wants to try out, the branch is 'defer'.

https://github.com/dibyendumajumdar/ravi/tree/defer

Regards

Reply | Threaded
Open this post in threaded view
|

Re: Another take on <close> - or defer-ring instead

Dibyendu Majumdar
On Sun, 6 Oct 2019 at 01:52, Dibyendu Majumdar <[hidden email]> wrote:
> BTW syntax of defer could be simplified by omitting the 'function()'.
>

This is now committed. So we can simply write:

function x()
   defer print('exited') end
end

Credit for this idea goes to Daurnimator:
http://lua-users.org/lists/lua-l/2019-06/msg00280.html

> The JIT backends are not yet fully updated.
>
> Anyway, if anyone wants to try out, the branch is 'defer'.
>
> https://github.com/dibyendumajumdar/ravi/tree/defer
>

Reply | Threaded
Open this post in threaded view
|

Re: Another take on <close> - or defer-ring instead

Dibyendu Majumdar
On Sun, 6 Oct 2019 at 18:46, Dibyendu Majumdar <[hidden email]> wrote:

> This is now committed. So we can simply write:
>
> function x()
>    defer print('exited') end
> end
>
> Credit for this idea goes to Daurnimator:
> http://lua-users.org/lists/lua-l/2019-06/msg00280.html
>
> > The JIT backends are not yet fully updated.
> >
> > Anyway, if anyone wants to try out, the branch is 'defer'.
> >
> > https://github.com/dibyendumajumdar/ravi/tree/defer
> >

One thing I realized while implementing this approach is that it
doesn't require folks to rewrite their libraries to implement __close
metamethods; i.e. user code can take advantage of deterministic
cleanup without having to use 5.4 only compatible libraries. In
particular, a patch can be applied to 5.3 to support this syntax.

Regards

Reply | Threaded
Open this post in threaded view
|

Re: Another take on <close> - or defer-ring instead

pocomane


On Mon 7 Oct 2019, 23:24 Dibyendu Majumdar, <[hidden email]> wrote:
One thing I realized while implementing this approach is that it
doesn't require folks to rewrite their libraries to implement __close
metamethods; i.e. user code can take advantage of deterministic
cleanup without having to use 5.4 only compatible libraries. In
particular, a patch can be applied to 5.3 to support this syntax.

Regards

This also means that you are not forcing any standards, i.e. your users need to know HOW to close any object, while with the <close> syntax they just need to know that they have to close them [1].

pocomane

P.S. I am enchanted by the simplicity of a go-like defer too.



Reply | Threaded
Open this post in threaded view
|

Re: Another take on <close> - or defer-ring instead

Dibyendu Majumdar
In reply to this post by Dibyendu Majumdar
I have been making progress with this. The initial LLVM backend
support is now in.
I am looking for tests I could add - so far the simple tests I have
created appear to work.

For the curious, here is what the bytecode looks like:

> function try_deferred()
>>   defer print'deferred' end
>> end
> ravi.dumplua(try_deferred)

function <stdin:1,3> (3 instructions at 000002442A3EEB30)
0 params, 2 slots, 1 upvalue, 1 local, 0 constants, 1 function
        1       [2]     DEFER           0
        2       [2]     CLOSURE         0 0     ; 000002442A3EEE60
        3       [3]     RETURN          0 1
constants (0) for 000002442A3EEB30:
locals (1) for 000002442A3EEB30:
        0       (deferred function)     3       4
upvalues (1) for 000002442A3EEB30:
        0       _ENV    0       0

function <stdin:2,2> (4 instructions at 000002442A3EEE60)
0 params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions
        1       [2]     GETTABUP_SK     0 0 -1  ; _ENV "print"
        2       [2]     LOADK           1 -2    ; "deferred"
        3       [2]     CALL            0 2 1
        4       [2]     RETURN          0 1
constants (2) for 000002442A3EEE60:
        1       "print"
        2       "deferred"
locals (0) for 000002442A3EEE60:
upvalues (1) for 000002442A3EEE60:
        0       _ENV    0       0

On Sun, 6 Oct 2019 at 18:46, Dibyendu Majumdar <[hidden email]> wrote:

>
> On Sun, 6 Oct 2019 at 01:52, Dibyendu Majumdar <[hidden email]> wrote:
> > BTW syntax of defer could be simplified by omitting the 'function()'.
> >
>
> This is now committed. So we can simply write:
>
> function x()
>    defer print('exited') end
> end
>
> Credit for this idea goes to Daurnimator:
> http://lua-users.org/lists/lua-l/2019-06/msg00280.html
>
> > The JIT backends are not yet fully updated.
> >
> > Anyway, if anyone wants to try out, the branch is 'defer'.
> >
> > https://github.com/dibyendumajumdar/ravi/tree/defer
> >