2012-01-16 6 views
3

Luaはファーストクラスの関数をサポートしているので、多くの関数型言語のように、演算子をdesugarできるかどうかを知りたいと思います。例えばOCamlの中であなたが行うことができます:Desugar Luaオペレータ

let x = (+) 3 5 

3 + 5を持つ変数xのINIT上記のコード。 (+)を書くことは、2つのパラメータをとり、その合計を返すローカル関数を持つことに相当します。 (+) 3 5は、この関数を2つの引数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, (>)) 

ありがとう: 動機は、これはあなたが前に、機能に包みすることなく、機能に直接オペレータを渡すことができるということです尻!

+0

私は答えは分かりませんが、不可能な場合は、独自の関数( 'function add(a、b)return a + b end'を返すことができます) – personak

+3

Um、そのコードが実際に何をするのか説明できますか?誰もOCamlが何であるかを知らない。 –

+0

なぜ1つのdesugar演算子ですか? –

答えて

4

できません。

Luaインタプリタは非常に小さく、演算子を扱うときには「ショートカットを作成します。パーサーにとっては、単に「関数」ではありません。

あなたは、このように、そののparamsなし演算子を使用しようとすると:そして、インタプリタは、構文エラーがスローされます

f(+) 

により、この実装には、すでに述べたオプションに制限されています:どちらかは、( addなど)のラッパー関数を使用するか、jpjacobsのソリューションのように、文字列を渡すと evalのようにいくつかの種類。

4

はいあなたは(私はそれのポイントが表示されていない、それが遅くなりますが、それは可能である)ことができます:

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の全廃、およびput各操作を1回だけコンパイルすることで、パフォーマンスを向上させるためにメモをとることができます。

+0

これはまだそれを関数にラップします。 – Deco

+0

ちょっとした注意 - 関数に 'local'がありません。このようにして、不要なグローバル' a'と 'b'が作成されます。また、効率的な理由から、[コンパイルされた関数をメモしてください](http://www.lua.org/pil/17.1.html)する必要があります。 –

+1

@Deco:kikitoが言ったように、演算子を "desugar"することはできません。演算子の関数を自分で作成する必要があります。難しいことではありません。このPenlightの演算子モジュール(https://github.com/stevedonovan/Penlight/blob/master/lua/pl/operator.lua)をご覧ください。 –