ক্লোজার প্রোটোকলের সহজ ব্যাখ্যা


131

আমি ক্লোজার প্রোটোকলগুলি বোঝার চেষ্টা করছি এবং তাদের কোন সমস্যার সমাধান করার কথা রয়েছে। ক্লোজার প্রোটোকলগুলি কী এবং কীসের স্পষ্ট ব্যাখ্যা কারও কাছে রয়েছে?


7
Clojure 1.2 27 মিনিটের মধ্যে প্রোটোকল্স: vimeo.com/11236603
miku

3
প্রোটোকলগুলির খুব নিকটতম উপমা স্কেলায় ট্রেইটস (মিক্সিনস): স্ট্যাকওভারফ্লো
ভাসিল রেমেনিয়ুক

উত্তর:


284

ক্লোজারে প্রোটোকলগুলির উদ্দেশ্য হ'ল এক্সপ্রেশন সমস্যাটি একটি দক্ষ পদ্ধতিতে সমাধান করা।

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

এক্সপ্রেশন সমস্যাটি হল, আপনি কীভাবে কোনও ভাষায় এই জাতীয় এক্সটেনসিবিলিটি প্রদান করবেন?

এটি প্রমাণিত হয়েছে যে পদ্ধতিগত এবং / বা কার্যকরী প্রোগ্রামিংয়ের সাধারণ নিখুঁত বাস্তবায়নের জন্য, নতুন ক্রিয়াকলাপগুলি (পদ্ধতি, ফাংশন) যুক্ত করা খুব সহজ তবে নতুন ডেটা ধরণের যুক্ত করা খুব শক্ত, যেহেতু মূলত অপারেশনগুলি কিছু ব্যবহার করে ডেটা ধরণের সাথে কাজ করে ধরণের ক্ষেত্রে বৈষম্য ( switch, caseপ্যাটার্ন মেলানো) এবং আপনার সেগুলিতে নতুন কেস যুক্ত করা দরকার, অর্থাৎ বিদ্যমান কোডটি সংশোধন করুন:

func print(node):
  case node of:
    AddOperator => print(node.left) + '+' + print(node.right)
    NotOperator => '!' + print(node)

func eval(node):
  case node of:
    AddOperator => eval(node.left) + eval(node.right)
    NotOperator => !eval(node)

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

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

class AddOperator(left: Node, right: Node) < Node:
  meth print:
    left.print + '+' + right.print

  meth eval
    left.eval + right.eval

class NotOperator(expr: Node) < Node:
  meth print:
    '!' + expr.print

  meth eval
    !expr.eval

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

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

নোট করুন যে ক্লোজুরে আসলে ইতিমধ্যে এক্সপ্রেশন সমস্যা: মাল্টিমিডাডস সমাধান করার জন্য একটি ব্যবস্থা আছে । ইপি-র সাথে ওওর সমস্যাটি হ'ল তারা একত্রে অপারেশন এবং প্রকারগুলি বান্ডিল করে। মাল্টিমেডথডসের সাথে তারা পৃথক। এফপির সমস্যাটি হ'ল তারা একত্রে অপারেশন এবং কেস বৈষম্যকে বান্ডিল করে। আবার, মাল্টিম্যাথডসের সাথে তারা পৃথক।

সুতরাং, আসুন আমরা মাল্টিমেডথডসের সাথে প্রোটোকলগুলি তুলনা করি, যেহেতু উভয়ই একই কাজ করে। অথবা, এটা অন্য উপায় করা হবে: কেন প্রোটোকল্স ইতিমধ্যে আমরা যদি আছে Multimethods?

মাল্টিমিডেডসের উপরে প্রোটোকলগুলির প্রধান জিনিস হ'ল গ্রুপিং: আপনি একসাথে একাধিক ফাংশনকে গ্রুপ করতে পারেন এবং বলতে পারেন "এই 3 টি ফাংশন একসাথে প্রোটোকল গঠন করে Foo"। মাল্টিমেডথডসের সাহায্যে আপনি এটি করতে পারবেন না, তারা সর্বদা নিজেরাই দাঁড়ায়। উদাহরণস্বরূপ, আপনি ঘোষণা করতে পারেন যে একটি Stackপ্রোটোকল এক এবং একটি ফাংশন উভয় সমন্বিত করেpushpop

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

ক্লোজার একটি আয়োজিত ভাষা। অর্থাৎ এটি বিশেষত অন্য ভাষার প্ল্যাটফর্মের শীর্ষে চালিত করার জন্য ডিজাইন করা হয়েছে । এবং এটি প্রমাণিত হয়েছে যে ক্লোজিউর (জেভিএম, সিএলআই, ইসিএমএসক্রিপট, অবজেক্টিভ-সি) চালাতে চান এমন কোনও প্ল্যাটফর্ম কেবলমাত্র প্রথম আর্গুমেন্টের ধরণে প্রেরণের জন্য উচ্চ-পারফরম্যান্স সমর্থন বিশেষীকরণ করেছে । Clojure Multimethods OTOH উপর প্রাণবধ নির্বিচারে বৈশিষ্ট্য এর সব আর্গুমেন্ট

সুতরাং, প্রোটোকল আপনি প্রাণবধ সীমিত শুধুমাত্র উপর প্রথম যুক্তি এবং শুধুমাত্র (তার ধরনের উপর বা একটি বিশেষ কেস হিসাবেnil )।

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

Seqউদাহরণস্বরূপ ক্লোজুরে সংস্করণ 1.0 থেকে প্রোটোকলগুলি ইতিমধ্যে রয়েছে: এটি একটি প্রোটোকল। তবে ১.২ অবধি ক্লোজুরে আপনি প্রোটোকল লিখতে পারেননি, আপনাকে সেগুলি হোস্ট ভাষায় লিখতে হয়েছিল।


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

3
এক্সপ্রেশন সমস্যা এবং ক্লোজারের
ডেভেলপ

এইরকম একটি পুরানো উত্তরে মন্তব্য পোস্ট করার জন্য দুঃখিত তবে এক্সটেনশন এবং ইন্টারফেস (সি # / জাভা) এক্সপ্রেশন সমস্যাটির কেন ভাল সমাধান নয় তা আপনি বিস্তারিতভাবে বলতে পারেন?
ওনোরিও ক্যাটানাচি

এই শব্দটি এখানে ব্যবহৃত হয়েছে এমন অর্থে জাভার এক্সটেনশন নেই।
ব্যবহারকারী 100464

রুবির সংশোধন রয়েছে যা বানরের প্যাচিংকে অচল করে দেয়।
মার্সিন বিলস্কি

64

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

একটি উদাহরণ:

(defprotocol my-protocol 
  (foo [x]))

"Foo" নামে একটি ফাংশন সহ একটি প্রোটোকল সংজ্ঞা দেয় যা একটি প্যারামিটার "x" এ কাজ করে acts

এরপরে আপনি ডেটা স্ট্রাকচার তৈরি করতে পারেন যা প্রোটোকল প্রয়োগ করে, যেমন

(defrecord constant-foo [value]  
  my-protocol
    (foo [x] value))

(def a (constant-foo. 7))

(foo a)
=> 7

নোট করুন যে এখানে প্রোটোকল প্রয়োগকারী অবজেক্টটি প্রথম প্যারামিটার হিসাবে পাস করা হয়েছে x - কিছুটা অবজেক্ট ওরিয়েন্টেড ভাষায় অন্তর্ভুক্ত "এই" পরামিতিগুলির মতো।

প্রোটোকলগুলির খুব শক্তিশালী এবং দরকারী বৈশিষ্ট্যগুলির মধ্যে একটি হ'ল আপনি সেগুলিকে বস্তুগুলিতে প্রসারিত করতে পারেন এমনকি যদি বস্তুটি মূলত প্রোটোকল সমর্থন করার জন্য তৈরি করা হয়নি । উদাহরণস্বরূপ আপনি java.lang.String ক্লাসে উপরের প্রোটোকলটি প্রসারিত করতে পারেন যদি আপনি চান:

(extend-protocol my-protocol
  java.lang.String
    (foo [x] (.length x)))

(foo "Hello")
=> 5

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