Per-value metatables would be great for threads

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

Per-value metatables would be great for threads

Dirk Laurie-2
Was there near-universal acclaim for per-value metatables,
or am I just remembering what I like to? Anyway, pointing out
one more advantage can't hurt :-)

When a coroutine goes dead, there is often some finalizing to do.
Setting a return hook in order to call a finalizer looks kludgy.
The neat way is a __gc metamethod.

Reply | Threaded
Open this post in threaded view
|

Re: Per-value metatables would be great for threads

Philipp Janda
Am 28.08.2015 um 09:48 schröbte Dirk Laurie:
> Was there near-universal acclaim for per-value metatables,
> or am I just remembering what I like to? Anyway, pointing out
> one more advantage can't hurt :-)
>
> When a coroutine goes dead, there is often some finalizing to do.
> Setting a return hook in order to call a finalizer looks kludgy.
> The neat way is a __gc metamethod.

Two ways of calling finalizers for coroutines in Lua 5.2+ without hooks:

     local function mycocreate1( func, gc )
       local fin = setmetatable( { thread = false }, { __gc = gc } )
       local t = coroutine.create( function( ... )
         local finalizer = fin -- keep finalizer as an upvalue
         return func( ... )
       end )
       fin.thread = t
       return t
     end


     local threadgcs = setmetatable( {}, { __mode = "k" } )

     local function mycocreate2( func, gc )
       local t = coroutine.create( func )
       threadgcs[ t ] = setmetatable( { thread = t }, { __gc = gc } )
       return t
     end


     local function gc( t )
       print( t.thread )
     end

     do
       local t1 = mycocreate1( function() end, gc )
       local t2 = mycocreate2( function() end, gc )
       collectgarbage() collectgarbage()
       print( "xxx" )
     end
     collectgarbage() collectgarbage()
     print( "yyy" )


That said, coroutines are GCObjects already, and a fresh coroutine costs
about 1K of memory, so the extra 8 bytes for a metatable pointer doesn't
really hurt.


Philipp



Reply | Threaded
Open this post in threaded view
|

Re: Per-value metatables would be great for threads

Roberto Ierusalimschy
In reply to this post by Dirk Laurie-2
> Was there near-universal acclaim for per-value metatables,
> or am I just remembering what I like to? Anyway, pointing out
> one more advantage can't hurt :-)

I originally proposed that in jest. (The light userdata part was
serious, but the "(We could even gain individual metatables for numbers
:-)" was intended as a joke...



> When a coroutine goes dead, there is often some finalizing to do.
> Setting a return hook in order to call a finalizer looks kludgy.
> The neat way is a __gc metamethod.

As someone already pointed out, "value metatables" cannot work for
finalizers. An object is collected when there are no more "values"
pointing to it; in that case, its metatable will be no longer
accessible...

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Per-value metatables would be great for threads

Parke
Dirk Laurie wrote:
>> Was there near-universal acclaim for per-value metatables,
>> or am I just remembering what I like to? Anyway, pointing out
>> one more advantage can't hurt :-)

On Fri, Aug 28, 2015 at 5:32 AM, Roberto Ierusalimschy
<[hidden email]> wrote:
> I originally proposed that in jest. (The light userdata part was
> serious, but the "(We could even gain individual metatables for numbers
> :-)" was intended as a joke...

Per value metatables would allow strings to have different metatables.
It would solve many (all of?) the problems Roberto pointed out
previously:

On Tue, May 5, 2015 at 9:00 AM, Roberto Ierusalimschy
<[hidden email]> wrote:
> More to the point, strings have no notion of "self", or of being
> created.  If you run "a".."bc" twice, do you create two different
> strings (with two different metatables) or only one? Are they the
> same as "abc"?  Does that depend on whether there is a GC between the
> execution of those expressions? However you answer those questions,
> there will be a lot of drawbacks.

http://lua-users.org/lists/lua-l/2015-05/msg00094.html

As far as numbers with different metatables... that might allow units
of measure (or other type information) to be associated with numbers.
I have used that capability in other languages in pursuit of
correctness and more informative error messages.  For example, is 4
meters the same as 4 feet?  4 US dollars the same as 4 Euros?

-Parke

Reply | Threaded
Open this post in threaded view
|

Re: Per-value metatables would be great for threads

Christian N.
On 2015-08-28 18:35 +0200, Parke wrote:

> As far as numbers with different metatables... that might allow units
> of measure (or other type information) to be associated with numbers.
> I have used that capability in other languages in pursuit of
> correctness and more informative error messages.  For example, is 4
> meters the same as 4 feet?  4 US dollars the same as 4 Euros?

IMHO 4 meters is not the number 4 with additional information, it should
have its own "meters" type. So if you want the 4 to be different from
other fours (e.g. not allowing addition with them), wrap in in a table
or a userdata object and give it the arithmetic metamethods along with
an appropriate __tostring. If that is too expensive performance-wise,
then I still think that rather than allowing per-value metatables for
all value types, a new value type should be introduced for this purpose
(or a way to create new value-(sub)types on the fly?). The fact that all
4s are the same is IMHO not (only) a limitation, it also reliefs us from
much complexity.

(Sorry if that has all already been said, I haven't read all the
messages about this topic.)


‒ Christian

Reply | Threaded
Open this post in threaded view
|

Re: Per-value metatables would be great for threads

Dirk Laurie-2
2015-08-28 19:46 GMT+02:00 Christian N. <[hidden email]>:
> The fact that all 4s are the same is IMHO not (only) a limitation, it also
> reliefs us from much complexity.

The metatable can always define __eq to enforce equality.