default metatable

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

default metatable

temp212
Hello,
I would like to have a "Mathematica style" table arthmetics in
Lua.
it is ok to have it implemented in Lua, something like:

local function ar_func (o1, o2, op)
   local o = {};
   if type(o1) == "table" and type(o2) == "table" then
     if #o1 == #o2 then
       for i = 1, #o1 do o[i] = op(o1[i], o2[i]) end
       return o
     end
   elseif type(o1) == "table" and type(o2) == "number" then
   for i = 1, #o1 do o[i] = op(o1[i], o2) end
   return o
   elseif type(o1) == "number" and type(o2) == "table" then
     for i = 1, #o2 do o[i] = op(o1, o2[i]) end
     return o
   end
   return nil
end


table.default_metatable = {}

table.default_metatable.__add = function (t1,t2) return
ar_func(t1,t2, function (o1,o2) return o1+o2 end) end
table.default_metatable.__mul = function (t1,t2) return
ar_func(t1,t2, function (o1,o2) return o1*o2 end) end
table.default_metatable.__sub = function (t1,t2) return
ar_func(t1,t2, function (o1,o2) return o1-o2 end) end
table.default_metatable.__div = function (t1,t2) return
ar_func(t1,t2, function (o1,o2) return o1/o2 end) end
table.default_metatable.__pow = function (t1,t2) return
ar_func(t1,t2, function (o1,o2) return o1^o2 end) end
table.default_metatable.__unm = function (t1 ) return
ar_func(t1,t1, function (o1,o2) return -o1 end) end


BUT, the problem is there is no way to set it as metatable to
newly created tables automatically, to make code like {x,y,z}
* {1,0,1} + 5 working.

I made it the ugly way, by modifing OP_NEWTABLE in lvm.c:

void luaV_execute (lua_State *L) {
...
vmcase(OP_NEWTABLE) {

   Table *t = luaH_new(L);

//+++++++++++++++
   if (NULL == t->metatable){
     if (LUA_TTABLE == lua_getglobal(L, "table")){
       if (LUA_TTABLE == lua_getfield(L, -1,
"default_metatable")){
         t->metatable = hvalue(L->top - 1);
       }
       lua_pop(L,1);
     }
     lua_pop(L,1);
   }
//+++++++++++++++
...

Currently there are "per type" metatables for all the other
types: numbers, strings.
Is it possible to add one more for the table type, which would
be set as metatable for new tables by default?

Reply | Threaded
Open this post in threaded view
|

Re: default metatable

Duncan Cross
On Thu, Jun 29, 2017 at 2:09 PM,  <[hidden email]> wrote:
> BUT, the problem is there is no way to set it as metatable to newly created
> tables automatically, to make code like {x,y,z} * {1,0,1} + 5 working.

There is no better way to do this currently. The approach I'd
recommend would be to have a function that takes one table parameter,
sets the metatable and returns it, and use it like a table-literal
prefix: T{x,y,z} * T{1,0,1} + 5

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: default metatable

Javier Guerra Giraldez
In reply to this post by temp212
On 29 June 2017 at 14:09,  <[hidden email]> wrote:
> BUT, the problem is there is no way to set it as metatable to newly created
> tables automatically, to make code like {x,y,z} * {1,0,1} + 5 working.


function m(t)
    return setmetatable(t, mathematicmetatable)
end

m{x,y,z} * m{1, 0, 1} +  5

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: default metatable

temp212
On Thu, 29 Jun 2017 15:01:00 +0100
  Javier Guerra Giraldez <[hidden email]> wrote:

> On 29 June 2017 at 14:09,  <[hidden email]> wrote:
>> BUT, the problem is there is no way to set it as metatable
>>to newly created
>> tables automatically
>
> function m(t)
>    return setmetatable(t, mathematicmetatable)
> end
>
> m{x,y,z} * m{1, 0, 1} +  5
>
> --
> Javier

Thanks Javier, this would work, but additional letter before
table still looks a little bit ugly to me, although not as
ugly as my patch that from internals gets the default
metatable using C api.

In some older Lua versions, according to few messages in
mailing list from about 15 years ago, it looks like there was
some default metatable, why its gone?

---
Pavel

Reply | Threaded
Open this post in threaded view
|

Re: default metatable

Tobias Kieslich

Quoting [hidden email]:

> On Thu, 29 Jun 2017 15:01:00 +0100
>  Javier Guerra Giraldez <[hidden email]> wrote:
>> On 29 June 2017 at 14:09,  <[hidden email]> wrote:
>>> BUT, the problem is there is no way to set it as metatable to newly created
>>> tables automatically
>>
>> function m(t)
>>   return setmetatable(t, mathematicmetatable)
>> end
>>
>> m{x,y,z} * m{1, 0, 1} +  5
>>
>> --
>> Javier
>
> Thanks Javier, this would work, but additional letter before table  
> still looks a little bit ugly to me, although not as ugly as my  
> patch that from internals gets the default metatable using C api.
While it might be conceived as ugly it is also explicit.  This is
important if you get back to your code a couple of months later and
wonder why is it doing what it's doing. Or if other people try to
understand your code.If you like to be more explicit you could turn
the function into a object constructor using __call.

  -tobbik




Reply | Threaded
Open this post in threaded view
|

Re: default metatable

Javier Guerra Giraldez
On 29 June 2017 at 18:54,  <[hidden email]> wrote:
> Quoting [hidden email]:
>
>> Thanks Javier, this would work, but additional letter before table still
>> looks a little bit ugly to me, although not as ugly as my patch that from
>> internals gets the default metatable using C api.
>
> While it might be conceived as ugly it is also explicit.

right.  remember that it's possible that you'd still want "plain" Lua
tables in your program.  the factory function can be seen as a "type
prefix", not too different to the '0x' used before hexadecimal
numbers.


--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: default metatable

temp212
On Fri, 30 Jun 2017 08:52:13 +0100
  Javier Guerra Giraldez <[hidden email]> wrote:

> On 29 June 2017 at 18:54,  <[hidden email]> wrote:
>> Quoting [hidden email]:
>>
>>> Thanks Javier, this would work, but additional letter before table still
>>> looks a little bit ugly to me, although not as ugly as my patch that from
>>> internals gets the default metatable using C api.
>>
>> While it might be conceived as ugly it is also explicit.
>
> right.  remember that it's possible that you'd still want "plain" Lua
> tables in your program.  the factory function can be seen as a "type
> prefix", not too different to the '0x' used before hexadecimal
> numbers.
>

The idea was not to break or replace anything, just add
possibility to make arithmetics on equal sized vectors and
numbers "Mathematica style".
'plain' tables would work as usual, by default there is just
no arithmetics for tables without metatable.