বাঁধাই কেন বেশিরভাগ ভাষায় একটি স্থানীয় বৈশিষ্ট্য নয়?


11

আইএমএইচও একটি পরিবর্তনশীলকে অন্য পরিবর্তনশীল বা একটি অভিব্যক্তিটির সাথে বাঁধাই গণিতের একটি খুব সাধারণ দৃশ্য scenario আসলে, শুরুতে, অনেক শিক্ষার্থী মনে করে যে অ্যাসাইনমেন্ট অপারেটর (=) একরকম বাধ্যতামূলক। তবে বেশিরভাগ ভাষায়, বাঁধাই স্থানীয় বৈশিষ্ট্য হিসাবে সমর্থিত নয়। সি # এর মতো কিছু ভাষায়, কিছু শর্ত পূরণ করে কিছু ক্ষেত্রে বাঁধাই সমর্থন করা হয়।

তবে আইএমএইচও এটির একটি স্থানীয় বৈশিষ্ট্য হিসাবে প্রয়োগ করে নিম্নলিখিত কোডগুলি পরিবর্তন করার মতোই সহজ ছিল-

int a,b,sum;
sum := a + b;
a = 10;
b = 20;
a++;

এই-

int a,b,sum;
a = 10;
sum = a + b;
b = 20;
sum = a + b;
a++;
sum = a + b;

অর্থ হ'ল বাধ্যতামূলক নির্দেশকে প্রতিটি নির্দেশের পরে অ্যাসাইনমেন্ট হিসাবে ডান পাশের এক্সপ্রেশনটিতে থাকা যেকোন ভেরিয়েবলের মান পরিবর্তন করে। এর পরে, ছাঁটাই অনর্থক নির্দেশাবলী (বা সংকলনের পরে সমাবেশে অপ্টিমাইজেশন) করবে।

সুতরাং, কেন এটি বেশিরভাগ ভাষায় স্থানীয়ভাবে সমর্থিত নয়। বিশেষ করে ভাষার সি-পরিবারে?

হালনাগাদ:

বিভিন্ন মতামত থেকে, আমি মনে করি আমার প্রস্তাবিত "বাঁধাই" আরও বিশদভাবে সংজ্ঞায়িত করা উচিত-

  • এটি এক উপায় বাঁধাই। কেবল সমষ্টিটি একটি বি + এর সাথে আবদ্ধ, বিপরীতে নয়।
  • বাইন্ডিংয়ের সুযোগ স্থানীয়।
  • বাঁধাই একবার প্রতিষ্ঠিত হয়ে গেলে, এটি পরিবর্তন করা যাবে না। অর্থ, একবার যোগফল a + b তে আবদ্ধ হলে যোগফল সর্বদা একটি + বি হবে।

আশা করি ধারণাটি এখন আরও পরিষ্কার হবে।

আপডেট 2:

আমি কেবল এই পি # বৈশিষ্ট্যটি চেয়েছিলাম । ভবিষ্যতে এটি হবে আশা করি।


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

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

2
এটির জন্য মূল্যবান, এই ধরণের প্রোগ্রাম্যাটিক দৃষ্টিভঙ্গিটি বাড়ছে: প্রতিক্রিয়াশীল প্রোগ্রামিং। আপনি যা বর্ণনা করছেন তা স্প্রেডশিট প্রোগ্রাম যেমন ম্যাক্সেল এক্সেল দ্বারা মূর্ত হয় যা স্টেরয়েডগুলিতে মূলত ডেটা বাঁধাই (বা প্রতিক্রিয়াশীল প্রোগ্রামিং)।
মাইক রোজেনব্লুম

11
এটা তোলে "সবচেয়ে" প্রোগ্রামিং ভাষার একটি বৈশিষ্ট্য নাও হতে পারে, কিন্তু এটা হয় এর একটি বৈশিষ্ট্য সবচেয়ে জনপ্রিয় প্রোগ্রামিং ভাষা: এক্সেল।
জার্গ ডব্লু মিট্টাগ

2
অভিব্যক্তি গাছের জন্য ধন্যবাদ, এটি সি # তে ইতিমধ্যে সম্ভব। আমি গতকাল এটি সম্পর্কে ব্লগ করেছি: হ্যাপিডনোমড 121.blogspot.com/2013/01/…
শুভনোমাদ

উত্তর:


9

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

আপনাকে বিবেচনা করতে হবে যে এটি সর্বদা আপনি চান তা নয়। অনেক লোক লুপগুলিতে তৈরি ক্লোজার দ্বারা দংশিত হয় বিশেষত কারণ ক্লোজারগুলি পরিবর্তনশীল রাখে, কোনও স্থানে এর মানের একটি অনুলিপি থাকে না, অর্থাৎ for (i = 0; i < 10; i++) { var f = function() { return i; }; /* store f */ }দশটি ক্লোজার তৈরি করে যা ফিরে আসে 9। সুতরাং আপনাকে উভয় উপায়ে সমর্থন করতে হবে - যার অর্থ "জটিলতা বাজেট" এর দ্বিগুণ এবং অন্য অপারেটরটি। কোডটি ব্যবহার করে এবং এটি ব্যবহার না করে কোডের মধ্যে সম্ভবত অসুবিধাগুলি যদি না টাইপ সিস্টেমটি যথেষ্ট পরিশীলিত হয় (আরও জটিলতা!)।

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

দ্রষ্টব্য যে প্রতিক্রিয়াশীল প্রোগ্রামিং মূলত এটি সম্পর্কে (যতদূর আমি বলতে পারি), তাই এটি বিদ্যমান। এটি কেবল প্রচলিত প্রোগ্রামিং ভাষায় সাধারণ নয় common এবং আমি পূর্ববর্তী অনুচ্ছেদে তালিকাভুক্ত কয়েকটি বাস্তবায়ন সমস্যাগুলি সমাধান করা বাজি রেখেছি।


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

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

আমাদের বাক্সে কেন আরও একটি সরঞ্জাম নেই? কোনও সরঞ্জাম উপস্থিত হয়ে গেলে লোকেরা এটি ব্যবহার করবে। একটি প্রশ্ন. সি বা সি ++ এর মতো কিছু ভাষা যদি এই বৈশিষ্ট্যটি বাস্তবায়িত করতে এবং আপনার মতামত জানতে চায়, আপনি কি বলবেন, "এটি দেবেন না Because কারণ এটি আপনার পক্ষে খুব কঠিন হবে এবং লোকেরা এ নিয়ে বিভ্রান্ত হবে?"
গুলশান

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

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

3

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


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

তাতে কিছু যায় আসে না। প্রতিবার আপনি যখন লিখছেন aবা লিখছেন তখন আপনার ব্যবহৃত bপ্রতিটি একক স্থানে এর প্রভাব বিবেচনা করতে হবে sumএবং আপনি যে জায়গাগুলি পড়েছেন sumতা আপনাকে কী aএবং bকী করছে তা বিবেচনা করা উচিত । তুচ্ছ-বিহীন মামলার ক্ষেত্রে এটি জটিল হয়ে উঠতে পারে, বিশেষত যদি আসল অভিব্যক্তিটি sumরানটাইমের সময় পরিবর্তন করতে পারে।
jprete

আমি এই নিয়মটি সুপারিশ করব যে বাঁধাইয়ের পরে বাঁধাইয়ের ভাবটি পরিবর্তন করা যায় না। এমনকি নিয়োগ অসম্ভব হবে। এটি একবারে একটি অভিব্যক্তি আবদ্ধ একটি অর্ধ ধ্রুবক মত হবে। এর অর্থ, একবারের যোগফলটি একটি + বিতে আবদ্ধ হয়ে গেলে, প্রোগ্রামের বাকি অংশে এটি সর্বদা একটি + বি হবে।
গুলশান

3

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

আইওডাব্লু, আমি লিখেছি জাভাস্ক্রিপ্টের ~ 3000 লাইনের অনেকগুলি অবজেক্টগুলি সনাক্ত করা ছাড়া কিছুই করে না। প্রতিক্রিয়াশীল প্রোগ্রামিং অল্প ব্যয়ে এগুলি করতে পারে; এবং কোড লাইন একটি বিশাল হ্রাস এ।

আপনি যদি না যে সম্পর্কে কি মনে করেন? হ্যাঁ, আমি লক্ষ্য করেছি যে আমার টেবিলটিতে প্রচুর স্প্রেডশিট-জাতীয় বৈশিষ্ট্য রয়েছে।


3

আমি মনে করি আপনি যা বর্ণনা করছেন তাকে স্প্রেডশিট বলা হয়:

A1=5
B1=A1+1
A1=6

... তারপরে B1রিটার্ন মূল্যায়ন 7।

সম্পাদনা

সি ভাষাটিকে কখনও কখনও "বহনযোগ্য সমাবেশ" বলা হয়। এটি একটি অপরিহার্য ভাষা, যেখানে স্প্রেডশিট ইত্যাদি etc.ণাত্মক ভাষাগুলি। আপনি যখন পরিবর্তন করবেন তখন পুনর্নির্মাণের জন্য বলা B1=A1+1এবং প্রত্যাশা B1করা A1নিশ্চিতভাবেই ঘোষিত। ঘোষিত ভাষাগুলি (যার মধ্যে কার্যকরী ভাষাগুলি একটি উপসেট) সাধারণত উচ্চ স্তরের ভাষা হিসাবে বিবেচিত হয়, কারণ তারা হার্ডওয়্যার কীভাবে কাজ করে তার থেকে অনেক দূরে।

সম্পর্কিত নোটে, মই লজিকের মতো অটোমেশন ভাষা সাধারণত ঘোষণামূলক decla যদি আপনি এমন একটি যুক্তি লেখেন যা বলে যে output A = input B OR input Cএটি ক্রমাগত সেই বিবৃতিটির পুনরায় মূল্যায়ন করতে চলেছে, এবং Aযখনই পরিবর্তন হবে Bবা Cপরিবর্তিত হতে পারে। ফাংশন ব্লক ডায়াগ্রামের মতো অন্যান্য অটোমেশন ভাষাগুলি (যা আপনি সিমুলিংক ব্যবহার করে থাকলে আপনার সাথে পরিচিত হতে পারে) এছাড়াও তা ঘোষণামূলক এবং ক্রমাগত কার্যকর করা হয়।

কিছু (এম্বেডেড) অটোমেশন সরঞ্জাম সি তে প্রোগ্রামিং করা হয় এবং এটি যদি রিয়েল-টাইম সিস্টেম হয় তবে এটির মধ্যে সম্ভবত একটি অসীম লুপ রয়েছে যা মই যুক্তিটি কার্যকর করে তার অনুরূপ লজিকটিকে পুনরায় কার্যকর করে- সেক্ষেত্রে আপনার মূল লুপের ভিতরে আপনি লিখতে পারেন:

A = B || C;

... এবং যেহেতু এটি সর্বদা কার্যকর করা হয়, এটি ঘোষণামূলক হয়ে যায়। Aক্রমাগত পুনরায় মূল্যায়ন করা হবে।


3

সি, সি ++, উদ্দেশ্য-সি:

ব্লকগুলি আপনি সন্ধান করছেন এমন বাধ্যতামূলক বৈশিষ্ট্য সরবরাহ করে।

আপনার উদাহরণে:

যোগফল: = a + b;

আপনি সেটিং করছি sumএক্সপ্রেশন a + bএকটি প্রেক্ষাপটে যেখানে aএবং bভেরিয়েবল বিদ্যমান করছে। আপনি সি, সি ++, বা অ্যাপল এর এক্সটেনশন (পিডিএফ) সহ অবজেক্টিভ-সিতে "ব্লক" (ওরফে ক্লোজার, ওরফে ল্যাম্বডা এক্সপ্রেশন) দিয়ে ঠিক এটি করতে পারেন :

__block int a = 0, b = 0;           // declare a and b
int (^sum)(void);                   // declare sum
sum = ^(void){return a + b;};       // sum := a + b

এটি sumএমন একটি ব্লকে সেট করে যা a এবং b এর যোগফল দেয়। __blockস্টোরেজ শ্রেণী সুনির্দিষ্টভাবে উল্লেখ করা ইঙ্গিত দেয় যে abপরিবর্তন হতে পারে। উপরের দিক থেকে দেওয়া, আমরা নিম্নলিখিত কোডটি চালাতে পারি:

printf("a=%d\t b=%d\t sum=%d\n", a, b, sum());
a = 10;
printf("a=%d\t b=%d\t sum=%d\n", a, b, sum());
b = 32;
printf("a=%d\t b=%d\t sum=%d\n", a, b, sum());
a++;
printf("a=%d\t b=%d\t sum=%d\n", a, b, sum());

এবং আউটপুট পেতে:

a=0      b=0     sum=0
a=10     b=0     sum=10
a=10     b=32    sum=42
a=11     b=32    sum=43

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


2

সি ++

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

#include <iostream>

template <class R, class A, class B>
class Binding {
public:
    typedef R (*BinOp)(A, B);
    Binding (A &x, B &y, BinOp op)
        : op(op)
        , rx(x)
        , ry(y)
        , useCache(false)
    {}
    R value () const {
        if (useCache && x == rx && y == ry) {
            return cache;
        }
        x = rx;
        y = ry;
        cache = op(x, y);
        useCache = true;
        return cache;
    }
    operator R () const {
        return value();
    }
private:
    BinOp op;
    A &rx;
    B &ry;
    mutable A x;
    mutable B y;
    mutable R cache;
    mutable bool useCache;
};

int add (int x, int y) {
    return x + y;
}

int main () {
    int x = 1;
    int y = 2;
    Binding<int, int, int> z(x, y, add);
    x += 55;
    y *= x;
    std::cout << (int)z;
    return 0;
}

যদিও এটি প্রশ্নের উত্তর দেয় না, আপনার উপস্থাপিত ধারণাটি আমার পছন্দ হয়। আরও জেনেরিক সংস্করণ থাকতে পারে?
গুলশান

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