কোনও স্মৃতিযুক্ত খাঁটি ফাংশন নিজেই খাঁটি হিসাবে বিবেচিত হয়?


47

আসুন ধরা যাক fn(x)একটি খাঁটি ফাংশন যা ব্যয়বহুল কিছু করে, যেমনগুলির প্রধান কারণগুলির একটি তালিকা ফেরত x

এবং আসুন আমরা বলি আমরা একই ফাংশনটির একটি মেমোজাইজড সংস্করণ তৈরি করি memoizedFn(x)। প্রদত্ত ইনপুটের জন্য এটি সর্বদা একই ফলাফলটি দেয়, তবে কার্য সম্পাদন উন্নত করতে এটি পূর্ববর্তী ফলাফলগুলির একটি ব্যক্তিগত ক্যাশে বজায় রাখে।

সাধারণভাবে বলতে গেলে কি memoizedFn(x)খাঁটি বলে বিবেচিত হয়?

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


24
সম্ভবত এটি শুদ্ধবাদীদের পক্ষে খাঁটি নয়, তবে ব্যবহারিক লোকের জন্য "যথেষ্ট খাঁটি" ;-)
ডক ব্রাউন

2
@ ডকব্রাউন আমি একমত হয়েছি, কেবল ভাবছি যে 'খাঁটি যথেষ্ট' এর জন্য আরও কোনও আনুষ্ঠানিক শব্দ আছে কিনা
কলম্ব

13
একটি খাঁটি ফাংশন সম্পাদন করা সম্ভবত প্রসেসরের নির্দেশ ক্যাশে, শাখার ভবিষ্যদ্বাণী ইত্যাদি সংশোধন করবে তবে এটি সম্ভবত পিউরিস্টদের পক্ষেও যথেষ্ট "খাঁটি" - অথবা আপনি খাঁটি ফাংশনগুলি পুরোপুরি ভুলে যেতে পারেন।
gnasher729

10
@ ক্যালাম না, "খাঁটি যথেষ্ট" এর কোনও আনুষ্ঠানিক সংজ্ঞা নেই। বিশুদ্ধতা এবং দুটি "রেফারেন্টালি ট্রান্সপারেন্ট" কলগুলির অর্থগত সমতুলতার বিষয়ে বিতর্ক করার সময়, আপনাকে সর্বদা সঠিকভাবে বলতে হবে যে আপনি কোন শব্দার্থক প্রয়োগ করতে চলেছেন। বাস্তবায়নের বিশদগুলির কয়েকটি নিম্ন স্তরে এটি সর্বদা ভেঙে যায় এবং এর মেমরির বিভিন্ন প্রভাব বা সময় থাকে। এজন্য আপনাকে ব্যবহারিক হতে হবে: আপনার কোডটি সম্পর্কে যুক্তির জন্য কোন স্তরের বিশদটি কার্যকর?
বার্গি

3
তারপরে বাস্তববাদীতার জন্য, আমি বলব যে আপনি গণনার সময়কে আউটপুটের অংশ হিসাবে বিবেচনা করছেন কিনা তা নির্ভর করে শুদ্ধতা নির্ভর করে। funcx(){sleep(cached_time--); return 0;}প্রতিবার একই ভ্যালু ফেরত দেয়, তবে ভিন্নভাবে সম্পাদন করবে
মঙ্গলবার

উত্তর:


41

হ্যাঁ. খাঁটি ফাংশনটির স্মৃতিযুক্ত সংস্করণটিও একটি শুদ্ধ ফাংশন।

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

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


19

উইকিপিডিয়া একটি "খাঁটি ফাংশন" একটি ফাংশন হিসাবে সংজ্ঞায়িত করে যা নিম্নলিখিত বৈশিষ্ট্যগুলি রয়েছে:

  • এর রিটার্ন মান একই আর্গুমেন্টের জন্য একই (স্থানীয় স্থিতিশীল ভেরিয়েবল, অ-স্থানীয় ভেরিয়েবল, পরিবর্তনীয় রেফারেন্স আর্গুমেন্ট বা আই / ও ডিভাইস থেকে ইনপুট স্ট্রিমের সাথে কোনও পার্থক্য নেই)।

  • এর মূল্যায়নের কোনও পার্শ্ব প্রতিক্রিয়া নেই (স্থানীয় স্ট্যাটিক ভেরিয়েবল, অ-স্থানীয় ভেরিয়েবল, পরিবর্তনীয় রেফারেন্স আর্গুমেন্ট বা I / O স্ট্রিমগুলির কোনও রূপান্তর)।

কার্যত, একটি খাঁটি ফাংশন একই ইনপুট দেওয়া একই আউটপুট প্রদান করে এবং ফাংশনের বাইরে অন্য কোনও কিছুকে প্রভাবিত করে না। বিশুদ্ধতার উদ্দেশ্যে, ফাংশনটি তার রিটার্নের মানটি কীভাবে গণনা করে তা বিবেচনা করে না, যতক্ষণ না এটি একই ইনপুট দেওয়া একই আউটপুট প্রদান করে।

কার্যত খাঁটি ভাষা যেমন হাস্কেলের নিয়মিতভাবে এর আগের গণিত ফলাফলগুলি ক্যাশে করে কোনও ফাংশন গতি বাড়ানোর জন্য মেমোয়েজেশন ব্যবহার করে


16
আমি কিছু মিস করতে পারি তবে আপনি কীভাবে পার্শ্ব প্রতিক্রিয়া ছাড়াই ক্যাশে রাখছেন?
Val

1
এটি ফাংশনের ভিতরে রেখে।
রবার্ট হার্ভে

4
"স্থানীয় স্ট্যাটিক ভেরিয়েবলের কোনও রূপান্তর" কলগুলির মধ্যে স্থির স্থানীয় ভেরিয়েবলগুলি বাদ দেয় বলে মনে হয় না।
Val

3
এটি আসলে প্রশ্নের উত্তর দেয় না, এমনকি যদি আপনি হ্যাঁ, এটি খাঁটি বলে মনে হয়।
মঙ্গলবার

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

7

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

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

কম্পিউটার বিজ্ঞানীর এই উদাহরণটি "খাঁটিভাবে কার্যকরী" শব্দটি ব্যবহার করে স্বয়ংক্রিয় স্মৃতিচারণ সম্পর্কে কনাল এলিয়টের এই ব্লগ পোস্টটি :

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

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

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

কিছু অপরিহার্য ভাষাগুলির অনুরূপ প্রবাদ রয়েছে। উদাহরণস্বরূপ, static constC ++ এ একটি ভেরিয়েবল কেবল একবারই শুরু করা হয়, এর মান ব্যবহৃত হওয়ার আগে এবং কখনই পরিবর্তিত হয় না।


3

এটি আপনি কীভাবে করেন তার উপর নির্ভর করে।

সাধারণত লোকেরা কোনও ধরণের ক্যাশে অভিধানকে পরিবর্তন করে স্মৃতিচারণ করতে চায়। এতে অশুচি পরিবর্তনের সাথে জড়িত সমস্ত সমস্যা রয়েছে, যেমন সম্মতি সম্পর্কে চিন্তাভাবনা করা, ক্যাশে খুব বেশি বড় হওয়া নিয়ে চিন্তা করা ইত্যাদি etc.

তবে, আপনি অপরিষ্কার মেমরি রূপান্তর ছাড়াই স্মৃতিচারণ করতে পারেন। একটি উদাহরণ এই উত্তরে রয়েছে , যেখানে আমি lengthsআর্গুমেন্টের মাধ্যমে বাহ্যিকভাবে স্মৃতিযুক্ত মানগুলি ট্র্যাক করি ।

ইন লিংক রবার্ট হার্ভে প্রদান , অলস মূল্যায়ন পার্শ্ব প্রতিক্রিয়া এড়াতে ব্যবহার করা হয়।

আরেকটি কৌশল মাঝে মাঝে দেখা স্পষ্টভাবে একটি প্রেক্ষিতে একটি অশুদ্ধ পার্শ্ব প্রতিক্রিয়া হিসাবে memoization চিহ্নিত হয় IOযেমন বিড়াল-প্রভাব এর সাথে ধরন, memoize ফাংশন

এই শেষটিটি এমন একটি পয়েন্টটি উপস্থিত করে যে কখনও কখনও লক্ষ্যটি পরিবর্তনের পরিবর্তে কেবল রূপান্তরকে encapsulating করে। বেশিরভাগ ক্রিয়ামূলক প্রোগ্রামাররা একে অপরিচ্ছন্নতা স্পষ্ট এবং আবদ্ধ করতে "যথেষ্ট খাঁটি" মনে করে।

আপনি যদি একটি শব্দটিকে সত্যিকারের শুদ্ধ কার্য থেকে আলাদা করতে চান তবে আমার মনে হয় এটি কেবল "একটি পরিবর্তনীয় অভিধানের সাথে স্মৃতিচারণ করা" যথেষ্ট। এটি লোকেরা কীভাবে এটি নিরাপদে ব্যবহার করতে পারে তা জানতে দেয়।


আমি মনে করি না খাঁটি সমাধানের কোনওটিই উপরের সমস্যাগুলি সমাধান করে: আপনি যখন কোনও সম্মতিযুক্ত উদ্বেগ হারাতে চান, তখন একই সাথে দুটি শুরু কল collatz(100)এবং মতামতের জন্য আপনি কোনও সুযোগও হারাবেন collatz(200)। এবং আইআইইউআইসি, খুব বড় আকারে ক্যাশে বাড়ার সমস্যা রয়েছে (যদিও হাস্কেলের কাছে এর জন্য কিছু সুন্দর কৌশল থাকতে পারে?)।
মার্টিনাস

দ্রষ্টব্য: IOখাঁটি। সমস্ত অশুচি পদ্ধতিতে IOএবং বিড়ালদের নাম দেওয়া হয়েছে unsafeAsync.memoizeখাঁটিও শুদ্ধ, সুতরাং আমাদের "যথেষ্ট পরিমাণে খাঁটি" এর জন্য নিষ্পত্তি করতে হবে না :)
স্যামুয়েল

2

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

সাধারণভাবে, যদি মেমোয়েজেশন এমনভাবে করা যায় যা ব্যর্থতা-কেস মুক্ত হয় (যেমন ভাষা স্মৃতিযুক্ত ফলাফলের জন্য স্ট্যাটিকভাবে বরাদ্দ দেওয়া এবং ভাষা থ্রেডকে স্বীকার করে তবে তাদের অ্যাক্সেস নিয়ন্ত্রণ করতে অভ্যন্তরীণ সিঙ্ক্রোনাইজেশন), এই জাতীয় ফাংশন বিবেচনা করা যুক্তিসঙ্গত বিশুদ্ধ।


0

আপনি রাষ্ট্র মোনাড ব্যবহার করে পার্শ্ব-প্রতিক্রিয়া ছাড়াই স্মারক প্রয়োগ করতে পারেন ।

[রাজ্য মোনাড] মূলত একটি ফাংশন এস => (এস, এ), যেখানে এস হ'ল প্রকার যা আপনার রাজ্যকে উপস্থাপন করে এবং ফল ফাংশনটি তৈরি করে - বিড়ালদের রাজ্য

আপনার ক্ষেত্রে রাষ্ট্রটি স্মৃতিযুক্ত মান বা কিছুই হবে না (যেমন হাস্কেল Maybeবা স্কেলা Option[A])। যদি মেমোজাইজ করা মানটি উপস্থিত থাকে তবে এটি হিসাবে প্রত্যাবর্তন করা হয় A, অন্যথায় Aরূপান্তরিত অবস্থা এবং ফলাফল উভয় হিসাবে গণনা করা হয় এবং ফিরে আসে।

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