【问题标题】:Desugar Lua operatorsDesugar Lua operators
【发布时间】:2012-01-16 00:37:00
【问题描述】:

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

谢谢!

【问题讨论】:

  • 我不知道答案,但如果不可能,你可以自己制作函数(function add(a, b) return a + b end
  • 嗯,你能解释一下这段代码的实际作用吗?不是每个人都知道 OCaml 是什么。
  • 为什么要对运营商脱糖?
  • 在许多编程语言中,运算符被视为函数。例如,1+2 在字面上等同于add(1,2)。他要求一个直接等同于add 的函数。 function(a,b)return a+b end 间接等效,因为它需要在应用实际运算符之前调用 Lua 函数。

标签: lua operators syntactic-sugar first-class-functions


【解决方案1】:

你不能。

Lua 解释器很小,在处理操作符时会“走捷径”;对于解析器,它们根本不是“函数”。

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

f(+)

然后解释器会抛出语法错误。

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

【讨论】:

    【解决方案2】:

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

    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,并通过只编译每个操作一次来提高性能。

    【讨论】:

    • 这仍然将它包装在一个函数中。
    • 只是一个旁注——你在函数中缺少一个local,这样不需要的全局变量ab就被创建了。此外,出于效率原因,您应该memoize the compiled functions
    • @Deco:正如 kikito 所说,您不能“脱糖”运算符。您必须自己为操作员创建函数。不难,看看at this Penlight "operator" module.
    • 完全正确。相应地编辑了我的帖子
    猜你喜欢
    • 2018-04-27
    • 2022-06-26
    • 1970-01-01
    • 2011-09-06
    • 2022-12-02
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多