ক্লোজার্ড: 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)))))

এবং এবার সবকিছুই প্রিন্ট করবে।