গ্রোভির বাস্তবায়ন 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);
}
বিভ্রান্তিকর এবং কিছুটা বেমানান নামের উপর ভিত্তি করে, আমি সন্দেহ করি যে এই যে লিখেছে সে সম্পর্কে ভাল ধারণা রয়েছে, তবে সম্ভবত তিনি কিছুটা ছুটে এসেছিলেন এবং অনেক স্মার্ট লোকের মতো - আংশিক প্রয়োগের সাথে তর্ক-বিতর্ক করেছিলেন। এটি বোধগম্য (পল কিং এর উত্তর দেখুন), যদি কিছুটা দুর্ভাগ্য হয়; পিছনের সামঞ্জস্যতা ভঙ্গ না করে এটি সংশোধন করা কঠিন হবে।
একটি সমাধান আমি প্রস্তাব করেছি যাতে curry
পদ্ধতিটি ওভারলোড করা হয় যে কোনও আর্গুমেন্ট পাস না করা হলে এটি আসল কার্চিং করে এবং কোনও নতুন partial
ফাংশনের পক্ষে যুক্তি সহ পদ্ধতিটিকে কল করে অবহেলা করে। এটি কিছুটা অদ্ভুত বলে মনে হতে পারে তবে এটি পিছনের সামঞ্জস্যকে সর্বাধিক করে তুলবে - যেহেতু শূন্য আর্গুমেন্টের সাথে আংশিক অ্যাপ্লিকেশন ব্যবহার করার কোনও কারণ নেই - সঠিকভাবে কার্চিংয়ের জন্য একটি নতুন, ভিন্ন-নামকরণের ফাংশনটি রাখার (আইএমএইচও) কুরুচিপূর্ণ পরিস্থিতি এড়িয়ে যাওয়ার সময় নামযুক্ত 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 } }
। পরিবর্তে এটি একটি রানটাইম ব্যতিক্রম ছুঁড়ে দেয় এবং আপনি কিছুটা ভিতরে মারা যান।