• Subject: Re: Comparing numerical objects for equality (patch)
• From: Eduardo Bart <edub4rt@...>
• Date: Wed, 8 Jun 2022 17:20:27 -0300

> 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 .

---
Eduardo Bart

Em qua., 8 de jun. de 2022 às 10:07, Andrew <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, 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

Perhaps this functionality could be considered for inclusion in a future
mainline release?

Andrew

• Follow-Ups:
• References: