মূলত দুই ধরনের লুপ আছে:
দুটোই Julia-তে সম্ভব, যদিও দ্বিতীয়টি বেশি কমন হতে পারে।
while লুপযেসব খোলা সমস্যায় লুপটি কতবার ঘুরবে তা আগে থেকে জানা যায় না, সেগুলোর জন্য Julia-তে রয়েছে while লুপ।
এর মূল রূপটি বেশ সহজ:
while condition
do_something()
end
এক্ষেত্রে প্রোগ্রামটি লুপে ঘুরতেই থাকবে, যতক্ষণ না condition আর true থাকে না।
লুপ থেকে আগেভাগে বেরোনোর দুটি উপায় আছে:
break লুপটি শেষ করে দেয়, আর এক্সিকিউশন লুপের end-এর পরের লাইন থেকে চলতে থাকে।return x বর্তমান ফাংশনের এক্সিকিউশন থামিয়ে দেয় এবং রিটার্ন ভ্যালু x কল করা জায়গায় ফেরত পাঠায়।এই সুবিধাগুলো থাকলে মাঝে মাঝে while true ... end দিয়ে একটি "অসীম" লুপ বানিয়ে, এরপর লুপ বডির ভেতরে থামার শর্ত খুঁজে পেয়ে break বা return ডাকা সুবিধাজনক হতে পারে।
সবচেয়ে সহজ উদাহরণ হলো একটি রেঞ্জের উপর লুপ করা।
যদি আমরা কোনো কাজ ১০ বার করতে চাই:
for n in 1:10
do_something(n)
end
যদি বর্তমান ইটারেশন কোনো শর্ত পূরণ না করে, তাহলে continue দিয়ে সঙ্গে সঙ্গে পরের ইটারেশনে চলে যাওয়া যায়:
for n in 1:10
if is_useless(n)
continue
end
# we decided this iteration could be useful
do_something_slow(n)
end
আরও ছোট রূপে, if ব্লকটির বদলে is_useless(n) && continue লেখা যায়।
আরও অনেক ধরনের কালেকশনের উপর লুপ চালানো যায়: অ্যারের এলিমেন্ট, স্ট্রিংয়ের ক্যারেক্টার, ডিকশনারির কী (key)...
শর্ত হলো, কালেকশনটি iterable হতে হবে।
এটি পরের কোনো কনসেপ্টে আরও বিস্তারিত ব্যাখ্যা করা হবে, তবে মূল কথা হলো, কালেকশনের কাছে চাওয়া হলে পরের আইটেমটি দিয়ে দেওয়ার একটি উপায় থাকতে হবে, সঙ্গে আরও একটি উপায় থাকতে হবে যা বোঝায় যে শেষ এসে গেছে এবং আর কোনো আইটেম নেই।
এখন পর্যন্ত উদাহরণগুলো 1:10 রেঞ্জের উপর লুপ করেছে, যেখানে মানটিই আবার লুপ ইনডেক্স।
আরও সাধারণভাবে, কেবল মান নয়, ইনডেক্সও দরকার হতে পারে।
এর জন্য eachindex() ফাংশনটি ব্যবহার করা হয়, যেমন for i in eachindex(my_array) ... end।
অনেক প্রচলিত ভাষার তুলনায় Julia-তে সরাসরি লুপ লেখা তুলনামূলক কম দেখা যায়, কারণ এখানে আরও সংক্ষিপ্ত নানা উপায় আছে।
বিশেষত কমন একটি পরিস্থিতি হলো, যখন অন্য কোনো কালেকশনের (ভেক্টর, স্ট্রিং, সেট ... সম্ভাবনা অনেক) এলিমেন্ট থেকে নতুন একটি ভেক্টর বানাতে হয়।
আপনি যদি Python-এ লিস্ট কম্প্রিহেনশন পছন্দ করেন, তাহলে জেনে খুশি হবেন যে Julia-তেও একই ধরনের সিনট্যাক্স ব্যবহার করা যায়।
এর মূল কথা হলো, একটি ভেক্টরের ভেতরে খুব সংক্ষিপ্ত একটি লুপ তৈরি করা।
সবচেয়ে সহজ সিনট্যাক্সটি হলো result = [f(x) for x in some_collection] ধরনের।
প্রচলিত লুপ দিয়ে এটি এভাবে লেখা যেত:
result = []
for x in some_collection
push!(result, f(x))
end
চাইলে শেষে একটি শর্ত যোগ করা যায়, যাতে কালেকশনের কেবল শর্ত মেলা এলিমেন্টগুলোই বাছাই করা হয়:
# multiples of 3
julia> [n^2 for n in 1:10 if n%3 == 0]
3-element Vector{Int64}:
9
36
81
# letters beyond 'h' in the alphabet
julia> [uppercase(c) for c in "Julia" if c > 'h']
3-element Vector{Char}:
'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
'I': ASCII/Unicode U+0049 (category Lu: Letter, uppercase)
সিনট্যাক্সটি Python-এর সঙ্গে একই রকম, তবে অভিন্ন নয়। একাধিক ভ্যারিয়েবল এবং/অথবা বহুমাত্রিক অ্যারের ক্ষেত্রে কিছুটা পার্থক্য আছে, তাই এই বিষয়টি পরের কোনো কনসেপ্টে আরও বিস্তারিত আলোচনা করা হবে।
আধুনিক ও বেশিরভাগ ক্ষেত্রে ফাংশনাল একটি প্রোগ্রামিং ভাষা হিসেবে Julia-তে (অবশ্যই) কালেকশনের উপর কাজ করার নানা উপায় আছে, শুধু সরাসরি লুপ বা কম্প্রিহেনশনের ভেতরে সংক্ষিপ্ত করা লুপ নয়।
পরের কনসেপ্টগুলোতে ব্রডকাস্টিং আর হায়ার-অর্ডার ফাংশনের মতো বিকল্প নিয়ে আলোচনা করা হবে।