ওকামল / এফ # এ ফাংশন কেন ডিফল্টরূপে পুনরাবৃত্ত হয় না?


105

কেন এটি F # এবং Ocaml (এবং সম্ভবত অন্যান্য ভাষাগুলিতে) ফাংশনগুলি ডিফল্ট পুনরাবৃত্তি নয়?

অন্য কথায়, ভাষা ডিজাইনাররা কেন সিদ্ধান্ত নেন যে আপনাকে স্পষ্টভাবে recকোনও ঘোষণায় টাইপ করা ভাল ধারণা ছিল :

let rec foo ... = ...

এবং ফাংশনটি ডিফল্টরূপে পুনরাবৃত্তির ক্ষমতা দেয় না? কেন একটি সুস্পষ্ট recনির্মাণ প্রয়োজন?


উত্তর:


88

মূল এমএল-এর ফরাসি এবং ব্রিটিশ বংশধরগণ বিভিন্ন পছন্দ করেছেন এবং তাদের পছন্দগুলি দশকগুলিতে আধুনিক রূপগুলিতে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে। সুতরাং এটি কেবল উত্তরাধিকার তবে এটি এই ভাষাগুলিতে আইডিয়ামগুলিকে প্রভাবিত করে।

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

উদাহরণস্বরূপ, ওসিএএমএলে pএকটি সিকোয়েন্সের শ্যানন এনট্রপি গণনা করার সময় ফাংশনটি সুপারসেসিং করা:

let shannon fold p =
  let p x = p x *. log(p x) /. log 2.0 in
  let p t x = t +. p x in
  -. fold p 0.0

নোটটি কীভাবে pউচ্চ-আদেশ shannonক্রিয়াকলাপের দ্বারা pদেহের প্রথম লাইনে অন্য এবং পরে অন্যটির pদ্বারা শরীরের দ্বিতীয় লাইনে যুক্ত করা হয় তা নোট করুন ।

বিপরীতে, ভাষাগুলির এমএল পরিবারের ব্রিটিশ এসএমএল শাখা অন্য পছন্দটি গ্রহণ করেছিল এবং এসএমএলের funবাউন্ড ফাংশনগুলি ডিফল্টরূপে পুনরাবৃত্ত হয়। যখন বেশিরভাগ ফাংশন সংজ্ঞাগুলিতে তাদের ফাংশন নামের পূর্বের বাইন্ডিংগুলিতে অ্যাক্সেসের প্রয়োজন হয় না, এর ফলে সহজ কোড আসে। যাইহোক, সংযোজন ফাংশন (বিভিন্ন নাম ব্যবহার করা হয় f1, f2ঘটনাক্রমে একটি ফাংশন ভুল "সংস্করণ" ডাকা ইত্যাদি) যা সুযোগ দূষিত এবং এটা সম্ভব করে তোলে। এবং এখন অন্তর্নিহিত-পুনরাবৃত্ত- funবাউন্ড ফাংশন এবং নন-রিকার্সিভ-বাউন্ড ফাংশনগুলির মধ্যে একটি তাত্পর্য রয়েছে val

হাস্কেল সংশোধনকে বিশুদ্ধ হতে সীমাবদ্ধ করে সংজ্ঞাগুলির মধ্যে নির্ভরতা নির্ধারণ করা সম্ভব করে তোলে। এটি খেলনা নমুনাগুলি সহজ দেখায় কিন্তু অন্যত্র গুরুতর খরচে আসে।

নোট করুন যে গণেশ এবং এডি প্রদত্ত উত্তরগুলি লাল হেরিংস। তারা ব্যাখ্যা করেছেন যে ফাংশনগুলির গ্রুপগুলি দৈত্যের ভিতরে কেন রাখা যায় না let rec ... and ...কারণ টাইপ ভেরিয়েবলগুলি সাধারণীকরণ করা হলে এটি প্রভাবিত করে। recএসএমএলে ডিফল্ট হওয়ার সাথে এটি ওসিএএমএল এর সাথে কিছুই করার নেই ।


4
আমি মনে করি না যে এগুলি লাল রঙের হেরিংস: যদি এটি অনুমানের উপর নিষেধাজ্ঞাগুলি না হয় তবে সম্ভবত অন্যান্য প্রোগ্রামের মতো পুরো প্রোগ্রাম বা মডিউলগুলি পারস্পরিক পুনরাবৃত্ত হিসাবে বিবেচিত হবে। এটি "রেক" কে মোট লাগাতে হবে কিনা তা সুনির্দিষ্ট নকশার সিদ্ধান্ত নেবে।
জিএস -

"... অন্যান্য ভাষার মতোই স্বয়ংক্রিয়ভাবে পারস্পরিক পুনরাবৃত্ত হিসাবে বিবেচিত"। বেসিক, সি, সি ++, ক্লোজার, এরলং, এফ #, ফ্যাক্টর, ফরথ, ফোর্টরান, গ্রোভী, ওক্যামেল, পাসকাল, স্মলটাক এবং স্ট্যান্ডার্ড এমএল নেই।
জেডি

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

4
"সি / সি ++ এর জন্য কেবল অগ্রবর্তী সংজ্ঞাগুলির জন্য প্রোটোটাইপগুলির প্রয়োজন হয়, যা স্পষ্টভাবে পুনরাবৃত্তি চিহ্নিত করার বিষয়ে নয়"। শুধুমাত্র স্ব-পুনরাবৃত্তির বিশেষ ক্ষেত্রে। পারস্পরিক পুনরাবৃত্তির সাধারণ ক্ষেত্রে, সি এবং সি ++ উভয় ক্ষেত্রেই ফরওয়ার্ড ঘোষণাগুলি বাধ্যতামূলক।
জেডি

4
ক্লাস স্কোপগুলিতে প্রকৃতপক্ষে ফরওয়ার্ড ডিক্লেয়ারেশনগুলি সি ++ তে প্রয়োজন হয় না, অর্থাত্ স্ট্যাটিক পদ্ধতিগুলি কোনও ঘোষণা ছাড়াই একে অপরকে কল করা ঠিক।
polkovnikov.ph

52

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

আপনার যদি সংজ্ঞা থাকে তবে আপনি let f x = xএটি টাইপ করতে 'a -> 'aএবং 'aবিভিন্ন পয়েন্টে বিভিন্ন ধরণের ক্ষেত্রে প্রযোজ্য তা প্রত্যাশা করবেন । তবে সমানভাবে, যদি আপনি লিখেন let g x = (x + 1) + ..., আপনি আশা xকরবেন intযে শরীরের বাকি অংশগুলিতে একটি হিসাবে বিবেচিত হবে g

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

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

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


4
এর, না। আপনার প্রথম অনুচ্ছেদটি ভুল (আপনি "এবং" এর স্পষ্ট ব্যবহার সম্পর্কে কথা বলছেন এবং "রেক" নয়) এবং ফলস্বরূপ, বাকীটি অপ্রাসঙ্গিক।
জেডি

5
এই প্রয়োজনে আমি কখনই সন্তুষ্ট হই নি। ব্যাখ্যার জন্য ধন্যবাদ. হাস্কেল ডিজাইনে উন্নত হওয়ার আরেকটি কারণ।
বেন্ট রাসমুসেন

9
না !!!! এটা কিভাবে হতে পারে? এটা যেভাবে হতে পারে?! এই উত্তরটি সরল ভুল! দয়া করে নীচে হ্যারোপের উত্তরটি পড়ুন বা স্ট্যান্ডার্ড এমএল (মিলনার,
তোফ্টে

9
আমি আমার উত্তর বলেন, টাইপ অনুমান বিষয় এক Rec প্রয়োজনীয়তার কারণ, যেমন একমাত্র কারণ হচ্ছে বিরোধিতা। জনের উত্তরটিও একটি খুব বৈধ উত্তর (হাস্কেল সম্পর্কে সাধারণ স্নাইড মন্তব্য বাদে); আমি মনে করি না যে দু'পক্ষের বিরোধিতা আছে।
জিএস -

16
"টাইপ অনুমানের ইস্যুটি rec এর প্রয়োজনীয়তার অন্যতম কারণ"। ওসিএএমএল এর প্রয়োজনীয়তা রয়েছে recতবে এসএমএল এর প্রকৃত পাল্টা উদাহরণ নয় example আপনার বর্ণনা করার কারণে যদি টাইপ ইনফারেন্সইস ইস্যু হত তবে ওসিএএমএল এবং এসএমএল তাদের মতো আলাদা সমাধান চয়ন করতে পারত না। কারণ অবশ্যই, আপনি andহাস্কেলকে প্রাসঙ্গিক করার জন্য কথা বলছেন ।
জেডি

10

দুটি ভাল কারণ এটি একটি ভাল ধারণা:

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

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


4

কিছু অনুমান:

  • letকেবলমাত্র ফাংশন বাঁধাই নয়, অন্যান্য নিয়মিত মানগুলিও ব্যবহৃত হয়। বেশিরভাগ মানগুলির পুনরাবৃত্তির অনুমতি নেই। রিকার্সিভ মানগুলির কয়েকটি ফর্ম অনুমোদিত (উদাহরণস্বরূপ ফাংশন, অলস প্রকাশ, ইত্যাদি), সুতরাং এটি সূচিত করার জন্য এটি একটি সুস্পষ্ট বাক্য গঠন প্রয়োজন।
  • অপরিবর্তিত ফাংশনগুলি অনুকূল করে তোলা আরও সহজ হতে পারে
  • যখন আপনি পুনরাবৃত্তি ফাংশন তৈরি করেন তখন তৈরি ক্লোজারটি একটি এন্ট্রি অন্তর্ভুক্ত করে যা ফাংশনটি নিজেই নির্দেশ করে (যাতে ফাংশনটি পুনরাবৃত্তভাবে নিজেকে কল করতে পারে), যা পুনরাবৃত্তির বন্ধকে অ-পুনরাবৃত্তির বন্ধ হওয়ার চেয়ে জটিল করে তোলে। সুতরাং যখন আপনার পুনরাবৃত্তি প্রয়োজন হবে না তখন সহজ সরল নন-রিকার্সিভ ক্লোজার তৈরি করতে সক্ষম হতে পারে it
  • এটি আপনাকে পূর্বনির্ধারিত ফাংশন বা একই নামের মান অনুসারে একটি ফাংশন সংজ্ঞায়িত করতে দেয়; যদিও আমি মনে করি এটি খারাপ অভ্যাস
  • অতিরিক্ত সুরক্ষা? আপনি যা ইচ্ছা করেছেন তা আপনি করছেন তা নিশ্চিত করে। উদাহরণস্বরূপ, যদি আপনি এটি পুনরাবৃত্তি করতে চান না তবে আপনি দুর্ঘটনাক্রমে ফাংশনটির ভিতরে একই নামটি ফাংশনটির মতো একটি নাম ব্যবহার করেছেন, তবে সম্ভবত এটি অভিযোগ করবে (নামটি আগে বর্ণিত না থাকলে)
  • letকনস্ট্রাক্ট অনুরূপ letপাতার মর্মর এবং স্কিম মধ্যে কনস্ট্রাক্ট; যা পুনরাবৃত্তিযোগ্য। letrecপুনরাবৃত্তির জন্য স্কিমে একটি পৃথক নির্মাণ রয়েছে

"বেশিরভাগ মানের মানকে পুনরাবৃত্ত হওয়ার অনুমতি নেই rec রিকার্সিভ মানগুলির কয়েকটি ফর্ম অনুমোদিত (যেমন ফাংশন, অলস প্রকাশ, ইত্যাদি), সুতরাং এটির ইঙ্গিত করার জন্য এটির একটি সুস্পষ্ট বাক্য গঠন প্রয়োজন"। এটি এফ # এর ক্ষেত্রে সত্য তবে আমি ওসিএএমএল যেখানে আপনি এটি করতে পারেন তা কতটা সত্য তা নিশ্চিত নই let rec xs = 0::ys and ys = 1::xs
জেডি

4

প্রদত্ত এই:

let f x = ... and g y = ...;;

তুলনা করা:

let f a = f (g a)

এর সাথে:

let rec f a = f (g a)

fপূর্বে সংজ্ঞা fপ্রয়োগের ফলাফলের সাথে পূর্বনির্ধারিত প্রয়োগ করতে পুনরায় সংজ্ঞা দেওয়া gহয় a। আধুনিক redefines fলুপ করতে চিরকাল আবেদন gকরতে a, যা সাধারণত নয় কি আপনি চান এমএল মধ্যে রূপগুলো।

বলেছিল, এটি একটি ভাষা ডিজাইনার স্টাইলের জিনিস। শুধু এটার সাথে যাও.


1

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

এটি স্কিমের গ্রেড সমতা পূর্বাভাসের অনুরূপ। (যেমন eq?, eqv?এবং equal?)

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