রি

রিকার্সন মধ্যে Elixir

56টি অনুশীলনী

রিকার্সন সম্পর্কে

রিকার্সিভ ফাংশন হলো এমন ফাংশন, যারা নিজেদেরকেই কল করে।

একটি রিকার্সিভ ফাংশনে অন্তত একটি বেস কেস এবং অন্তত একটি রিকার্সিভ কেস থাকতে হয়।

একটি বেস কেস ফাংশনটিকে আবার কল না করেই একটি মান রিটার্ন করে। একটি রিকার্সিভ কেস ফাংশনটিকে আবার কল করে, আর ইনপুটটি এমনভাবে বদলে দেয় যে একসময় তা বেস কেসের সাথে মিলে যাবে।

খুব বেশি ক্ষেত্রেই প্রতিটি কেস আলাদা ফাংশন ক্লজে লেখা হয়।

# base case
def count([]), do: 0

# recursive case
def count([_head | tail]), do: 1 + count(tail)

একটি রিকার্সিভ ফাংশনে অনেকগুলো বেস কেস এবং/অথবা অনেকগুলো রিকার্সিভ কেস থাকতে পারে। যেমন ফিবোনাচি সংখ্যাক্রম হলো একটি রিকার্সিভ সংখ্যাক্রম, যাতে দুটি বেস কেস আছে:

def fibonacci(0), do: 0
def fibonacci(1), do: 1
def fibonacci(n), do: fibonacci(n - 1) + fibonacci(n - 2)

কোনো অ্যারেতে একটি নির্দিষ্ট মান x কতবার আছে তা গণনা করার জন্য দুটি রিকার্সিভ কেস লাগে:

def count_occurrences([], _x), do: 0
def count_occurrences([x | tail], x), do: 1 + count_occurrences(tail, x)
def count_occurrences([_ | tail], x), do: count_occurrences(tail, x)

রিকার্সনের মাধ্যমে লুপ

ইমিউটেবিলিটির কারণে Elixir-এ লুপগুলো ইম্পারেটিভ ভাষার থেকে ভিন্নভাবে লেখা হয়। যেমন, সাধারণত লুপ দেখতে এমন হয়:

for(i = 0; i < array.size; i++) {
  # do something with array[i]
}

ফাংশনাল ভাষায় i-কে মিউটেট করা (i++ কল করে) সম্ভব নয়। তাই লুপগুলো রিকার্সন দিয়ে ইমপ্লিমেন্ট করতে হয়।

Elixir-এ একটি for লুপের সমতুল্য রূপ দেখতে এমন হবে:

def loop([]), do: nil

def loop([head | tail]) do
  do_something(head)
  loop(tail)
end

বাস্তবে অ্যারে বা অন্য এনিউমারেবল ডেটা স্ট্রাকচারের উপর ইটারেশন বেশিরভাগ ক্ষেত্রেই Enum মডিউল দিয়ে করা হয়। আসলে ভেতরে ভেতরে, Enum মডিউলের ফাংশনগুলো রিকার্সন ব্যবহার করে ইমপ্লিমেন্ট করা হয়েছে।

অসীম এক্সিকিউশন

রিকার্সিভ ফাংশন ভুলভাবে ইমপ্লিমেন্ট করলে হয়তো কখনোই তাদের ফলাফল রিটার্ন নাও করতে পারে। এটি সমস্যার হতে পারে, কারণ প্রতিবার একটি ফাংশন কল করলে VM-এর ফলাফল রিটার্ন করার জায়গায় (কল স্ট্যাকে) মেমরিতে একটি রেফারেন্স জমা হয়। একটি রিকার্সিভ ফাংশন যদি অসীমভাবে নিজেকে কল করতে থাকে, তবে মেমরি শেষ হয়ে VM ক্র্যাশ করতে পারে (স্ট্যাক ওভারফ্লো এরর)। Erlang VM, যার উপর Elixir চলে, রিকার্সন ও নির্ভরযোগ্যতার জন্য বিশেষভাবে অপ্টিমাইজ করা। তাই অসীম রিকার্সনের এরর ধরা পড়তে বা ক্র্যাশ হতে অনেক সময় লেগে যেতে পারে।

অসীম এক্সিকিউশনের এই সমস্যাটি এই কারণে হতে পারে:

  • বেস কেস ইমপ্লিমেন্ট করতে ভুলে যাওয়া।
  • বেস কেসটিকে প্রথম ক্লজ হিসেবে ডিফাইন না করা।
  • রিকার্সিভ কল করার সময় আর্গুমেন্টটি ঠিকভাবে বদল না করা, আর তাই বেস কেসে কখনোই না পৌঁছানো।
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি নতুন একটি উইন্ডো বা ট্যাবে খুলবে

রিকার্সন শিখুন

অনুশীলন লক করা আছে

রিকার্সন অনুশীলন করতে আরও 10টি অনুশীলনী আনলক করুন