বন্ধগুলি কি অশুচি কার্যকরী শৈলী হিসাবে বিবেচিত হয়?


33

ক্লোজারগুলি কি কার্যকরী প্রোগ্রামিংয়ে অশুচি বিবেচিত হয়?

দেখে মনে হচ্ছে যে কোনও ব্যক্তি সরাসরি কোনও ফাংশনে মান প্রেরণ করে ক্লোজারগুলি এড়াতে পারে। সুতরাং যেখানে সম্ভব বন্ধগুলি এড়ানো উচিত?

যদি তারা নাপাক হয় এবং আমি এ কথাটি সঠিকভাবে বলতে পারি যে সেগুলি এড়ানো যায়, তবে এতগুলি কার্যকরী প্রোগ্রামিং ভাষা কেন বন্ধকে সমর্থন করে?

খাঁটি ফাংশনের একটি মানদণ্ড হ'ল "ফাংশন সর্বদা একই যুক্তির মান (গুলি) প্রদত্ত একই ফলাফলের মানটি মূল্যায়ন করে ।"

অনুমান করা

f: x -> x + y

f(3)সর্বদা একই ফলাফল দেয় না। f(3)কোনটির yযুক্তি নয় এর উপর নির্ভর করে f। সুতরাং fএটি একটি খাঁটি ফাংশন নয়।

যেহেতু সমস্ত বন্ধনগুলি সেই মানগুলিতে নির্ভর করে যেগুলি আর্গুমেন্ট নয়, তাই কোনও বন্ধের শুদ্ধ হওয়া কীভাবে সম্ভব? হ্যাঁ, তাত্ত্বিকভাবে বদ্ধমূল্য স্থির থাকতে পারে তবে কেবল ফাংশনের উত্স কোডটি দেখে তা জানার কোনও উপায় নেই looking

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

আমি কি এই সম্পর্কে সঠিকভাবে চিন্তা করছি?


6
আমি হাস্কেলের সব সময় ক্লোজার ব্যবহার করি এবং হাস্কেল যতটা বিশুদ্ধ হয় ততই শুদ্ধ।
টমাস এডিং

5
খাঁটি কার্যকরী ভাষায়, yপরিবর্তন করতে পারে না, সুতরাং আউটপুট f(3)সর্বদা একই থাকে।
লিলি চুং

4
yfযদিও এটি স্পষ্টভাবে ইনপুট হিসাবে চিহ্নিত করা হয়নি তার সংজ্ঞাটির অংশ f- এটি এখনও সেই ক্ষেত্রে রয়েছে যা পরিস্কারভাবে fসংজ্ঞায়িত করা হয়েছে y(আমরা f_y ফাংশনটি বোঝাতে পারি, yসুস্পষ্টের উপর নির্ভরশীলতা তৈরি করতে ), এবং তাই পরিবর্তনটি yএকটি ভিন্ন ফাংশন দেয় । f_yনির্দিষ্ট জন্য নির্দিষ্ট নির্দিষ্ট ফাংশনটি yখুব খাঁটি। (উদাহরণস্বরূপ, দুটি ফাংশন f: x -> x + 3এবং f: x -> x + 5হয় বিভিন্ন ফাংশন উভয় বিশুদ্ধ, এবং, যদিও আমরা তাদের বোঝাতে একই চিঠি ব্যবহার করতে ঘটেছে।)
ShreevatsaR

উত্তর:


26

বিশুদ্ধতা দুটি জিনিস দ্বারা পরিমাপ করা যেতে পারে:

  1. ফাংশনটি কি সর্বদা একই ইনপুট দেওয়া একই আউটপুট ফেরত দেয়; অর্থাত্ এটি কি স্বচ্ছ?
  2. ফাংশনটি কি নিজের বাইরে কিছু সংশোধন করে, এর কী পার্শ্ব-প্রতিক্রিয়া রয়েছে?

যদি 1 এর উত্তর হ্যাঁ হয় এবং 2 এর উত্তর না হয়, তবে ফাংশনটি খাঁটি। ক্লোজার-ওভার ভেরিয়েবলটি সংশোধন করা হলে বন্ধগুলি কেবল একটি ফাংশনকে অপরিষ্কার করে।


প্রথম আইটেম নির্ধারণ নয়? নাকি তাও পবিত্রতার অঙ্গ? প্রোগ্রামিংয়ের প্রসঙ্গে আমি "শুদ্ধি" ধারণার সাথে খুব বেশি পরিচিত নই।

4
@ জিমি হোফা: অগত্যা নয়। আপনি একটি ফাংশনে একটি হার্ডওয়্যার টাইমার আউটপুট রাখতে পারেন, এবং ফাংশনের বাইরে কোনও কিছুই সংশোধন করা হয়নি।
রবার্ট হার্ভে

1
@ রবার্টহার্ভে এটি কী আমাদের কোনও কার্যের ইনপুটগুলি সংজ্ঞায়িত করে তা সম্পর্কে? উইকিপিডিয়া থেকে আমার উদ্ধৃতিটি ফাংশন আর্গুমেন্টগুলিকে কেন্দ্র করে, যেখানে আপনি অতিরিক্তভাবে বদ্ধ ভেরিয়েবল (গুলি) ইনপুট হিসাবে বিবেচনা করেন।
ব্যবহারকারী 2179977

8
@ ব্যবহারকারী2179977: যদি না তারা পরিবর্তনীয় হয়, আপনার ক্লোজড ওভার ভেরিয়েবলগুলি ফাংশনের অতিরিক্ত ইনপুট হিসাবে বিবেচনা করা উচিত নয় । বরং, আপনি একটি ফাংশন হতে অবসান নিজেই বিবেচনা করা উচিত, এবং একটি হতে বিভিন্ন ফাংশন যখন এটি একটি ভিন্ন মান ধরে বন্ধ y। সুতরাং উদাহরণস্বরূপ আমরা একটি ফাংশন সংজ্ঞায়িত করি gযে g(y)এটি নিজেই ফাংশন x -> x + y। তারপর gএর পূর্ণসংখ্যার যে আয় ফাংশন একটি ফাংশন হয় g(3)পূর্ণসংখ্যার একটি ফাংশন যে আয় পূর্ণসংখ্যার, এবং g(2)একটি হল বিভিন্ন পূর্ণসংখ্যার যে আয় পূর্ণসংখ্যার ফাংশন। তিনটি ফাংশনই খাঁটি।
স্টিভ জেসোপ

1
@ দারখোগ: হ্যাঁ আমার আপডেট দেখুন।
রবার্ট হার্ভে

10

বন্ধগুলি ল্যাম্বডা ক্যালকুলাস প্রদর্শিত হবে যা কার্যকরী প্রোগ্রামিংয়ের বিশুদ্ধতম রূপ, তাই আমি তাদের "অপরিষ্কার" বলব না ...

বন্ধগুলি "অপরিষ্কার" নয় কারণ কার্যকরী ভাষায় ফাংশনগুলি প্রথম শ্রেণির নাগরিক - এর অর্থ তারা মান হিসাবে বিবেচিত হতে পারে।

এটি (সিউডোকোড) কল্পনা করুন:

foo(x) {
    let y = x + 1
    ...
}

yএকটি মান। এটির মান নির্ভর করে xতবে xঅপরিবর্তনীয় তাই yএর মানও অপরিবর্তনীয়। আমরা fooবিভিন্ন বার বিভিন্ন যুক্তি দিয়ে কল করতে পারি যা বিভিন্ন yগুলি তৈরি করে , তবে যারা yসকলেই বিভিন্ন স্কোপে বেঁচে থাকে এবং বিভিন্ন এসের উপর নির্ভর করে xতাই বিশুদ্ধতা অক্ষত থাকে।

এখন এটি পরিবর্তন করুন:

bar(x) {
    let y(z) = x + z
    ....
}

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

এছাড়াও, দয়া করে নোট করুন যে বন্ধগুলি কারিঙের সাথে খুব একই রকম প্রভাব ফেলে:

adder(a)(b) {
    return a + b
}
baz(x) {
    let y = adder(x)
    ...
}

bazএর চেয়ে সত্যই পৃথক নয় bar- উভয় ক্ষেত্রেই আমরা একটি ফাংশন মান তৈরি করি yযা তার যুক্তিটি যোগ করে দেয় x। প্রকৃতপক্ষে, ল্যাম্বদা ক্যালকুলাসে আপনি একাধিক যুক্তি সহ ফাংশন তৈরি করতে ক্লোজার ব্যবহার করেন - এবং এটি এখনও অপরিষ্কার নয়।


9

অন্যরা তাদের উত্তরগুলিতে সাধারণ প্রশ্নটি খুব সুন্দরভাবে কভার করেছেন, সুতরাং আমি আপনার সম্পাদনায় যে বিভ্রান্তি দেখিয়েছি তা কেবল সাফ করার দিকে নজর দেব।

বন্ধটি ফাংশনের একটি ইনপুট হয়ে ওঠে না, বরং এটি ফাংশন বডিটিতে 'যায়'। আরও কংক্রিট হতে, একটি ফাংশন তার শরীরের বাইরের সুযোগের মান বোঝায়।

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

ধরা যাক আপনার মতো কোডের একটি অংশ রয়েছে:

let make y =
    fun x -> x + y

কল করা হচ্ছে make 3এবং make 4উপর বন্ধ সঙ্গে আপনি দুটি ফাংশন দেব makeএর yযুক্তি। তাদের একজন ফিরে আসবে x + 3, অন্যটি x + 4। এগুলি দুটি স্বতন্ত্র ফাংশন, এবং উভয়ই খাঁটি। এগুলি একই makeফাংশনটি ব্যবহার করে তৈরি করা হয়েছিল , তবে এটি।

বেশিরভাগ সময় পিছনে কয়েকটি অনুচ্ছেদে নোট করুন ।

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

নোট করুন যে 2 এবং 3 এর জন্য, সেই ভাষাগুলি বিশুদ্ধতা সম্পর্কে কোনও গ্যারান্টি দেয় না। অপরিচ্ছন্নতা বন্ধের সম্পত্তি নয়, তবে ভাষাটি। বন্ধগুলি নিজের দ্বারা ছবিটি খুব বেশি পরিবর্তন করে না।


1
আপনি হাস্কেলের মধ্যে পরিবর্তনীয় মানগুলি একেবারে বন্ধ করতে পারেন, তবে আইও মোনাডের সাথে এ জাতীয় জিনিসটি বর্নিত হবে।
ড্যানিয়েল গ্রেটজার

1
@ জোজেফজি নং, আপনি একটি অপরিবর্তনীয় IO Aমানের উপর থেকে বন্ধ করুন এবং আপনার বন্ধের ধরণটি কিছুটা IO (B -> C)বা কিছুটা । বিশুদ্ধতা বজায় রাখা হয়েছে
কালেথ

5

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

দেখে মনে হচ্ছে যে কোনও ব্যক্তি সরাসরি কোনও ফাংশনে ডেটা প্রেরণ করে ক্লোজারগুলি এড়াতে পারে।

হ্যাঁ, তবে তারপরে আপনার ফাংশনে আরও একটি প্যারামিটার থাকবে এবং এটির ধরণটি পরিবর্তিত হবে। বন্ধগুলি আপনাকে প্যারামিটারগুলি যুক্ত না করে ভেরিয়েবলের ভিত্তিতে ফাংশন তৈরি করতে দেয় । এটি কার্যকর যখন আপনি বলুন, একটি ফাংশন যা 2 টি আর্গুমেন্ট নেয় এবং আপনি এটির একটি সংস্করণ তৈরি করতে চান যা কেবল 1 টি আর্গুমেন্ট নেয়।

সম্পাদনা: আপনার নিজের সম্পাদনা / উদাহরণের সাথে ...

অনুমান করা

f: x -> x + y

চ (3) সর্বদা একই ফলাফল দেয় না। f (3) y এর মানের উপর নির্ভর করে যা চ এর যুক্তি নয়। সুতরাং চ কোনও খাঁটি ফাংশন নয়।

নির্ভর করে এখানে শব্দের ভুল পছন্দ। আপনি যে একই উইকিপিডিয়া নিবন্ধটি উদ্ধৃত করেছেন:

কম্পিউটার প্রোগ্রামিংয়ে কোনও ফাংশন বিশুদ্ধ ফাংশন হিসাবে বর্ণনা করা যেতে পারে যদি ফাংশন সম্পর্কে এই উভয় বক্তব্য হোল্ড থাকে:

  1. ফাংশন সর্বদা একই আর্গুমেন্ট মান (গুলি) প্রদত্ত একই ফলাফলের মানটি মূল্যায়ন করে। ফাংশন ফলাফলের মান কোনও গোপন তথ্য বা অবস্থার উপর নির্ভর করতে পারে না যা প্রোগ্রাম এক্সিকিউশনটি এগিয়ে যাওয়ার সাথে সাথে বা প্রোগ্রামের বিভিন্ন নির্বাহের মধ্যে পরিবর্তিত হতে পারে, বা এটি I / O ডিভাইসগুলির কোনও বাহ্যিক ইনপুটের উপর নির্ভর করতে পারে না।
  2. ফলাফলের মূল্যায়ন কোনও শব্দার্থগতভাবে পর্যবেক্ষণযোগ্য পার্শ্ব প্রতিক্রিয়া বা আউটপুট সৃষ্টি করে না, যেমন পরিবর্তনযোগ্য বস্তুর রূপান্তর বা I / O ডিভাইসে আউটপুট।

ধরে yনেওয়া স্থায়ী নয় (যা সাধারণত কার্যকরী ভাষায় হয়), শর্ত 1 সন্তুষ্ট: সমস্ত মানের জন্য x, এর মান f(x)পরিবর্তন হয় না। এটি yধ্রুবক থেকে আলাদা নয় এবং x + 3খাঁটি এই সত্য থেকে পরিষ্কার হওয়া উচিত । এটাও পরিষ্কার যে কোনও রূপান্তর বা I / O চলছে না।


3

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

এখন বন্ধ সম্পর্কে কথা বলা যাক।

বিরক্তিকর (বেশিরভাগ বিশুদ্ধ) "ক্লোজারগুলি"

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

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

-- untyped lambda calculus values are functions
data Value = FunVal (Value -> Value)

-- we write expressions where variables take string-based names, but we'll
-- also just assume that nobody ever shadows names to avoid having to do
-- capture-avoiding substitutions

type Name = String

data Expr
  = Var Name
  | App Expr Expr
  | Abs Name Expr

-- We model the environment as function from strings to values, 
-- notably ignoring any kind of smooth lookup failures
type Env = Name -> Value

-- The empty environment
env0 :: Env
env0 _ = error "Nope!"

-- Augmenting the environment with a value, "closing over" it!
addEnv :: Name -> Value -> Env -> Env
addEnv nm v e nm' | nm' == nm = v
                  | otherwise = e nm

-- And finally the interpreter itself
interp :: Env -> Expr -> Value
interp e (Var name) = e name          -- variable lookup in the env
interp e (App ef ex) =
  let FunVal f = interp e ef
      x        = interp e ex
  in f x                              -- application to lambda terms
interp e (Abs name expr) =
  -- augmentation of a local (lexical) environment
  FunVal (\value -> interp (addEnv name value e) expr)

addEnvযখন আমরা একটি নতুন নাম দিয়ে পরিবেশকে বাড়িয়ে তুলি তখন গুরুত্বপূর্ণ অংশটি লক্ষ্য করা যায় । এই ফাংশনটিকে ব্যাখ্যা করা Absট্র্যাকশন টার্মের (ল্যাম্বডা টার্ম) কেবল "ভিতরে" বলা হয় " যখনই আমরা কোনও Varশব্দটির মূল্যায়ন করি তখনই পরিবেশ "আপ" হয়ে যায় এবং তাই Varএর Nameমধ্যে Envযেটি উল্লেখ করা হয়েছে তাতে Absসংশ্লেষটি এতে থাকা ট্রেস দ্বারা ধরা পড়ে Var

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

এটিও (প্রায়) খাঁটি। আমাদের ল্যাম্বডা ক্যালকুলাসের যে কোনও পদটির একমাত্র অর্থ তার ফেরতের মান দ্বারা নির্ধারিত হয়। একমাত্র ব্যতিক্রম হ'ল অ-সমাপ্তির পার্শ্ব-প্রতিক্রিয়া যা ওমেগা শব্দটির দ্বারা প্রতিপন্ন হয়েছে:

-- in simple LC syntax:
--
-- (\x -> (x x)) (\x -> (x x))
omega :: Expr
omega = App (Abs "x" (App (Var "x") 
                          (Var "x")))
            (Abs "x" (App (Var "x") 
                          (Var "x")))

আকর্ষণীয় (অপরিষ্কার) বন্ধ

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

> function mk_counter() {
  var n = 0;
  return function incr() {
    return n += 1;
  }
}
undefined

> var c = mk_counter()
undefined
> c()
1
> c()
2
> c()
3

এটি প্রমাণ করে যে আমরা nঅভ্যন্তরীণ ফাংশনটিতে ভেরিয়েবলটি বন্ধ করে দিয়েছি incrএবং কলিং incrঅর্থপূর্ণভাবে সেই ভেরিয়েবলের সাথে ইন্টারেক্ট করে। mk_counterখাঁটি, তবে incrএটি অশুচি (এবং রেফারেন্সিয়ালি স্বচ্ছ নয়)

এই দুটি দৃষ্টান্তের মধ্যে কী পার্থক্য রয়েছে?

"পরিবর্তনশীল" ধারণা

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

অনেকের কাছে এটি "ভেরিয়েবল" এর অর্থ হ'ল। প্রকরণ। তবে, শব্দার্থবিজ্ঞানীরা এলসিতে ব্যবহৃত ভেরিয়েবল এবং জাভাস্ক্রিপ্টে ব্যবহৃত "ভেরিয়েবল" ধরণের মধ্যে পার্থক্য করতে পছন্দ করেন। এটি করার জন্য, তারা পরবর্তীকে একটি "পরিবর্তনীয় সেল" বা "স্লট" বলে অভিহিত করে।

এই নামকরণটি গণিতের "পরিবর্তনশীল" এর দীর্ঘ historicalতিহাসিক ব্যবহার অনুসরণ করে যেখানে এটি "অজানা" এর মতো আরও কিছু বোঝায়: (গাণিতিক) এক্সপ্রেশন "x + x" xসময়ের সাথে পরিবর্তিত হতে দেয় না , পরিবর্তে এর অর্থ নির্বিশেষে অর্থ বোঝাতে বোঝানো হয় এর (একক, ধ্রুবক) মান xলাগে।

সুতরাং, আমরা "স্লট" বলি মানগুলিকে স্লটে রাখার এবং এগুলি নেওয়ার ক্ষমতাকে জোর দেওয়ার জন্য।

বিভ্রান্তিতে আরও যোগ করার জন্য, জাভাস্ক্রিপ্টে এই "স্লটগুলি" ভেরিয়েবলের মতো দেখতে পাওয়া যায়: আমরা লিখি

var x;

একটি তৈরি করতে এবং তারপরে যখন আমরা লিখি

x;

এটি আমাদের সেই স্লটে বর্তমানে সঞ্চিত মান সন্ধান করার ইঙ্গিত দেয়। এটি আরও পরিষ্কার করার জন্য, খাঁটি ভাষাগুলি স্লটকে (গাণিতিক, ল্যাম্বডা ক্যালকুলাস) নাম হিসাবে নেওয়ার কথা ভাবেন। এই ক্ষেত্রে আমাদের যখন স্লট পাওয়া বা রাখা হয় তখন আমাদের স্পষ্টভাবে লেবেল করতে হবে। এই জাতীয় স্বরলিপি দেখতে দেখতে ঝোঁক

-- create a fresh, empty slot and name it `x` in the context of the 
-- expression E
let x = newSlot in E

-- look up the value stored in the named slot named `x`, return that value
get x

-- store a new value, `v`, in the slot named `x`, return the slot
put x v

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

এই স্বরলিপিটি ব্যবহার করে আমরা mk_counterউদাহরণটি পুনরায় লিখতে পারি (এবার হাসকলের মতো সিনট্যাক্সে, যদিও সিদ্ধান্তহীনভাবে অ-হাস্কেলের মতো শব্দার্থক):

mkCounter = 
  let x = newSlot 
  in (\() -> let old = get x 
             in get (put x (old + 1)))

এক্ষেত্রে আমরা এমন পদ্ধতি ব্যবহার করছি যা এই পরিবর্তনযোগ্য স্লটটিকে ব্যবহার করে। এটি বাস্তবায়নের জন্য আমাদের কেবল নামের মতো ধ্রুবক পরিবেশকেই বন্ধ করতে হবে না xতবে প্রয়োজনীয় সমস্ত স্লট যুক্ত একটি পরিবর্তনীয় পরিবেশও বন্ধ করতে হবে। এটি "ক্লোজার" লোকেদের এত ভালবাসার সাধারণ ধারণার কাছাকাছি।

আবার, mkCounterখুব অপরিষ্কার। এটি খুব রেফারেন্সালি অস্বচ্ছও। তবে লক্ষ্য করুন যে নাম ক্যাপচার বা বন্ধ হওয়া থেকে পার্শ্ব-প্রতিক্রিয়াগুলি উত্থাপিত হয় না বরং পরিবর্তে পরিবর্তনীয় সেলটি ক্যাপচার করে এবং এর উপর পার্শ্ব-কার্যকারী অপারেশনগুলি পছন্দ করে getএবং put

শেষ পর্যন্ত, আমি মনে করি এটিই আপনার প্রশ্নের চূড়ান্ত উত্তর: বিশুদ্ধতা (গাণিতিক) ভেরিয়েবল ক্যাপচার দ্বারা প্রভাবিত হয় না বরং পরিবর্তে ক্যাপচারযুক্ত ভেরিয়েবলগুলির দ্বারা নাম পরিবর্তনশীল স্লটগুলিতে পার্শ্ব-প্রতিক্রিয়াশীল অপারেশন দ্বারা।

এটি কেবলমাত্র সেই ভাষাগুলিতে যেগুলি এলসির নিকটবর্তী হওয়ার চেষ্টা করে না বা বিশুদ্ধতা বজায় রাখার চেষ্টা করে না যে এই দুটি ধারণাগুলি প্রায়শই বিভ্রান্তির কারণ হয়ে থাকে confusion


1

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

মনে রাখবেন যে আপনি সর্বদা পরিবর্তে একটি যুক্তি হিসাবে একটি মান পাস করতে পারেন, সাধারণত আপনি যথেষ্ট পরিমাণে অসুবিধা ছাড়াই এটি করতে পারবেন না। উদাহরণস্বরূপ (coffeescript):

closedValue = 42
return (arg) -> console.log "#{closedValue} #{arg}"

আপনার পরামর্শ অনুসারে, আপনি কেবল ফিরে আসতে পারেন:

return (arg, closedValue) -> console.log "#{closedValue} #{arg}"

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

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

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