print("i", "j", "i & j")
for i = 0,1 do
for j=0,1 do
print(i, j, i & j)
end
end
The above code works fine in Lua. It gives the following output.
i j i & j
0 0 0
0 1 0
1 0 0
1 1 1
I want to define another operator implies
. It is conditional logical operator. The result p implies q
is false only when p is true and q is false.
print("i", "j", "i implies j")
for i = 0,1 do
for j=0,1 do
print(i, j, i implies j)
end
end
I want the above code to work. It should output the following.
i j i implies j
0 0 1
0 1 1
1 0 0
1 1 1
So far I have succeeded in defining implies function but that doesn't seem to be of great use. Of course I can write implies(i,j) but I want operator similar to & or | that I can use. So basic question is to replicate definition of logical operator & or | from lua. Here is the code for implies function (not operator).
function implies(a,b)
if a then
return b
else
return True
end
end
CodePudding user response:
OOP-style calls
This gets rather hacky if it must truly be infix. What about simply using metatables for OOP-ish object:method(params)
syntax?
Assuming implies
is defined as
local function _implies(a, b)
if a ~= 0 then return b end
return 1
end
this would be implemented as
debug.setmetatable(0, {__index = {
implies = _implies
}})
and used as
i:implies(j)
if you want you a simpler dot syntax instead, consider using currying:
debug.setmetatable(0, {__index = {
implies = function(a) return function(b) return _implies(a, b) end end
}})
used as
i.implies(j)
A more "infix-ish" notation might be achieved by using the __call
metamethod, and passing a function name:
debug.setmetatable(0, {__index = {
implies = function(a) return function(b) return _implies(a, b) end end
}, __call = function(self, index) return self[index] end})
(i)("implies")(j)
If implies = "implies"
, this can even be shortened to (i)(implies)(j)
.
Hacky, "truly" infix notation
If infix notation is of utmost importance, yet you can't use the available metamethods as they are limited and rather unreadable, you can use even more currying and workarounds to use other metamethods to create operators that seemingly turn your function (at least syntactically) into an infix operator using a "proxy" metatable instead of the function. You can use whatever operators you like; just make sure they suit your needs in terms of associativity and precedency:
local implies_right_hand_mt = {
__mul = function(self, b)
return _implies(self.a, b)
end
}
local implies_left_hand = setmetatable({}, {
__mul = function(a)
return setmetatable({a = a}, implies_right_hand_mt)
end
})
implies = implies_left_hand
The syntax would then be i *implies* j
or "i *implies* j"
in your example (using the multiplication operator). You could however use all other operators (except the comparison operators) as well, including other arithmetic operators, as implies
is not a number but rather a table and may thus override number metamethods.
Side note
Consider using booleans instead of numbers. You'd get two advantages:
- Most metamethods aren't used by booleans (especially all arithmetic & bitwise metamethods);
- The logic operators
not
,and
andor
work; you don't have to use bitwise operators (although those work fine as well).
CodePudding user response:
There are two metamethods available for "number" datatype: __call
and __index
.
debug.setmetatable(0, {__call = function(a, b) return a~1|b end})
-- Now you can use "(i)(j)" for "i implies j"
print("i", "j", "(i)(j)")
for i = 0,1 do
for j = 0,1 do
print(i, j, (i)(j))
end
end
CodePudding user response:
Lua has no provision for user-defined operators.
But if i and j were boolean, you could use:
i and j or true
It doesn't work with 0 and 1, because for LUA they are both true!