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
and or
work; you don't have to use bitwise operators (although those work fine as well).