Generic Programming হলো এমন একটি প্রোগ্রামিং প্যারাডাইম যেখানে কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা বাড়ানোর জন্য টাইপ-নির্ভর অপারেশন বা ডেটা স্ট্রাকচার তৈরি করা হয়। এটি সাধারণত generic types বা type parameters ব্যবহার করে কাজ করে, যা ফাংশন বা ক্লাসকে বিভিন্ন ধরনের ডেটা টাইপের সাথে কাজ করার সুযোগ দেয়।
স্কালাতে generic programming এর সাহায্যে আপনি কোডের অধিকাংশ অংশকে এমনভাবে লিখতে পারেন যা টাইপ সুনির্দিষ্ট না হয়ে, বিভিন্ন টাইপের সাথে কাজ করতে সক্ষম হয়। এর ফলে কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা বৃদ্ধি পায়।
Type Parameters এর ধারণা
Type Parameters হলো এমন প্যারামিটারস যা একটি ক্লাস, ট্রেইট বা ফাংশনে টাইপ হিসেবে ব্যবহৃত হয়। এগুলি এক ধরনের প্যারামিটার যা টাইপ সিস্টেম (Type System) এর জন্য কাজ করে। যখন কোনো ক্লাস বা ফাংশন টাইপ প্যারামিটার নেয়, তখন এটি একাধিক টাইপের সাথে কাজ করতে সক্ষম হয়। এটি ফাংশনাল প্রোগ্রামিংয়ে খুবই শক্তিশালী একটি বৈশিষ্ট্য, কারণ আপনি একাধিক টাইপের জন্য একটি একক ইমপ্লিমেন্টেশন তৈরি করতে পারেন।
Generic Types বা Type Parameters ব্যবহার করা
স্কালাতে, টাইপ প্যারামিটার ব্যবহার করতে হয় [T] এর মতো সিঙ্গুলার টাইপ প্যারামিটার দ্বারা, যেখানে T হলো টাইপ প্যারামিটার যা ক্লাস বা ফাংশন দ্বারা পরিচালিত হবে।
উদাহরণ: Generic Class
// Generic class with type parameter T
class Box[T](value: T) {
def getValue: T = value
}
// Creating instances of Box with different types
val intBox = new Box(intBox.getValue) // Output: 42
val stringBox = new Box[String]("Hello, Scala!")
println(stringBox.getValue) // Output: Hello, Scala!এখানে, Box একটি generic class যার মধ্যে type parameter T ব্যবহার করা হয়েছে। আপনি বিভিন্ন টাইপের ডেটা (যেমন Int, String) দিয়ে একই ক্লাসের ইনস্ট্যান্স তৈরি করতে পারবেন।
Generic Functions
ফাংশনেও টাইপ প্যারামিটার ব্যবহার করা যায়। এর মাধ্যমে একটি ফাংশন একাধিক টাইপের সাথে কাজ করতে সক্ষম হয়। স্কালাতে, টাইপ প্যারামিটার এমনভাবে ব্যবহার করা যায় যেন একই ফাংশন বিভিন্ন টাইপের আর্গুমেন্ট গ্রহণ করতে পারে।
উদাহরণ: Generic Function
// A generic function that works with any type T
def printValue[T](value: T): Unit = {
println(value)
}
printValue(42) // Output: 42
printValue("Hello, World!") // Output: Hello, World!এখানে, printValue একটি generic function যেটি T টাইপের প্যারামিটার নেয়। এটি যেকোনো ধরনের ডেটা (যেমন Int, String) প্রিন্ট করতে পারে।
Multiple Type Parameters
একাধিক টাইপ প্যারামিটারও ব্যবহার করা যায়। এটি অনেক বেশি নমনীয়তা প্রদান করে, কারণ আপনি একাধিক ডেটা টাইপের জন্য কাজ করতে পারেন।
উদাহরণ: Multiple Type Parameters
// A generic class with two type parameters
class Pair[A, B](val first: A, val second: B) {
def getFirst: A = first
def getSecond: B = second
}
// Creating an instance of Pair with different types
val pair = new Pair[Int, String](42, "Scala")
println(pair.getFirst) // Output: 42
println(pair.getSecond) // Output: Scalaএখানে, Pair ক্লাসে দুটি টাইপ প্যারামিটার (A এবং B) ব্যবহার করা হয়েছে, যার মাধ্যমে একই ক্লাসের মধ্যে বিভিন্ন ধরনের ডেটা (যেমন Int এবং String) রাখতে সক্ষম হয়েছি।
Upper Bound and Lower Bound with Type Parameters
স্কালাতে টাইপ প্যারামিটারদের জন্য upper bounds এবং lower bounds নির্ধারণ করা যেতে পারে, যা ক্লাস বা ফাংশনের টাইপ প্যারামিটার কী ধরনের টাইপ হতে পারে তা নির্ধারণ করে।
- Upper Bound: এটি একটি টাইপ প্যারামিটারের সর্বোচ্চ টাইপের সীমা নির্ধারণ করে। অর্থাৎ, টাইপ প্যারামিটারটি ঐ টাইপ বা তার সাবক্লাস হতে পারে।
- Lower Bound: এটি টাইপ প্যারামিটারের সর্বনিম্ন টাইপের সীমা নির্ধারণ করে, অর্থাৎ টাইপ প্যারামিটারটি ঐ টাইপ বা তার সুপারক্লাস হতে পারে।
উদাহরণ: Upper Bound
// A function with an upper bound type parameter
def printNumbers[T <: Number](value: T): Unit = {
println(value)
}
printNumbers(42) // Output: 42
printNumbers(3.14) // Output: 3.14এখানে, T <: Number দ্বারা upper bound নির্ধারণ করা হয়েছে, অর্থাৎ T টাইপটি Number ক্লাস বা তার সাবক্লাস হতে হবে।
উদাহরণ: Lower Bound
// A function with a lower bound type parameter
def add[T >: Int](value: T): Unit = {
println(value)
}
add(42) // Output: 42
add(3.14) // Output: 3.14এখানে, T >: Int দ্বারা lower bound নির্ধারণ করা হয়েছে, অর্থাৎ T টাইপটি Int বা তার সুপারক্লাস হতে হবে।
Type Classes
স্কালাতে type classes একটি শক্তিশালী কনসেপ্ট, যা বিভিন্ন টাইপের জন্য নির্দিষ্ট আচরণ সংজ্ঞায়িত করতে ব্যবহৃত হয়। এটি generic programming এর আরও উন্নত ধারণা হিসেবে কাজ করে।
উদাহরণ: Type Class
// A type class for printable types
trait Printable[T] {
def print(value: T): Unit
}
object PrintableInstances {
implicit val intPrintable: Printable[Int] = new Printable[Int] {
def print(value: Int): Unit = println(s"Int: $value")
}
implicit val stringPrintable: Printable[String] = new Printable[String] {
def print(value: String): Unit = println(s"String: $value")
}
}
// A generic function to print values using the type class
def printValue[T](value: T)(implicit printable: Printable[T]): Unit = {
printable.print(value)
}
printValue(42) // Output: Int: 42
printValue("Scala") // Output: String: Scalaএখানে, Printable একটি type class তৈরি করা হয়েছে, যা Int এবং String টাইপের জন্য implicit instances প্রদান করেছে। printValue ফাংশনটি এই টাইপ ক্লাসকে ব্যবহার করে বিভিন্ন টাইপের জন্য print ফাংশন কল করতে সক্ষম হয়েছে।
সারাংশ
- Generic Programming হলো এমন একটি প্রোগ্রামিং প্যাটার্ন, যা টাইপ প্যারামিটার বা জেনেরিক টাইপ ব্যবহার করে কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা বৃদ্ধি করে।
- Type Parameters একটি ক্লাস বা ফাংশনে টাইপ প্যারামিটার ব্যবহার করে বিভিন্ন টাইপের সাথে কাজ করার সুযোগ দেয়।
- Upper Bound এবং Lower Bound টাইপ প্যারামিটারের জন্য সীমা নির্ধারণ করে, যা তাদের টাইপ সিস্টেমকে আরও নির্দিষ্ট এবং নিরাপদ করে তোলে।
- Type Classes জেনেরিক প্রোগ্রামিংয়ের উন্নত কনসেপ্ট, যা টাইপের উপর নির্দিষ্ট আচরণ বা ফাংশনালিটি প্রয়োগ করতে ব্যবহৃত হয়।
এভাবে, স্কালায় generic programming এর মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, নিরাপত্তা এবং নমনীয়তা বৃদ্ধি করা সম্ভব।
Read more