ফাংশনাল প্রোগ্রামিংয়ে, স্থানীয় পার্শ্ব প্রতিক্রিয়াবিহীন স্থানীয় পরিবর্তনীয় পরিবর্তনগুলি এখনও "খারাপ অনুশীলন" হিসাবে বিবেচিত হয়?


23

কেবলমাত্র অভ্যন্তরীণভাবে ব্যবহৃত কোনও ফাংশনে (যেমন ফাংশনটির কোনও পার্শ্ব প্রতিক্রিয়া নেই, অন্তত ইচ্ছাকৃতভাবে নয়) এখনও পরিবর্তনযোগ্য স্থানীয় হিসাবে বিবেচিত হয়?

উদাহরণস্বরূপ "স্কলার সহ ফাংশনাল প্রোগ্রামিং" কোর্সের স্টাইল চেক কোনও varব্যবহারকে খারাপ হিসাবে বিবেচনা করে

আমার প্রশ্ন, যদি ফাংশনটির কোনও পার্শ্ব প্রতিক্রিয়া না থাকে, তবে কি আবশ্যক স্টাইল কোডটি লিখতে নিরুৎসাহিত করা হচ্ছে?

যেমন পরিবর্তে সঁচায়ক প্যাটার্ন সঙ্গে লেজ পুনরাবৃত্তির ব্যবহার, কি লুপ জন্য স্থানীয় করছেন এবং একটি তৈরি সঙ্গে ভুল স্থানীয় চপল ListBufferএবং চাইলে এটিকে সমৃদ্ধ, দীর্ঘ ইনপুট হিসাবে হিসাবে পরিবর্তিত হয়?

উত্তরটি যদি "হ্যাঁ, তারা সর্বদা নিরুৎসাহিত হয়, এমনকি কোনও পার্শ্ব প্রতিক্রিয়া নাও থাকে" তবে তার কারণ কী?


3
আমি যে বিষয়টি কখনও শুনেছি সে সম্পর্কে সমস্ত পরামর্শ, উপদেশ ইত্যাদি shared ভাগের পরিবর্তিত স্থিতিস্থলকে জটিলতার উত্স হিসাবে উল্লেখ করে। সেই কোর্সটি কি কেবলমাত্র প্রাথমিক শিক্ষাগুলি দ্বারা গ্রাস করা হবে? তাহলে এটি সম্ভবত একটি সু-উদ্দেশ্যমূলক ইচ্ছাকৃত ওভারসিম্প্লিফিকেশন।
কিলিয়ান ফট

3
@ কিলিয়ানফথ: বহু ভাগ্যযুক্ত প্রেক্ষাপটে ভাগ করা মিউটটেবল স্টেট একটি সমস্যা, তবে অংশীদারিত্বহীন মিউচ্যবাল স্ট্যাটগুলি প্রোগ্রামগুলির পক্ষেও যুক্তিযুক্ত হতে শক্ত হতে পারে।
মাইকেল শ

1
আমি মনে করি স্থানীয় পরিবর্তনীয় পরিবর্তনশীলটি ব্যবহার করা অগত্যা খারাপ অভ্যাস নয়, তবে এটি "কার্যকরী শৈলী" নয়: আমি মনে করি স্কালা কোর্সের উদ্দেশ্য (যা আমি শেষ পতনের সময় নিয়েছিলাম) আপনাকে কার্যকরী শৈলীতে প্রোগ্রামিং শেখানো to একবার আপনি কার্যকরভাবে এবং অপরিহার্য শৈলীর মধ্যে স্পষ্টভাবে আলাদা করতে পারলে আপনি কখন কোনটি ব্যবহার করবেন তা সিদ্ধান্ত নিতে পারেন (যদি আপনার প্রোগ্রামিং ভাষা উভয়কেই অনুমতি দেয়)। varসর্বদা অ-কার্যকরী হয়। স্কালায় অলস ভ্যালস এবং লেজ পুনরাবৃত্তি অপ্টিমাইজেশন রয়েছে, যা পুরোপুরি ভারগুলি এড়াতে দেয়।
জর্জিও

উত্তর:


17

এখানে যে বিষয়টিকে দ্ব্যর্থহীনভাবে খারাপ অভ্যাস বলে দাবি করা হচ্ছে তা যখন কিছু তখন না হয় তখন খাঁটি ফাংশন।

যদি পরিবর্তনীয় ভেরিয়েবলগুলি এমনভাবে ব্যবহার করা হয় যা সত্য এবং সম্পূর্ণ স্বয়ংসম্পূর্ণ থাকে তবে ফাংশনটি বাহ্যিকভাবে খাঁটি এবং সকলেই খুশি। প্রকৃতপক্ষে হাস্কেল এটিকে স্পষ্টভাবে সমর্থন করে, টাইপ সিস্টেম এমনকি এটি নিশ্চিত করে যে পরিবর্তনীয় রেফারেন্সগুলি তাদের তৈরি করা ফাংশনের বাইরে ব্যবহার করা যাবে না।

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


16

সমস্যা প্রতি সেচ পার্শ্বচরিত্রতা নয়, এটি রেফারেন্সিয়াল স্বচ্ছতার অভাব।

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

এর একটি উদাহরণ আমি ভাবতে পারি যেখানে খুব কার্যকরী কিছু করতে মিউটিয়েটেবলিটি ব্যবহার করতে হয়: স্মৃতিচারণ। মেমোয়েজেশন একটি ফাংশন থেকে মানগুলি ক্যাশে করছে, তাই তাদের পুনরায় সংশোধন করতে হবে না; এটি উল্লেখযোগ্যভাবে স্বচ্ছ, তবে এটি রূপান্তর ব্যবহার করে।

তবে সাধারণভাবে রেফারেনশিয়াল স্বচ্ছতা এবং অপরিবর্তনীয়তা একসাথে চলে যায়, একটি রেফারেন্সালি ট্রান্সফার ফাংশন এবং স্মৃতিচারণে স্থানীয় পরিবর্তনশীল পরিবর্তনশীল ব্যতীত, আমি নিশ্চিত নই যে যেখানে এমন ঘটনা নেই সেখানে অন্য কোনও উদাহরণ রয়েছে।


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

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

@ মিশেল শ: +1 এর জন্য "সমস্যাটি প্রতি সেচ পরিবর্তনের নয়, এটি উল্লেখযোগ্য স্বচ্ছতার অভাব।" হতে পারে আপনি পরিষ্কার ভাষাটি উল্লেখ করতে পারেন যেখানে আপনার স্বতন্ত্রতা রয়েছে: এগুলি পরিবর্তনের অনুমতি দেয় তবে এখনও উল্লেখযোগ্য স্বচ্ছতার গ্যারান্টি দেয়।
জর্জিও

@ জর্জিও: আমি ক্লিন সম্পর্কে সত্যই কিছু জানি না, যদিও আমি এটি সময়ে সময়ে উল্লেখ করেছি। এটি আমার উচিত ছিল।
মাইকেল শ

@ মিশেল শ: ক্লিন সম্পর্কে আমি খুব বেশি কিছু জানি না, তবে আমি জানি যে এটি প্রাসঙ্গিক স্বচ্ছতা নিশ্চিত করতে স্বতন্ত্রতা ব্যবহার করে। মূলত, আপনি একটি ডেটা অবজেক্টটি সংশোধন করতে পারেন প্রদত্ত পরিবর্তনের পরে আপনার পুরানো মানটির কোনও রেফারেন্স নেই। আইএমও এটি আপনার বিষয়টির চিত্র তুলে ধরে: রেফারেনশিয়াল স্বচ্ছতা হ'ল গুরুত্বপূর্ণ পয়েন্ট এবং অপরিবর্তনীয়তা এটির নিশ্চিত করার একমাত্র সম্ভাব্য উপায়।
জর্জিও

8

এটি "ভাল অনুশীলন" বনাম "খারাপ অনুশীলন" এ সিদ্ধ করা সত্যিই ভাল নয়। স্কেলা পরিবর্তনীয় মানগুলিকে সমর্থন করে কারণ তারা কিছু সমস্যা সমাধান করতে পারে অপরিবর্তনীয় মানগুলির চেয়ে অনেক ভাল, যথা প্রকৃতির পুনরাবৃত্তিযোগ্য।

দৃষ্টিকোণের জন্য, আমি মোটামুটি নিশ্চিত যে CanBuildFromস্কালার দ্বারা প্রদত্ত প্রায় সমস্ত অপরিবর্তনীয় কাঠামোর মাধ্যমে অভ্যন্তরীণভাবে কিছু প্রকারের পরিবর্তন ঘটায়। মুল বক্তব্যটি হ'ল তারা যা প্রকাশ করে তা স্থাবর। যতটা সম্ভব মান যথাযথভাবে অপরিবর্তনীয় রাখার ফলে প্রোগ্রামটি যুক্তিযুক্ত করতে আরও সহজ হয় এবং ত্রুটির প্রবণতা কম হয়

এর অর্থ এই নয় যে আপনার পরিবর্তিততার সাথে আরও উপযুক্ত উপযুক্ত এমন কোনও সমস্যা থাকলে আপনার অভ্যন্তরীণভাবে পরিবর্তনীয় কাঠামো এবং মানগুলি এড়ানো উচিত।

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


2
হ্যাঁ, স্কালার সংগ্রহগুলি ব্যবহার করার সময় আমার কখনই লুপের প্রয়োজন হয় না। map, filter, foldLeftএবং forEach অধিকাংশ সময় কৌতুক করতে, কিন্তু যখন তারা নয়, অনুভব করতে আমি পাশব বল অনুজ্ঞাসূচক কোডে প্রত্যাবর্তন করতে "ঠিক আছে" আছি সক্ষম হচ্ছে চমৎকার। (যতক্ষণ না
ইরান মেডান

3

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

অপরিহার্য লুপগুলির চেয়ে ফাংশনাল কন্টেইনার প্রসেসিংয়ের জন্য আপনার কাছে আরও অনেক বিকল্প রয়েছে। অনুজ্ঞাসূচক সঙ্গে, আপনি মূলত আছে for, whileএবং অন্য কোনো ঐ দুটি উপর ছোটখাট পরিবর্তনের do...whileএবং foreach

ক্রিয়াকলাপে, আপনার সমষ্টি, গণনা, ফিল্টার, সন্ধান, ফ্ল্যাটম্যাপ, ভাঁজ, গ্রুপবাই, লাস্ট ইনডেক্স যেখানে, মানচিত্র, ম্যাক্সবাই, মিনি বি, পার্টিশন, স্ক্যান, সারণি বাই, সাজানো উইথ, স্প্যান এবং টেকহইল রয়েছে, কেবল স্কালার থেকে আরও কয়েকটি সাধারণের নামকরণ করুন স্ট্যান্ডার্ড লাইব্রেরি। আপনি যখন সেগুলি উপলভ্য হয়ে উঠবেন, তখন forতুলনামূলকভাবে অত্যাবশ্যকীয় লুপগুলি খুব বেসিক মনে হয়।

স্থানীয় পরিবর্তনের একমাত্র আসল কারণটি পারফরম্যান্সের জন্য খুব মাঝেমধ্যে।


2

আমি বলব এটি বেশিরভাগ ক্ষেত্রে ঠিক আছে। আরও কী, কাঠামোগুলি এইভাবে তৈরি করা কিছু ক্ষেত্রে পারফরম্যান্সের উন্নতি করার ভাল উপায় হতে পারে। ক্ষণস্থায়ী ট্রান্সিয়েন্ট ডেটা স্ট্রাকচার সরবরাহ করে এই সমস্যাটি সমাধান করেছে ।

মূল ধারণাটি হ'ল স্থানীয় রূপান্তরগুলিকে একটি সীমিত সুযোগে মঞ্জুরি দেওয়া এবং তারপরে কাঠামো ফিরিয়ে দেওয়ার আগে হিমশীতল করা। এইভাবে, আপনার ব্যবহারকারী এখনও আপনার কোড সম্পর্কে যুক্তি দিতে পারে যেন এটি খাঁটি ছিল তবে আপনি যখন প্রয়োজন তখন আপনি স্থান পরিবর্তন করতে সক্ষম হবেন।

লিঙ্কটি যেমন বলে:

কোন গাছ যদি বনের মধ্যে পড়ে তবে কি শব্দ করে? যদি একটি খাঁটি ফাংশন কিছু স্থানীয় ডেটা পরিবর্তন করে যাতে অপরিবর্তনীয় ফেরতের মান উত্পাদন করতে পারে, তা কি ঠিক?


2

স্থানীয় পরিবর্তনীয় ভেরিয়েবলগুলির কোনও সুবিধা নেই - এটি ফাংশনটিকে থ্রেডগুলির পক্ষে আরও বন্ধুত্বপূর্ণ করে তোলে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.