Groovyの実装 curry、舞台裏であっても実際にはどの時点でもカレーしません。これは、部分的なアプリケーションと本質的に同じです。
curry、rcurryおよびncurry方法は返すCurriedClosureオブジェクトをバインドされた引数を保持しています。またgetUncurriedArguments、バインドされた引数とともに渡された引数の構成を返すメソッド(名前は間違っています-引数ではなく関数です)があります。
クロージャが呼び出されると、最終的にのinvokeMethodメソッドをMetaClassImpl呼び出し、呼び出し元のオブジェクトがのインスタンスであるかどうかを明示的に確認しますCurriedClosure。その場合、前述の方法getUncurriedArgumentsを使用して、適用する引数の完全な配列を作成します。
if (objectClass == CurriedClosure.class) {
    // ...
    final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
    // [Ed: Yes, you read that right, curried = uncurried. :) ]
    // ...
    return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}
上記の混乱したやや一貫性のない命名法に基づいて、私はこれを書いた人は誰でも概念的な理解を持っていると思うが、多分少し急ぎ、おそらく多くの賢い人々のようにカリー化を部分適用と混同した。少し不幸な場合、これは理解できます(ポールキングの答えを参照)。後方互換性を損なうことなくこれを修正することは困難です。
私が提案した解決策の1つはcurry、引数が渡されないときに実際にカリー化するようにメソッドをオーバーロードし、新しいpartial関数を優先して引数を使用してメソッドを呼び出すことを非推奨にすることです。これは少し奇妙に思えるかもしれませんが、後方互換性を最大化するでしょう(引数なしで部分的なアプリケーションを使用する理由がないためです)。 named curryは何か違うもので、紛らわしいほど似ています。
curry言うまでもなく、呼び出しの結果は実際のカレーとはまったく異なります。関数が本当にカリー化されている場合、次のように書くことができます。
def add = { x, y -> x + y }
def addCurried = add.curry()   // should work like { x -> { y -> x + y } }
def add1 = addCurried(1)       // should work like { y -> 1 + y }
assert add1(1) == 2 
…そしてのように動作するaddCurriedはずなので、動作し{ x -> { y -> x + y } }ます。代わりに、実行時例外がスローされ、内部で少し死にます。