এই উত্তরের উদ্দেশ্যগুলির জন্য আমি একটি কার্যকরী ভাষা বোঝাতে "বিশুদ্ধভাবে কার্যকরী ভাষা" সংজ্ঞায়িত করি যেখানে ফাংশনগুলি উল্লেখযোগ্যভাবে স্বচ্ছ হয়, অর্থাত্ একই যুক্তিকে একাধিকবার একই আর্গুমেন্টের সাথে কল করা সর্বদা একই ফলাফল তৈরি করে। এটি, আমি বিশ্বাস করি, খাঁটি কার্যকরী ভাষার স্বাভাবিক সংজ্ঞা।
খাঁটি ফাংশনাল প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি পার্শ্ব প্রতিক্রিয়াগুলিকে অনুমতি দেয় না (এবং তাই অনুশীলনে খুব কম ব্যবহার হয় কারণ কোনও কার্যকর প্রোগ্রামের পার্শ্ব প্রতিক্রিয়া যেমন, যখন এটি বাহ্যিক বিশ্বের সাথে যোগাযোগ করে))
রেফারেন্সিয়াল স্বচ্ছতা অর্জনের সবচেয়ে সহজ উপায় হ'ল পার্শ্ব প্রতিক্রিয়াগুলি অস্বীকার করা এবং প্রকৃতপক্ষে এমন ভাষাগুলি রয়েছে যা ক্ষেত্রে এটি (বেশিরভাগ ডোমেন সুনির্দিষ্ট)। তবে এটি অবশ্যই একমাত্র উপায় নয় এবং সর্বাধিক সাধারণ উদ্দেশ্য খাঁটি কার্যকরী ভাষাগুলি (হাস্কেল, ক্লিন, ...) পার্শ্ব প্রতিক্রিয়াটিকে মঞ্জুরি দেয়।
পার্শ্ব প্রতিক্রিয়াবিহীন একটি প্রোগ্রামিং ভাষা অনুশীলনে খুব কম ব্যবহার করা আমার পক্ষে মনে হয় - অবশ্যই ডোমেন নির্দিষ্ট ভাষার জন্য নয়, এমনকি সাধারণ উদ্দেশ্যে ব্যবহৃত ভাষাগুলির জন্যও আমি ভাবতে পারি যে কোনও ভাষা পার্শ্ব প্রতিক্রিয়া সরবরাহ না করে বেশ কার্যকর হতে পারে । সম্ভবত কনসোল অ্যাপ্লিকেশনগুলির জন্য নয়, তবে আমি মনে করি জিইউআই অ্যাপ্লিকেশনগুলি কার্যকরভাবে প্রতিক্রিয়াশীল দৃষ্টান্ত হিসাবে পার্শ্ব-প্রতিক্রিয়া ছাড়াই সুন্দরভাবে প্রয়োগ করা যেতে পারে।
পয়েন্ট ১ সম্পর্কিত, আপনি পরিবেশের সাথে নিখুঁত ক্রিয়ামূলক ভাষায় যোগাযোগ করতে পারেন তবে আপনাকে তাদের কোড (ফাংশন) স্পষ্টভাবে চিহ্নিত করতে হবে যা তাদের পরিচয় করিয়ে দেয় (উদাহরণস্বরূপ মনডিক ধরণের মাধ্যমে হাস্কেল)।
এটি সহজ করার চেয়ে কিছুটা বেশি। পার্শ্ব-কার্যকারী ফাংশনগুলি যেমন চিহ্নিত করা দরকার কেবল এমন একটি সিস্টেম থাকা (সি ++ তে কনস্ট-যথার্থতার অনুরূপ, তবে সাধারণ পার্শ্ব-প্রতিক্রিয়া সহ) উল্লেখযোগ্য স্বচ্ছতা নিশ্চিত করতে যথেষ্ট নয়। আপনাকে অবশ্যই নিশ্চিত করতে হবে যে কোনও প্রোগ্রাম একই আর্গুমেন্টের মাধ্যমে কোনও ফাংশনকে একাধিকবার কল করতে পারে না এবং বিভিন্ন ফলাফল পেতে পারে। আপনি হয় মত জিনিস তৈরি করে তা করতে পারেreadLineএমন কোনও কিছু হোন যা কোনও ফাংশন নয় (এটি হ্যাস্কেল আইও মোনাডের সাথে কি করে) বা আপনি একই যুক্তি দিয়ে একাধিকবার পার্শ্ব-কার্যকারী ফাংশন কল করা অসম্ভব করে তুলতে পারেন (এটি ক্লিন যা করে)) পরবর্তী ক্ষেত্রে সংকলকটি নিশ্চিত করবে যে প্রতিবার আপনি কোনও পার্শ্ব-প্রভাবকারী ফাংশনটি কল করার সময় আপনি এটি একটি নতুন যুক্তি দিয়ে করবেন এবং এটি এমন কোনও প্রোগ্রামকে প্রত্যাখ্যান করবে যেখানে আপনি একই যুক্তিটি দুবার পার্শ্ব-কার্যকারী ফাংশনে পাস করবেন।
খাঁটি ফাংশনাল প্রোগ্রামিং ল্যাঙ্গুয়েজ এমন কোনও প্রোগ্রাম লিখতে দেয় না যা রাষ্ট্র বজায় রাখে (যা প্রোগ্রামিংকে খুব বিশ্রী করে তোলে কারণ অনেক অ্যাপ্লিকেশনে আপনাকে রাষ্ট্রের প্রয়োজন হয়)।
আবার, একটি নিখুঁত কার্যকরী ভাষা খুব ভাল পরিবর্তনযোগ্য রাষ্ট্রকে অস্বীকার করতে পারে তবে আপনি যদি এটি উপরের পার্শ্ব প্রতিক্রিয়াগুলির সাথে বর্ণনা করে ঠিক একইভাবে প্রয়োগ করেন তবে খাঁটি হওয়া এবং এখনও পরিবর্তনীয় স্থিতি থাকা সম্ভব। সত্যিই পরিবর্তনীয় অবস্থা পার্শ্ব-প্রতিক্রিয়াগুলির অন্য একটি রূপ।
এটি বলেছিল, কার্যকরী প্রোগ্রামিং ভাষা অবশ্যই স্পষ্টত পরিবর্তনযোগ্য অবস্থাটিকে নিরুৎসাহিত করে - বিশেষত খাঁটি ভাষা। এবং আমি মনে করি না যে এটি প্রোগ্রামিংকে বিশ্রী করে তোলে - একেবারে বিপরীত। কখনও কখনও (তবে প্রায়শই সব কিছু হয় না) পারফরম্যান্স বা স্পষ্টতা হারানো ছাড়াই (পরিবর্তনশীল অবস্থা) এড়ানো যায় না (এ কারণেই হাস্কেলের মতো ভাষাগুলিতে পার্সোনাল রাষ্ট্রের জন্য সুবিধা রয়েছে), তবে বেশিরভাগ ক্ষেত্রেই এটি হতে পারে।
এগুলি যদি ভুল ধারণা হয় তবে তারা কীভাবে এলো?
আমি মনে করি অনেক লোক কেবল "একই যুক্তি দিয়ে ডাকা হলে একটি ফাংশন অবশ্যই একই ফলাফল আনতে পারে" পড়েন এবং এ থেকে এই সিদ্ধান্তে পৌঁছান readLineযে পরিবর্তনীয় অবস্থা বজায় রাখার মতো এমন কিছু বা কোড প্রয়োগ করা সম্ভব নয় । সুতরাং তারা "চিট" সম্পর্কে সহজেই অবগত নন যে খাঁটি কার্যকরী ভাষাগুলি প্রাসঙ্গিক স্বচ্ছতা ভঙ্গ না করে এই জিনিসগুলি প্রবর্তন করতে ব্যবহার করতে পারে।
পরিবর্তনীয় স্থিতিটি কার্যকরী ভাষাগুলিতে ব্যাপকভাবে নিরুৎসাহিত হয়, তাই এটি খাঁটি কার্যকরী ভাষায় একেবারেই অনুমোদিত নয় বলে ধরে নেওয়া খুব একটা লাফিয়ে যায় না।
(1) পার্শ্ব প্রতিক্রিয়াগুলি প্রয়োগ করতে এবং (2) রাষ্ট্রের সাথে একটি গণনা বাস্তবায়ন করার জন্য হাস্কেল ইডিয়োমেটিক পদ্ধতিতে চিত্রিত একটি (সম্ভবত ছোট) কোড স্নিপেট লিখতে পারেন?
সিউডো-হাস্কেল-এ এখানে একটি আবেদন রয়েছে যা ব্যবহারকারীকে একটি নাম জিজ্ঞাসা করে এবং তাকে অভ্যর্থনা জানায়। সিউডো-হাস্কেল হ'ল এমন একটি ভাষা যা আমি সবেমাত্র আবিষ্কার করেছি, যার হাস্কেলের আইও সিস্টেম রয়েছে, তবে এটি প্রচলিত বাক্য গঠন, আরও বর্ণনামূলক ফাংশন নাম ব্যবহার করে এবং কোনও doনোটেশন নেই (এটি কেবল আইও মনাদ কীভাবে কাজ করে তা থেকে বিভ্রান্ত করবে):
greet(name) = print("Hello, " ++ name ++ "!")
main = composeMonad(readLine, greet)
এখানে ক্লুটি হ'ল এটি readLineটাইপের মান IO<String>এবং composeMonadএটি এমন একটি ফাংশন যা টাইপের একটি আর্গুমেন্ট গ্রহণ করে IO<T>(কিছু প্রকারের জন্য T) এবং অন্য একটি যুক্তি যা একটি ফাংশন যা টাইপের একটি আর্গুমেন্ট গ্রহণ করে Tএবং টাইপের মান IO<U>(কোনও প্রকারের জন্য U) প্রদান করে। printএকটি ফাংশন যা একটি স্ট্রিং নেয় এবং টাইপের মান প্রদান করে IO<void>।
প্রকারের মান IO<A>হ'ল একটি মান যা প্রদত্ত ক্রিয়াকে "এনকোড করে" দেয় যা প্রকারের মান উৎপন্ন করে A। composeMonad(m, f)একটি নতুন IOমান উত্পাদন করে যা ক্রিয়াকে mঅনুসরণ করে এর ক্রিয়াকে এনকোড করে f(x), যেখানে xক্রিয়া সম্পাদন করে মানটি উত্পাদন করে m।
পরিবর্তনীয় স্থিতিটি এমন দেখাচ্ছে:
counter = mutableVariable(0)
increaseCounter(cnt) =
setIncreasedValue(oldValue) = setValue(cnt, oldValue + 1)
composeMonad(getValue(cnt), setIncreasedValue)
printCounter(cnt) = composeMonad( getValue(cnt), print )
main = composeVoidMonad( increaseCounter(counter), printCounter(counter) )
এখানে mutableVariableএকটি ফাংশন যা কোনও ধরণের মান নেয় Tএবং একটি উত্পাদন করে MutableVariable<T>। ফাংশন getValueএমনটি গ্রহণ করে যা তার বর্তমান মান উত্পাদন করে MutableVariablereturns লাগে এবং একটি এবং আয় একটি যে মান সেট করে। হিসাবে একই ছাড়া প্রথম আর্গুমেন্ট একটি হল যে একটি যুক্তিসম্মত মান এবং দ্বিতীয় যুক্তি হতে পারে না অন্য একসংখ্যা, না একটি ফাংশন যা রিটার্ন একটি একসংখ্যা হয়।IO<T>setValueMutableVariable<T>TIO<void>composeVoidMonadcomposeMonadIO
হাস্কেলের মধ্যে এমন কিছু সিনট্যাকটিক চিনি রয়েছে যা পুরো পুরো অগ্নিপরীক্ষাকে কম বেদনাদায়ক করে তোলে তবে এটি এখনও স্পষ্ট যে পরিবর্তনীয় অবস্থা এমন একটি ভাষা যা ভাষা আপনাকে সত্যিই করতে চায় না।