ক্লোজার্ড: doall to Do all
একটা সিম্পল ফাংশন লেখা যাক, যেটা কিনা (range 10) এর মধ্যে নাম্বারগুলো প্রিন্ট করবে:
(defn print-num-seq []
(map println (range 10)))
রান করলে ঠিকঠাকই কাজ করবে, অর্থাৎ 0 থেকে 9 পর্যন্ত সংখ্যাগুলো প্রিন্ট করবে। এবার, একই কাজ যদি আমরা পাঁচবার করতে চাই তাহলে তারজন্য এমন একটা ফাংশন লিখতে পারি:
(defn print-recur []
(loop [i 0]
(when (< i 5)
(print-num-seq)
(recur (inc i)))))
মজার বিষয় হচ্ছে রান করলে শুধু nil
রিটার্ন করবে। কিছুই প্রিন্ট করবে না।
কেন?
println
print-num-seq
এর সাইডএফেক্ট। আর print-recur
কিছু প্রিন্ট করুক বা না করুক তার রিটার্ন ভ্যালু হবে nil। আসলে এটিই মূল ফলাফল। এখন লেজি সিকোয়েন্সের ক্ষেত্রে সেই সব সাইড এফেক্টগুলোই এক্সিকিউট করা হয় যেগুলোর ফলাফল মূল ফলাফলে প্রভাব রাখবে। এজন্যই কিচ্ছু প্রিন্ট হয়নি।
doall saves the day!
doall
এর কাজ হলো, লেজি সিকোয়েন্সের সাইডএফেক্টগুলো জোর করে এক্সিকিউট করানো। অর্থাৎ print-recur
ফাংশনটি লেখা যায় এভাবে:
(defn print-recur []
(loop [i 0]
(when (< i 5)
(doall (print-num-seq))
(recur (inc i)))))
এবং এবার সবকিছুই প্রিন্ট করবে।