lua-users home
lua-l archive

Re: Comparing numerical objects for equality (patch)

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Eduardo,
Nathan's patch modifies the behaviour of the __eq metamethod so it might
(and almost certainly will) break some existing code. That's why I
suggest adding a new metamethod to 'fill in the gap'.
This way, the change is completely backwards compatible. There should
not be any code which puts an entry called '__eqval' into the metatable,
since all identifiers starting with '__' are reserved for use by Lua.
My patch introduces a slight performance penalty on all comparisons with
a constant, and an extra search for the __eqval metamethod iff one of
the operands to '==' or '~=' is a table or userdata.
I'm not very familiar with the internals of the VM, so it's probably
possible to implement the feature more efficiently.
-a
On 09/06/2022 06:20, Eduardo Bart wrote:
 > So we can't write "natural" code that works for both Lua numbers and
numerical objects.
As the author of lua-bint (Arbitrary precision integer arithmetic
library in pure Lua), I also wish there was some solution for this
problem in a future Lua release, because this is the only corner case
where I can't mix lua numbers.
This problem has been mentioned before by Nathan Page and he has also
come with a smaller patch for Lua 5.4 in
http://lua-users.org/lists/lua-l/2022-01/msg00140.html
<http://lua-users.org/lists/lua-l/2022-01/msg00140.html> .
---
Eduardo Bart
Em qua., 8 de jun. de 2022 às 10:07, Andrew <ajc@gmx.net
<mailto:ajc@gmx.net>> escreveu:
 Hello All,
 there is currently a small but annoying problem when constructing
 numerical objects based on tables or userdata.
 To illustrate this, here is a little multi-precision integer library in
 pure Lua that I've been working on (https://github.com/geneas/lua
 <https://github.com/geneas/lua>, see
 file mpi.lua).
 By defining appropriate metamethods we can use these objects in
 expressions just like native Lua numbers:
 local mpi = require "geneas.mpi"
 local a = mpi(1)
 local b = mpi "777777777777777777777777777777"
 local c = a + b         -- metamethod __add
 print(c)                -- metamethod __tostring
 [ 777777777777777777777777777778 ]
 if a < 2 then           -- metamethod __lt
         print "true"
 else
         print "false"
 end
 [ true ]
 But there's a problem when comparing for equality, because the __eq
 metamethod is only called when _both_ operands are tables or userdata!
 if a == 1 then          -- metamethod __eq
         print "true"
 else
         print "false"
 end
 [ false ]
 This is annoying, because we have to write "if a == mpi(1)", or maybe
 even "if mpi(a) == mpi(1)", if we are not sure whether a is actually an
 mpi object or a Lua number!
 So we can't write "natural" code that works for both Lua numbers and
 numerical objects.
 My proposed solution is to add an extra metamethod __eqval (suggested
 name) which is called by the equality operators when exactly one of the
 operands is a table or userdata, ie, in all those cases where the other
 arithmetic and comparison metamethods would be called but __eq is not.
 The __eqval metamethod should perform the same function as __eq (maybe
 with some extra checking of the operand types). As a result the equality
 operators '==' and '~=' now behave the same for objects of the numerical
 class as they do for Lua numbers.
 No existing Lua code is impacted, since the semantics of the __eq
 metamethod remain unchanged and no __eqval metamethod will be defined.
 I've made a patch for Lua 5.4.4 which is available here:
 https://github.com/geneas/lua/blob/master/eqval544.p
 <https://github.com/geneas/lua/blob/master/eqval544.p>
 Perhaps this functionality could be considered for inclusion in a future
 mainline release?
 Andrew

AltStyle によって変換されたページ (->オリジナル) /