Desugar Lua operators

329 views Asked by At

Since Lua supports first-class functions, I'd like to know if you can desugar operators, like in many functional languages. E.g in OCaml you can do:

let x = (+) 3 5

The code above inits the variable x with the value 3 + 5. Writing (+) is equivalent of having a local function that takes two parameters and returns their sum. (+) 3 5 is calling this function with the two arguments 3 and 5. The motivation behinds this is that you can pass the operator directly to a function without having to wrapped it in a function before:

local t = {"ab", "d", "c" }
local function op_greaterthan (a,b) return a>b end
table.sort (t, op_greaterthan) --would like to write: table.sort (t, (>)) 

Thanks!

2

There are 2 answers

0
kikito On BEST ANSWER

You can't.

The Lua interpreter is very small, and it "makes shortcuts" when dealing with operators; for the parser, they are simply not "functions".

If you try to use an operator without its params, like this:

f(+)

Then the interpreter will throw a syntax error.

Due to this implementation, you are limited to the options already discussed: either you use a wrapper function (such as add) or you pass in a string and so some kind of eval, as in jpjacobs' solution.

4
jpjacobs On

Yes you can (I don't see the point of it, and it will be slower, but it is possible):

do
    local mem={}
    function unsugar(op,a,b)

        if mem[op] then
            print('Fetched operation from memory')
            return mem[op](a,b)
        else
            local f=loadstring('local a,b=...; return a '..op..' b')
            mem[op]=f
            return f(a,b)
        end
    end
end
print(unsugar('+',1,2)) -- = 3
print(unsugar('%',5,3)) -- = 2
print(unsugar('%',5,3)) -- = Fetched operation from memory \n 2

Edit: Eliminated stray globals a and b, and put in memoizing to improve performance, by compiling each operation only once.