পার্শ্ব প্রতিক্রিয়াগুলি উল্লেখযোগ্য স্বচ্ছতা ভঙ্গ করছে


11

স্কেলে কার্যকরী প্রোগ্রামিং রেফারেন্সিয়াল স্বচ্ছতা ভঙ্গ করার ক্ষেত্রে একটি পার্শ্ব প্রতিক্রিয়ার প্রভাব ব্যাখ্যা করে:

পার্শ্ব প্রতিক্রিয়া, যা রেফারেনশিয়াল স্বচ্ছতার কিছু লঙ্ঘন বোঝায়।

আমি এস আই সি পি-র অংশটি পড়েছি , যা একটি প্রোগ্রাম মূল্যায়নের জন্য "প্রতিস্থাপন মডেল" ব্যবহার করে আলোচনা করে।

রেফারেনশিয়াল স্বচ্ছতার (আরটি) বিকল্প হিসাবে আমি মোটামুটি প্রতিস্থাপনের মডেলটি বুঝতে পেরেছিলে আপনি কোনও ফাংশনকে তার সহজতম অংশে ডি-রাইজ করতে পারেন। যদি এক্সপ্রেশনটি আরটি হয়, তবে আপনি এক্সপ্রেশনটি ডি-রচনা করতে পারেন এবং সর্বদা একই ফলাফল পেতে পারেন।

যাইহোক, উপরের উদ্ধৃতি হিসাবে বলা হয়েছে, পার্শ্ব প্রতিক্রিয়া ব্যবহার করে প্রতিস্থাপনের মডেলটিকে ভেঙে ফেলতে পারে / করবে।

উদাহরণ:

val x = foo(50) + bar(10)

যদি fooএবং এর bar কোনও পার্শ্ব প্রতিক্রিয়া নাও থাকে, তবে উভয় ফাংশন সম্পাদন করলে সর্বদা একই ফলাফলটি ফিরে আসবে x। তবে, যদি তাদের পার্শ্ব প্রতিক্রিয়া থাকে, তবে তারা এমন একটি পরিবর্তনশীল পরিবর্তন করবে যা প্রতিস্থাপনের মডেলটিতে একটি রেঞ্চকে বাধাগ্রস্থ করে / ছুড়ে দেয়।

আমি এই ব্যাখ্যাটি দিয়ে স্বাচ্ছন্দ্য বোধ করি, তবে আমি এটি পুরোপুরি ছাঁটাই করি না।

দয়া করে আমাকে সংশোধন করুন এবং আরটি ব্রেকিং এর পার্শ্ব প্রতিক্রিয়া সম্পর্কিত কোনও গর্ত পূরণ করুন, পাশাপাশি প্রতিস্থাপনের মডেলটির উপর প্রভাবগুলি নিয়েও আলোচনা করুন।

উত্তর:


20

আসল স্বচ্ছতার জন্য একটি সংজ্ঞা দিয়ে শুরু করা যাক :

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

এর অর্থ হ'ল (উদাহরণস্বরূপ) আপনি প্রোগ্রামের যে কোনও অংশে 2 দিয়ে 5 প্রতিস্থাপন করতে পারেন এবং প্রোগ্রামটি এখনও কাজ করা উচিত। এই প্রক্রিয়াটিকে প্রতিস্থাপন বলা হয় প্রতিস্থাপন বৈধ যদি হয়, এবং শুধুমাত্র যদি, প্রোগ্রামের অন্য কোনও অংশকে প্রভাবিত না করে 2 + 5 7 দিয়ে প্রতিস্থাপন করা যায় ।

ধরা যাক যে আমি একটি ক্লাস ডেকেছি Baz, ফাংশন সহ Fooএবং Barএটিতে। সরলতার জন্য, আমরা কেবল এটিই বলব Fooএবং Barউভয়ই যে মানটি উত্তীর্ণ হয়েছিল তা ফিরিয়ে দেবে So সুতরাং Foo(2) + Bar(5) == 7, যেমনটি আপনি প্রত্যাশা করবেন। রেফারেনশিয়াল ট্রান্সপারেন্সি গ্যারান্টি দেয় যে আপনি আপনার প্রোগ্রামের যে কোনও জায়গায় অভিব্যক্তিটির Foo(2) + Bar(5)সাথে অভিব্যক্তিটি প্রতিস্থাপন করতে পারবেন 7এবং প্রোগ্রামটি এখনও স্বতন্ত্রভাবে চলবে।

কিন্তু যদি Fooমানটি উত্তীর্ণ হয়, তবে Barযে মানটি উত্তীর্ণ হয় তা ফেরত দেয়, এবং শেষ মানটি দেওয়া হয় Foo? আপনি ক্লাসের Fooমধ্যে স্থানীয় ভেরিয়েবলের মান সঞ্চয় করতে পারলে এটি করা যথেষ্ট সহজ Baz। ঠিক আছে, যদি স্থানীয় ভেরিয়েবলের প্রাথমিক মান 0 Foo(2) + Bar(5)হয় 7তবে আপনি প্রথমবারের মতো অনুরোধ করলে প্রথমে এটির প্রত্যাশিত মান ফিরে আসবে, কিন্তু 9আপনি যখন দ্বিতীয়বার ডাকেন তখন এটি ফিরে আসবে।

এটি দুটিভাবে রেফারেন্সিয়াল স্বচ্ছতা লঙ্ঘন করে। প্রথমত, বারটি যখন একবার বলা হয়, তখন একই অভিব্যক্তি ফিরে পাওয়ার জন্য বার গণনা করা যায় না। দ্বিতীয়ত, একটি পার্শ্ব-প্রতিক্রিয়া ঘটেছে, যথা Foo কল করা বারের রিটার্ন মানকে প্রভাবিত করে। যেহেতু আপনি আর গ্যারান্টি দিতে পারবেন না যে Foo(2) + Bar(5)এটি 7 এর সমান হবে তাই আপনি আর বিকল্প করতে পারবেন না।

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


5
সুতরাং ব্রেকিং RTআপনাকে ব্যবহার থেকে অক্ষম করে এটি ব্যবহার করতে সক্ষম না হওয়ায় substitution model.বড় সমস্যাটি কোনও প্রোগ্রাম সম্পর্কে যুক্তিযুক্ত কারণ হিসাবে এটি ব্যবহার করার শক্তি? substitution model
কেভিন মেরিডেথ

একদম ঠিক।
রবার্ট হার্ভে

1
+1 বিস্ময়করভাবে পরিষ্কার এবং বোধগম্য উত্তর। ধন্যবাদ.
রাশেত 12

2
এছাড়াও যদি সেই ফাংশনগুলি স্বচ্ছ বা "খাঁটি" হয় তবে তারা যে ক্রমটি চালিয়েছে তা গুরুত্বপূর্ণ নয়, আমরা foo () বা বার () প্রথমে চালিত হয় কিনা তা বিবেচনা করি না এবং কিছু ক্ষেত্রে তারা প্রয়োজন না হলে তারা কখনই মূল্যায়ন করতে পারে না
জাচারি কে

1
আরটিটির আরও একটি সুবিধা হ'ল ব্যয়বহুল রেফারেন্টালি স্বচ্ছ ভাবগুলি ক্যাশ করা যায় (যেহেতু একবার বা দু'বার মূল্যায়ন করার পরেও একই ফলাফল পাওয়া উচিত)।
ডাস্ট্রো

3

কল্পনা করুন যে আপনি একটি প্রাচীর তৈরি করার চেষ্টা করছেন এবং আপনাকে বিভিন্ন আকার এবং আকারের বাক্সগুলির একটি ভাণ্ডার দেওয়া হয়েছে। আপনাকে প্রাচীরের একটি নির্দিষ্ট এল-আকৃতির গর্ত পূরণ করতে হবে; আপনার কি একটি এল-আকৃতির বাক্সের সন্ধান করা উচিত বা আপনি উপযুক্ত আকারের দুটি সোজা বাক্সের বিকল্প দিতে পারেন?

কার্যকরী বিশ্বে, উত্তরটি হ'ল উভয় সমাধানই কাজ করবে। আপনার কার্যকরী বিশ্ব তৈরি করার সময়, ভিতরে কী রয়েছে তা দেখতে আপনাকে কখনই বাক্সগুলি খুলতে হবে না।

অপরিহার্য বিশ্বে, প্রতিটি বাক্সের সামগ্রীগুলি পরীক্ষা না করে এবং অন্যান্য বাক্সের সামগ্রীর সাথে তুলনা না করে আপনার প্রাচীর তৈরি করা বিপজ্জনক :

  • কিছু শক্তিশালী চৌম্বক ধারণ করে এবং অন্যায়ভাবে চৌম্বকীয় বাক্সগুলি প্রাচীরের বাইরে ধাক্কা দেয় যদি ভুলভাবে সারিবদ্ধ হয়।
  • কিছু খুব গরম বা ঠান্ডা থাকে এবং সংলগ্ন জায়গাগুলিতে রাখলে খারাপ প্রতিক্রিয়া জানায়।

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

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

একটি অপরিহার্য ভাষায়, আপনি কখনই জানেন না যে কী আশ্চর্যতা ভিতরে লুকিয়ে থাকতে পারে।


"একটি খাঁটি কার্যকরী ভাষায়, আপনাকে যা দেখতে হবে তা হ'ল এটি কী করে তা জানার জন্য একটি ফাংশনের স্বাক্ষর" " - এটি সাধারণত সত্য নয়। হ্যাঁ, প্যারাম্যাট্রিক পলিমারফিজম অনুমানের অধীনে আমরা এই সিদ্ধান্তে পৌঁছাতে পারি যে টাইপের একটি ফাংশন (a, b) -> aকেবল fstফাংশন হতে পারে এবং টাইপের ফাংশনটি a -> aকেবল identityফাংশন হতে পারে তবে (a, a) -> aউদাহরণস্বরূপ আপনি কোনও ধরনের ফাংশন সম্পর্কে অগত্যা কিছু বলতে পারবেন না ।
Jörg ডব্লু মিট্টাগ

2

আমি মোটামুটি প্রতিস্থাপনের মডেলটি বুঝতে পারছি (রেফারেনশিয়াল স্বচ্ছতার সাথে (আরটি)), আপনি কোনও ফাংশনকে তার সহজতম অংশে ডি-রাইজ করতে পারেন। যদি এক্সপ্রেশনটি আরটি হয়, তবে আপনি এক্সপ্রেশনটি ডি-রচনা করতে পারেন এবং সর্বদা একই ফলাফল পেতে পারেন।

হ্যাঁ, অন্তর্দৃষ্টিটি বেশ সঠিক। আরও সুনির্দিষ্ট পেতে এখানে কয়েকটি পয়েন্টার রয়েছে:

যেমনটি আপনি বলেছেন, যে কোনও আরটি এক্সপ্রেশনটির single"ফলাফল" হওয়া উচিত । এটি, factorial(5)প্রোগ্রামটিতে একটি অভিব্যক্তি দেওয়া , এটি সর্বদা একই "ফলাফল" পাওয়া উচিত yield সুতরাং, যদি কোনও factorial(5)প্রোগ্রামে থাকে এবং এটি 120 উপার্জন করে তবে সময়টি নির্বিশেষে এটি "ধাপে ক্রম" প্রসারিত / গণনা করা ছাড়াই সর্বদা 120 ফলন করা উচিত ।

উদাহরণ: factorialফাংশন

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)

এই ব্যাখ্যাটি সহ কয়েকটি বিবেচনা রয়েছে।

প্রথমত, বিভিন্ন মূল্যায়ন মডেলগুলি মনে রাখবেন (আবেদনকারী বনাম স্বাভাবিক ক্রম দেখুন) একই আরটি এক্সপ্রেশনটির জন্য বিভিন্ন "ফলাফল" পেতে পারে।

def first(y, z):
  return y

def second(x):
  return second(x)

first(2, second(3)) # result depends on eval. model

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

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

তৃতীয়ত, foo(50)প্রোগ্রামে দু'জনকে বিভিন্ন স্থানে আলাদা আলাদা এক্সপ্রেশন হিসাবে দেখা দরকার হতে পারে - প্রত্যেকে একে অপরের থেকে পৃথক হতে পারে এমন নিজস্ব ফলাফল প্রদান করে। উদাহরণস্বরূপ, ভাষা যদি গতিশীল সুযোগের অনুমতি দেয় তবে উভয় এক্সপ্রেশন, যদিও বর্ণগতভাবে অভিন্ন, ভিন্ন। পার্ল ইন:

sub foo {
    my $x = shift;
    return $x + $y; # y is dynamic scope var
}

sub a {
    local $y = 10;
    return &foo(50); # expanded to 60
}

sub b {
    local $y = 20;
    return &foo(50); # expanded to 70
}

ডায়নামিক সুযোগ বিপথগামী করা হয়েছে কারণ এটি সহজ করে এক চিন্তা করতে করতে xশুধু ইনপুট fooযখন বাস্তবে, তা না হয়, xএবং y। পার্থক্যটি দেখার একটি উপায় হ'ল প্রোগ্রামটি গতিশীল সুযোগ ছাড়াই সমতুল্য রূপে রূপান্তরিত করা - অর্থাৎ স্পষ্টভাবে প্যারামিটারগুলি পাশ করা, সুতরাং সংজ্ঞার পরিবর্তে foo(x)আমরা কলকারীদের মধ্যে স্পষ্টভাবে সংজ্ঞা দিয়ে foo(x, y)ও পাস করি y

মুল বক্তব্যটি হ'ল আমরা সর্বদা একটি functionমানসিকতার আওতায় থাকি : একটি অভিব্যক্তির জন্য একটি নির্দিষ্ট ইনপুট দেওয়া হলে আমাদের একটি সম্পর্কিত "ফলাফল" দেওয়া হয়। আমরা যদি একই ইনপুট দিই, আমাদের সর্বদা একই "ফলাফল" আশা করা উচিত।

এখন, নিম্নলিখিত কোড সম্পর্কে কি?

def foo():
   global y
   y = y + 1
   return y

y = 10
foo() # yields 11
foo() # yields 12

fooকার্যপ্রণালী রিটুইট ভঙ্গ কারণ redefinitions হয়। অর্থাৎ আমরা সংজ্ঞায়িত yএক বিন্দুতে, এবং পরেরটির, যে পুনরায় সংজ্ঞায়িত একই y । উপরের পার্ল উদাহরণে, ys একই অক্ষরের নাম "y" ভাগ করে নিলেও তারা আলাদা আলাদা বাইন্ডিং। এখানে ys গুলি আসলে একই রকম। এজন্য আমরা বলি (পুনরায়) নিয়োগটি একটি মেটা অপারেশন: আপনি আসলে আপনার প্রোগ্রামের সংজ্ঞা পরিবর্তন করছেন।

মোটামুটিভাবে লোকেরা সাধারণত পার্থক্যটি নিম্নরূপে চিত্রিত করে: পার্শ্ব-প্রতিক্রিয়া মুক্ত সেটিংয়ে আপনার কাছ থেকে একটি ম্যাপিং রয়েছে input -> output। একটি "অপরিহার্য" সেটিংসে আপনার এমন input -> ouputএকটি প্রসঙ্গে রয়েছে stateযা সময়ের সাথে পরিবর্তিত হতে পারে।

এখন, তাদের সম্পর্কিত মানগুলির জন্য কেবল প্রকাশের পরিবর্তে, stateপ্রতিটি অপারেশনের জন্য এটির প্রয়োজন অনুসারে রূপান্তরকৃত প্রয়োগ করতে হবে (এবং অবশ্যই, এক্সপ্রেশনগুলি stateগণনা সম্পাদন করতে একই পরামর্শ করতে পারে )।

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


1
আপনি স্মৃতিচারণ উল্লেখ করেছেন যে দুর্দান্ত। এটি অভ্যন্তরীণ অবস্থার উদাহরণ হিসাবে ব্যবহার করা যেতে পারে যা বাইরে দৃশ্যমান নয়: মেমোয়েজেশন ব্যবহার করে একটি ফাংশন অভ্যন্তরীণভাবে রাষ্ট্র এবং মিউটেশন ব্যবহার করে সত্ত্বেও উল্লেখযোগ্যভাবে স্বচ্ছ।
জর্জিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.