3

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!

elmattic
  • 12,046
  • 5
  • 43
  • 79
  • I don't know the answer, but if it's impossible, you can make your own function (`function add(a, b) return a + b end`) – personak Jan 16 '12 at 00:43
  • 3
    Um, can you explain what that code actually does? Not everyone know what OCaml is. – Nicol Bolas Jan 16 '12 at 01:15
  • Why would one desugar operators? –  Jan 16 '12 at 05:39
  • In many programming languages, operators are treated as functions. For example, `1+2` is literally equivalent to `add(1,2)`. He's asking for a function that is directly equivalent to `add`. `function(a,b)return a+b end` is indirectly equivalent, in that it requires a Lua function to be called before the actual operator is applied. – Deco Jan 16 '12 at 10:55

2 Answers2

4

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.

jpjacobs
  • 9,359
  • 36
  • 45
  • This still wraps it in a function. – Deco Jan 16 '12 at 10:52
  • Just a side note - you are missing a `local` in the function, this way unwanted globals `a` and `b` are created. Also, you should [memoize the compiled functions](http://www.lua.org/pil/17.1.html) for efficiency reasons. – Michal Kottman Jan 16 '12 at 15:14
  • 1
    @Deco: as kikito said, you cannot "desugar" operators. You have to create functions for operators yourself. It's not hard, take a look [at this Penlight "operator" module](https://github.com/stevedonovan/Penlight/blob/master/lua/pl/operator.lua). – Michal Kottman Jan 16 '12 at 15:18
  • Entirely true. Edited my post accordingly – jpjacobs Jan 16 '12 at 15:26
4

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.

kikito
  • 51,734
  • 32
  • 149
  • 189