হাতে খড়ি

Last updated 3 months ago

চলুন তাহলে স্ক্যালা-তে কোড করা শুরু করা যাক। প্রথমত আমরা স্ক্যালা ইন্টাপ্রেটার দিয়ে শুরু করবো। আমরা দেখবো স্ক্যালা ইন্টারপ্রেটার কিভাবে ইন্ডাস্ট্রি-স্ট্যান্ডার্ড পকেট ক্যালকুলেটর এর মতো কাজ করে।

এর জন্যে প্রথমত আমাদের স্ক্যালা ইনভাইরনমেন্ট সেটাপ করতে হবে। এর জন্যে আমাদের যা যা লাগবে তা হলো-

  • Java – Java Development Kit ইনস্টলেশান

  • স্ক্যালা ইনস্টলেশান

জাভা ইনস্টল করতে হলে আমাদের প্রথমে জাভা ডাউনলোড করতে হবে।

আমি ঠিক করেছি এই পুরো টিউটোরিয়াল গুলো লিনাক্স মেশিন ব্যবহার করে করবো (এর পেছনের কারণ, আমার মেশিনে একমাত্র ওএস লিনাক্স)। সুতরাং আপনার মেশিনে যদি লিনাক্স থাকে তাহলে খুবই চমৎকার, না থাকলে লিনাক্স ইনস্টল করে নেওয়া ভাল আইডিয়া, অথবা ভার্চুয়াল বক্স দিয়েও কাজ চলে যাবে।

জাভা ইনস্টলেশান-

জাভা ইনস্টল করতে নিচের ধাপ গুলো apply করতে হবে-

ধাপ ১: নিচের লিংক থেকে জাভা ডাউনলোড করে নিন।

Oracle JDK 7 Download Link

ধাপ ২: এরপর টার্মিনাল থেকে যেখানে জাভা ডাউনলোড হয়েছে সেখানে যান-

cd ~/Download

ধাপ ৩: এবার JDK ইনস্টল করি-

sudo tar -xzvf jdk-7u21-linux-i586.tar.gz --directory=/usr/local/
sudo ln -s /usr/local/[jdk_folder_name]/ /usr/local/jdk

jdk_folder_name - আপনার পছন্দমত একটি নাম দিন।

ধাপ ৪: আবার টার্মিনালে ফিরে যান- .bashrc অপেন করুন।

sudo gedit .bashrc

ধাপ ৫ : .bashrc ফাইল-এ নিচের লাইনটি এড করুন।

export JAVA_HOME=/usr/local/jdk

Save and close .bashrc file.

ধাপ ৬: কম্পাইল .bashrc ফাইল

source .bashrc

ধাপ ৭: এবার পরিক্ষা করে দেখা যাক জাভা ইনস্টল হয়েছে কিনা। আবার টার্মিনাল ওপেন করুন এবং নিচের লাইনটি টাইপ করুন।

java -version

যদি সবকিছু ঠিকঠাক থাকে তাহলে আপনি নিচের তথ্য গুলো দেখতে পারবেন-

java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

Scala installation

কমান্ড লাইন থেকে Scala চালানোর জন্য, নিচের লিংক থেকে বাইনারিটি ডাউনলোড করুন এবং আর্কাইভটি /usr/local/scala ফোল্ডার-এ আনপ্যাক করুন।

http://www.scala-lang.org/download/

এবার টার্মিনালে যান- .bashrc অপেন করুন।

sudo gedit .bashrc

এবং নিচের লাইন গুলো .bashrc ফাইল এ এড করুন।

export SCALA_HOME=/usr/local/scala-2.11.2/bin
export PATH=$PATH:$SCALA_HOME

সবকিছু ঠিকঠাক থাকলে চলুন এবার টার্মিনালে ফিরে যাই।

টাইপ scala এবং প্রেস ইন্টার।

:~$ scala
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala>

এরপর লিখুন 8*9. আপনি সাথে সাথেই উত্তর পেয়ে যাবেন। উদাহরণ-

scala> 8*9
res0: Int = 72

একটি মজার বিষয় লক্ষ্য করুন, আপনার উত্তরটি res0 ভ্যারিয়বল এ স্টোর হয়েছে। আপনি চাইলে এটি অন্য যায়গায় ব্যবহার করতে পারবেন। উদাহরণ-

scala> res0 * 5
res1: Int = 360

চলুন অন্য কিছু চেষ্টা করে দেখি।

scala> "Hello, " + res1
res2: String = Hello, 360

আপনি লক্ষ্য করুন, ইন্টারপ্রেটারটি উত্তরটির সাথে এর টাইপ ইনফরমেশান-ও পদর্শন করে ।

আপনি চাইলে এখানে কোন মেথড ও কল করতে পারেন।

scala> res2.toUpperCase
res4: String = HELLO, 360
scala> res2.toCharArray
res5: Array[Char] = Array(H, e, l, l, o, ,, , 3, 6, 0)
scala> res2.toLowerCase
res6: String = hello, 360

সুতরাং দেখা যাচ্ছে যে স্ক্যালা ইন্টারপ্রেটার প্রথমে একটি এক্সপ্রেশান পড়ে, তারপর এটিকে Evaluate করে , প্রিন্ট করে এবং এক্সপ্রেশান পড়ে। একে বলে - read-eval-print lool সংক্ষেপে REPL.

টেকনিক্যালি স্ক্যালা প্রোগ্রাম মোটেও ইন্টারপ্রেটার নয়। কারণ এর পেছনের দৃশ্য অন্যরকম। এটি দ্রুত আপনার ইনপুট কে কম্পাইল করে বাইট কোড রূপান্তরিত করে এবং যা জাভা ভার্চুয়াল মেশিন দ্বারা এক্সিকউট হয়। সুতরাং খুব দ্রুত কিছু করতে হলে REPL হচ্ছে আপনার চমৎকার বন্ধু।

Declaring variables

res0 , res1 পরিবর্তে আমরা আমাদের নিজেদের পছন্দমত ভ্যারিয়েবল ব্যবহার করতে পারি।

scala> val answer = 5* 99
answer: Int = 495

লক্ষ্য করুন, আপনাকে ভ্যারিয়বলের টাইপ বলে দিতে হচ্ছে না। স্ক্যালা নিজে নিজেই টাইপ বুঝে নিতে পারে। এটিকে বলে Type Inference। তবে আপনি চাইলে টাইপ বলে দিতে পারেন, এতে স্ক্যালা কোন আপত্তি করবে না।

scala> val hello:String = "Hello, world"
hello: String = Hello, world

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

স্ক্যালাতে ভ্যারিয়্যবল ডিক্ল্যেয়ার করার জন্যে দুই ধরণের Keyword ব্যবহার কর হয়- val এবং var।

যে ভ্যারিয়বল গুলো val ব্যবহার করে ডিক্ল্যায়ার করা হয় সেগুলো মূলত কনস্ট্যান্ট, এর কনটেন্ট আর পরিবর্তন করা যাবে না। কিন্তু যে সব ভ্যারিয়েবল এর কনটেন্ট পরিবর্তনীয় সেগুলোর ক্ষেত্রে var ব্যবহার করা হয়।

কোন ভ্যারিয়েবল যদি val ব্যবহার করে ডিক্ল্যায়ার করা হয় এবং আমরা তা পরিবর্তন করতে চাই তাহলে সাথে সাথে ইন্টারপ্রেটার কম্পাইলার ইরর দেখাবে।

scala> val x = 9
x: Int = 9
scala> x =6
<console>:8: error: reassignment to val
x =6
^

আরেকটি মজার বিষয় লক্ষ্য করুন, আমরা কোন স্ট্যাটমেন্ট এর আগে সেমিকোলন ব্যবহার করি নি। স্ক্যালাতে সেমিকোলন বাধ্যতামূলক নয়। তবে যদি একি লাইন এ আমরা একাধিক স্ট্যাটমেন্ট ব্যবহার করি, তহালে সেমিকোল দিয়ে স্ট্যাটমেন্ট গুলোকে আলাদা করতে হবে।

ডাটা টাইপ

স্ক্যালাতে মূলত নিচের বিল্ট ইন ডাটাটাইপ গুলো ভ্যারিয়েবল হিসেবে ব্যবহার করা হয়।

Type

Value Space

Boolean

true or false

Byte

8 bit signed value

Short

16 bit signed value

Char

16 bit unsigned Unicode character

Int

32 bit signed value

Long

64 bit signed value

Float

32 bit IEEE 754 single-precision float

Double

64 bit IEEE 754 double-precision float

String

A sequence of characters

এবং স্ক্যালাতে সবগুলো ডাটা টাইপ অবজেক্ট্ এবং এতে জাভা এর মতো কোন প্রিমিটিভ ডাটা টাইপ নেই। এতে করে একটা মজার সুবিধে পাওয়া যাচ্ছে - আপনি সরা সরি এর মেথড গুলো কল করতে পারবেন। উদাহরণ-

scala> 1.toString
res7: String = 1
scala> 1.to(10)
res8: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

লক্ষ্য করুন, 1.toString লাইনে আমি পেরেন্থেসিস () ব্যবহার করি নি। কারণ স্ক্যালাতে এটি আবশ্যিক নয় ।

আমাদের যদি কোন Double নাম্বারকে Integer রূপান্তরিত করতে হয়, স্ক্যালাতে সি এর মতো কাস্টিং না করে আমরা toInt মেথড কল করা হয়।

scala> var a:Double = 9.6
a: Double = 9.6
scala> var b: Int = a.toInt
b: Int = 9

Arithmetic operation

স্ক্যালাতে এরিথমেটিক অপারেশন গুলো জাভা এবং সি++ এর মতই কাজ করে। যেমন-

val answer = 1 + 8 / 4

+ - / % & | ^ >> << এই অপারেটর গুলো মূলত তাদের ইউজ্যুয়াল কাজ গুলোই করে থাকে, তবে একটি অত্যন্ত মজার দৃষ্টিভঙ্গি আছে এখানে এবং সেটি হলো এগুলো মূলত মেথড। আপনি নিশ্চয় এটি শুনে আকাশ থেকে পরবেন। কিন্তু সত্যি হচ্ছে স্ক্যালা তে অন্যান্য ল্যাংগুয়েজ গুলোর মতো অর্থহীন কুসংস্কার নেই যে মেথড শুধুমাত্রই alphanumeric ই হতে হবে। আপনি যে কোন সিম্বল দিয়ে মেথড লিখতে পারেন।

a +b

মূলত

a.+(b)

এর শর্টহ্যান্ড।

নিচের উদাহরণটি লক্ষ্য করুন

class Calculator {
def doubleIt(a: Int) = a*a
}

এটি একটি ক্লাস এবং এতে একটি মেথড আছে। আমরা এই মেথডটি ব্যবহার করতে হলে আমাদের যা করতে হবে -

var calculator = new Calculator()
calculator.doubleIt(5)

উপরের মেথড কলটি আমরা চাইলে শর্টহ্যান্ড এ লিখতে পারি -

calculator doubleIt 5

চমৎকার। প্রথম শব্দটি হলো ইনসট্যন্স এবং পরেরটি মেথড এবং এর পরেরটি হলো আর্গুমেন্ট।

ফাংশান

চলুন এবার দেখি কিভাবে স্ক্যালাতে ফাংশন লেখা যায়।

scala> def max(x:Int, y:Int): Int ={
| if(x>y) x
| else y
| }
max: (x: Int, y: Int)Int
scala> max(9,5)
res9: Int = 9

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

ইন্টারপ্রেটার-এ যদি মাল্টিলাইন কোড লিখতে হয়, তাহলে আপনি ইন্টার চেপে যেতে থাকুন। আপনি যদি মনে করে থাকেন আপনি কিছু ভুল লিখে ফেলেছেন তাহলে পর পর দুইবার ইন্টার চাপুন, তাহলে ইন্টারপ্রেটার আপনাকে নতুন কমান্ড লেখার জন্যে কনসোল ফ্রি করে দেবে।

scala> val opps =
|
|
You typed two blank lines. Starting a new command.

ফাংশান এ ফিরে আসি।

স্ক্যালাতে ফাংশান শুরু হয় def কিওয়ার্ড দিয়ে। তারপর ফাংশান এর নাম। এর পর পেরেন্থেসিস এর মাঝে প্যারামিটার গুলো লিখতে হয়। প্যারামিটার গুলোতে টাইপ নোটেশান আবশ্যক কারণ স্ক্যালা কম্পাইলার মেথড এর টাইপ ইনফার করতে পারে না। এরপার ক্লােজড পেরেন্থেসিস এর পর একটি কোলন(:) দিয়ে পাশে টাইপ নোটেশান লিখতে হয় ।এটি হলো ফাংশানের রিটার্ন টাইপ। এরপর একটি সমান সমান চিহ্নের পর কার্লি ব্রেস এর মাঝে মেথড বডি লিখতে হয়।

ফাংশানটি আবার দেখি-

def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}

খেয়াল করুন, আমরা কোথাও return কিওয়ার্ড ব্যবহার করিনি। জাভাতে আমরা অনেকেই টার্রনারি অপারেটর ব্যবহার করি, এখানে ব্যাপরটি তাই। সাধরাণত কোন ফাংশান বডি এর লাস্ট লাইনটি রিটার্ন স্ট্যাটম্যন্ট হিসেবে বিবেচিত হয়। তবে আমরা চাইলে return কিওয়ার্ড করতে পারি, কিন্তু এটি আবশ্যক নয়।

def max(x: Int, y: Int): Int = {
if (x > y) return x
else return y
}

আরেকটি বিষয় লক্ষ্যনীয়, সেটি হলো আমরা চাইলে রিটার্ন টাইপ নাও লিখতে পারি, সে ক্ষেত্রে স্ক্যালা কম্পাইলার অটোম্যাটিক্যালি ইনফার করে নেবে। উদাহরণ-

def max(x: Int, y: Int) = {
if (x > y) x
else y
}

আমরা আরেকটি উদাহরণ দেখি-

scala> def greet() = println("hello world")
greet: ()Unit

আমরা এখানে একটি ফাংশান লিখেছি। ইন্টারপ্রেটার এর আউটপুটটি লক্ষ্যনীয়। এখানে greet অবশ্যই ফাংশানের নাম এবং Unit হচ্ছে রিটার্ন টাইপ। এটি মূলত জাভা এর void এর মতো কাজ করে। কোন ফাংশান যদি কোন কিছু রিটার্ন না করে , তাহলে সেটি Unit রিটার্ন করে।