脱糖 Lua 运算符

发布于 2024-12-27 12:55:12 字数 521 浏览 1 评论 0原文

由于 Lua 支持一等函数,我想知道是否可以像许多函数式语言一样对运算符进行脱糖操作。例如,在 OCaml 中,您可以执行以下操作:

let x = (+) 3 5

上面的代码使用值 3 + 5 初始化变量 x。编写 (+) 相当于拥有一个接受两个参数并返回它们之和的本地函数。 (+) 3 5 使用两个参数 35 调用此函数。 其背后的动机是您可以将运算符直接传递给函数,而不必之前将其包装在函数中:

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, (>)) 

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陪你搞怪i 2025-01-03 12:55:12

你不能。

Lua解释器很小,在处理运算符时“走捷径”;对于解析器来说,它们根本就不是“函数”。

如果您尝试使用不带参数的运算符,如下所示:

f(+)

那么解释器将抛出语法错误。

由于这种实现,您只能使用已经讨论过的选项:要么使用包装函数(例如 add),要么传入字符串等某种 eval >,如 jpjacobs 的解决方案所示。

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.

爱已欠费 2025-01-03 12:55:12

是的,你可以(我不明白它的意义,它会更慢,但这是可能的):

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

编辑:消除杂散全局变量 a 和 b,并放入记忆以提高性能,每个操作仅编译一次。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文