জেনারেটর ফাংশনগুলি কার্যকরী প্রোগ্রামিংয়ে বৈধ?


17

প্রশ্নগুলি হ'ল:

  • জেনারেটর কি কার্যকরী প্রোগ্রামিং দৃষ্টান্তটি ভেঙে দেয়? কেন অথবা কেন নয়?
  • যদি হ্যাঁ, জেনারেটরগুলি কার্যকরী প্রোগ্রামিংয়ে ব্যবহৃত হতে পারে এবং কীভাবে?

নিম্নোক্ত বিবেচনা কর:

function * downCounter(maxValue) {
  yield maxValue;
  yield * downCounter(maxValue > 0 ? maxValue - 1 : 0);
}

let counter = downCounter(26);
counter.next().value; // 26
counter.next().value; // 25
// ...etc

downCounterপদ্ধতি আড়ম্বরহীন প্রদর্শিত হবে। পাশাপাশি, downCounterএকই ইনপুট দিয়ে কল করা , সর্বদা একই আউটপুট তৈরি করে। তবে একই সময়ে, কলিং next()সুসংগত ফলাফল দেয় না produce

আমি নিশ্চিত না যে জেনারেটরগুলি কার্যকরী প্রোগ্রামিং দৃষ্টান্তটি ভেঙে দেয় বা না কারণ এই উদাহরণে counterএকটি জেনারেটর অবজেক্ট এবং তাই কলিং next()একই ফলাফল দিয়ে অন্য জেনারেটর অবজেক্ট হিসাবে তৈরি করবে maxValue

পাশাপাশি, someCollection[3]একটি অ্যারেতে কল করা সর্বদা চতুর্থ উপাদানটি ফিরিয়ে দেয়। একইভাবে, next()একটি জেনারেটর অবজেক্টে চারবার কল করাও সর্বদা চতুর্থ উপাদানটি ফিরিয়ে দেয়।

আরও প্রসঙ্গে, একটি প্রোগ্রামিং কাটার কাজ করার সময় এই প্রশ্নগুলি উত্থাপিত হয়েছিল । যে ব্যক্তি এই প্রশ্নের উত্তর দিয়েছিল, জেনারেটরগুলি কার্যকরী প্রোগ্রামিংয়ে ব্যবহৃত হতে পারে এবং না এবং তারা রাষ্ট্রটি ধরে রাখে কি না সে প্রশ্ন উত্থাপন করেছিল।


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

উত্তর:


14

জেনারেটরের কাজগুলি বিশেষভাবে বিশেষ নয়। কলব্যাক-ভিত্তিক শৈলীতে জেনারেটরের ফাংশনটি আবার লিখে আমরা আমাদের অনুরূপ প্রক্রিয়াটি প্রয়োগ করতে পারি:

function downCounter(maxValue) {
  return {
    "value": maxValue,
    "next": function () {
      return downCounter(maxValue > 0 ? maxValue - 1 : 0);
     },
  };
}

let counter = downCounter(26);
counter.value; //=> 26
counter.next().value; //=> 25

স্পষ্টতই, এটি downCounterযতটা খাঁটি এবং কার্যকর তা ততই কার্যকর। এখানে কোন সমস্যা নেই।

জাভাস্ক্রিপ্ট দ্বারা ব্যবহৃত জেনারেটর প্রোটোকলটিতে একটি পরিবর্তনীয় অবজেক্ট জড়িত। এটি প্রয়োজনীয় নয়, উপরের কোডটি দেখুন। বিশেষত, পরিবর্তনীয় অবজেক্টগুলির অর্থ আমরা রেফারেনশিয়াল স্বচ্ছতা আলগা করি - একটি এক্সপ্রেশনকে এর মান দ্বারা প্রতিস্থাপনের ক্ষমতা। আমার উদাহরণে, যদিও counter.next().valueকরবে সবসময় নির্ণয় 25কোন ব্যাপার যেখানে এটি ঘটে এবং কত ঘন ঘন সেভাবে পুনরায় সৃষ্টি, এই জাতীয় জেনারেটরের সঙ্গে কেস নয় - এক পর্যায়ে এটা 26, তারপর 25, এবং এটি সত্যিই কোন সংখ্যা হতে পারে। যদি আমরা জেনারেটরের একটি রেফারেন্স অন্য কোনও কার্যক্রমে পাস করি তবে এটি সমস্যাযুক্ত:

counter.next().value; //=> 25
otherFunction(counter); // does this consume the counter?
counter.next().value; // what will this be? It depends on the otherFunction()

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

যাইহোক, হাস্কেলের কোনও তালিকা এবং জেনারেটর ফিরিয়ে দেওয়ার মধ্যে কোনও পার্থক্য নেই, কারণ এটি অলস মূল্যায়ন ব্যবহার করে:

downCounter :: Int -> [Int]
downCounter maxValue =
  maxValue : (downCounter (max 0 (maxValue - 1)))
-- invoke as "take n (downCounter 26)" to display n elements
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.