রিটার্নের ধরণের সাথে ওভারলোডিং কেন অনুমোদিত নয়? (কমপক্ষে সাধারণত ব্যবহৃত ভাষাগুলিতে)


9

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

আমি এরকম কিছু বোঝাতে চাইছি:

 int method1 (int num)
 {

 }
 long method1 (int num)
 {

 }

এটি প্রোগ্রামিংয়ের পক্ষে বড় সমস্যা নয় তবে কয়েকটি অনুষ্ঠানে আমি এটি স্বাগত জানাই।

স্পষ্টতই সেই ভাষাগুলির পক্ষে সমর্থন করার কোনও উপায় নেই যে কোনও পদ্ধতিটি কী বলা হচ্ছে তার পার্থক্য না করে, তবে এর বাক্য গঠনটি [int] মেথড 1 (নাম্বার) বা [দীর্ঘ] মেথড 1 (নাম্বার) এর মতো কোনও কিছুর মতো সহজ হতে পারে support এইভাবে সংকলকটি জানতে পারে কোনটি ডাকা হবে।

কম্পাইলাররা কীভাবে কাজ করে সে সম্পর্কে আমি জানি না তবে এটি করা এতটা কঠিন বলে মনে হচ্ছে না, তাই আমি ভাবছি যে কেন এমন কিছু সাধারণত প্রয়োগ করা হয় না।

এরকম কিছুকে সমর্থন না করার কারণগুলি কী?


আপনার প্রশ্নটি এমন উদাহরণের সাথে আরও ভাল হবে যেখানে দুটি রিটার্নের ধরণের মধ্যে অন্তর্নিহিত রূপান্তরগুলি নেই - যেমন ক্লাস Fooএবং Bar

আচ্ছা, এ জাতীয় বৈশিষ্ট্যটি কেন কার্যকর হবে?
জেমস ইয়ংম্যান

3
@ জেমস ইয়ংম্যান: উদাহরণস্বরূপ স্ট্রিংকে বিভিন্ন ধরণের পার্স করার জন্য আপনার কাছে একটি পদ্ধতি ইট রিড (স্ট্রিং গুলি), ফ্লাট রিড (স্ট্রিং) ইত্যাদি থাকতে পারে। পদ্ধতির প্রতিটি ওভারলোড হওয়া তারতম্য যথাযথ প্রকারের জন্য একটি পার্স সম্পাদন করে।
জর্জিও 21

এটি কেবলমাত্র স্থায়ীভাবে টাইপ করা ভাষাগুলির সাথে সম্পর্কিত। জাভা স্ক্রিপ্ট বা পাইথনের মতো গতিময় টাইপ করা ভাষাগুলিতে একাধিক রিটার্নের ধরণগুলি বেশ নিয়মিত।
রোবট

1
@ স্টিভেন বার্নাপ, উম, নং উদাহরণস্বরূপ জাভাস্ক্রিপ্ট সহ আপনি ফাংশন ওভারলোডিং মোটেই করতে পারবেন না। সুতরাং এটি আসলে ভাষাগুলির সাথে কেবল একটি সমস্যা যা ফাংশন নাম ওভারলোডিং সমর্থন করে।
ডেভিড আরনো

উত্তর:


19

এটি টাইপ চেকিংয়ে জটিল করে তোলে।

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

var x = f();

given      f   : () -> int  [upward]
given      ()  : ()         [upward]
therefore  f() : int        [upward]
therefore  x   : int        [upward]

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

var x = parse("123");
print_int(x);

given      parse        : string -> T  [upward]
given      "123"        : string       [upward]
therefore  parse("123") : ∃T           [upward]
therefore  x            : ∃T           [upward]
given      print_int    : int -> ()    [upward]
therefore  print_int(x) : ()           [upward]
therefore  int -> ()    = ∃T -> ()     [downward]
therefore  ∃T           = int          [downward]
therefore  x            : int          [downward]

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

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

এ থেকে, কোনও ভাষা ডিজাইনার উপসংহারে আসতে পারে:

  • এটি বাস্তবায়নে জটিলতা যুক্ত করে।

  • এটি টাইপচেকিংকে ধীর করে তোলে - রোগগত ক্ষেত্রে, তত দ্রুত।

  • ভাল ত্রুটির বার্তা উত্পাদন করা আরও শক্ত।

  • এটি স্থিতাবস্থা থেকে খুব আলাদা।

  • আমি এটি বাস্তবায়নের মত মনে করি না।


1
এছাড়াও: এটি বোঝা এত কঠিন হবে যে কোনও কোনও ক্ষেত্রে আপনার সংকলকটি এমন পছন্দগুলি তৈরি করবে যা প্রোগ্রামার একেবারেই প্রত্যাশা করেনি, ফলে বাগগুলি খুঁজে পাওয়া শক্ত হয়ে যায়।
gnasher729

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

4

কারণ এটি অস্পষ্ট। সি # উদাহরণ হিসাবে ব্যবহার করুন:

var foo = method(42);

আমাদের কোন ওভারলোড ব্যবহার করা উচিত?

ঠিক আছে, সম্ভবত এটি কিছুটা অন্যায় ছিল। সংকলকটি যদি আমরা আপনার অনুমানের ভাষায় না বলি তবে কী ধরণের ব্যবহার করতে হবে তা নির্ধারণ করতে পারে না। সুতরাং, আপনার ভাষায় অন্তর্নিহিত টাইপিং অসম্ভব এবং সেখানে বেনামে পদ্ধতি এবং এর সাথে লিনক রয়েছে ...

এটা কেমন? (পয়েন্টটি বর্ণনা করার জন্য সামান্য পুনঃনির্ধারিত স্বাক্ষর)

short method(int num) { ... }
int method(int num) { ... }

....

long foo = method(42);

আমাদের কি intওভারলোড, বা ওভারলোড ব্যবহার করা উচিত short? আমরা কেবল জানি না, আমাদের আপনার [int] method1(num)সিনট্যাক্সের সাহায্যে এটি নির্দিষ্ট করতে হবে । যা পার্স করতে এবং লিখতে সত্য বলতে কিছুটা ব্যথা হয় ।

long foo = [int] method(42);

জিনিসটি হ'ল এটি আশ্চর্যজনকভাবে সি # এর জেনেরিক পদ্ধতির সাথে একই রকম সিনট্যাক্স।

long foo = method<int>(42);

(সি ++ এবং জাভাতে একই বৈশিষ্ট্য রয়েছে))

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

আপনি বলেছেন আপনি সংকলক সম্পর্কে খুব বেশি জানেন না। আমি ব্যাকরণ এবং পার্সারগুলি সম্পর্কে শিখার সুপারিশ করব। একবার আপনি প্রসঙ্গমুক্ত ব্যাকরণ কী তা বুঝতে পারলে, দ্বিপাক্ষিকতা কেন খারাপ জিনিস তা সম্পর্কে আপনার আরও ভাল ধারণা হবে।


জেনেরিক্স সম্পর্কে ভাল বক্তব্য, যদিও আপনি বিবাদযুক্ত বলে মনে করছেন shortএবং int
রবার্ট হার্ভে

হ্যাঁ @ রবার্ট হার্ভে আপনি ঠিক বলেছেন। আমি দৃষ্টান্তটি বর্ণনা করার জন্য উদাহরণের জন্য লড়াই করছিলাম। যদি methodএকটি সংক্ষিপ্ত বা ইনটার ফিরে আসে তবে এটি আরও ভাল কাজ করবে এবং টাইপটি দীর্ঘ হিসাবে সংজ্ঞায়িত করা হয়েছিল।
রাবারডাক

এটি কিছুটা ভাল বলে মনে হচ্ছে।
রাবারডাক

আমি আপনার যুক্তিগুলি কিনব না যে আপনার কাছে টাইপ অনুমিতি, বেনামে সাববুটাইন বা মোনাড বোঝার জন্য কোনও ভাষাতে রিটার্ন টাইপ ওভারলোডিং নেই। হাস্কেল এটি করে এবং হাস্কেলের তিনটিই আছে। এতে প্যারামেট্রিক পলিমারফিজমও রয়েছে। তোমার বিন্দু সম্পর্কে long/ int/ shortsubtyping জটিলতার এবং / অথবা রিটার্ন টাইপ ওভারলোডিং সম্পর্কে চেয়ে অন্তর্নিহিত ধর্মান্তর সম্পর্কে বেশি। সব পরে, সংখ্যা লিটারেল হয় সি তাদের রিটার্ন টাইপ ++ জাভা, C♯, এবং অনেক অন্যদের উপর ওভারলোড, এবং যে একটি সমস্যা উপস্থাপন মনে হচ্ছে না। আপনি কেবল একটি বিধি তৈরি করতে পারেন: উদাহরণস্বরূপ সুনির্দিষ্ট / সাধারণ ধরণ বেছে নিন।
জার্গ ডব্লু মিটাগ

@ জার্গডাব্লু মিটাগ আমার বক্তব্যটি এটি অসম্ভব করে তুলবে না, কেবল এটি অযথা জটিল করে তোলে complex
রাবারডাক

0

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

বেশিরভাগ ভাষায়, আপনি ভাবটিটির method1(2)একটি নির্দিষ্ট ধরণের এবং কম-বেশি অনুমানযোগ্য প্রত্যাবর্তনের মান আশা করতে পারেন । তবে আপনি যদি রিটার্ন মানগুলিতে অতিরিক্ত চাপ দেওয়ার অনুমতি দেন, তার অর্থ এটির চারপাশের প্রসঙ্গটি বিবেচনা না করেই সাধারণভাবে অভিব্যক্তিটির অর্থ কী তা বলা অসম্ভব। আপনি যখন এমন একটি unsigned long long foo()পদ্ধতি প্রয়োগ করেন যার প্রয়োগ শেষ হয় তখন কী হয় তা বিবেচনা করুন return method1(2)? longসেটিকে কি পুনরুদ্ধারকারী ওভারলোড বা int-টেনারিং ওভারলোড বলা উচিত বা কেবল একটি সংকলক ত্রুটি দেওয়া উচিত?

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


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


2
"সমস্ত ফাংশনকে খাঁটি এবং সাধারণভাবে স্বচ্ছ হতে হবে": এটি কীভাবে রিটার্নের ধরণের ওভারলোডিংকে সহজ করে?
জর্জিও 21

@ জর্জিও এটি করে না - মরচে ফাংশন পিউরিটি প্রয়োগ করে না এবং এটি এখনও রিটার্ন টাইপ ওভারলোডিং করতে পারে (যদিও রাস্টে তার ওভারলোডিং অন্যান্য ভাষার চেয়ে খুব আলাদা (আপনি কেবল টেমপ্লেট ব্যবহার করে ওভারলোড করতে পারেন))
ইদন আরে

[দীর্ঘ] এবং [অন্তর্] অংশটি পদ্ধতিটি স্পষ্টভাবে কল করার একটি উপায় ছিল, বেশিরভাগ ক্ষেত্রে কীভাবে এটি বলা উচিত তা পদ্ধতিটির কার্যকরকরণের জন্য নির্ধারিত পরিবর্তনের ধরণ থেকে সরাসরি সনাক্ত করা যেতে পারে।
ব্যবহারকারী2638180

0

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

আমি এটি একটি সাধারণ এনকোড / ডিকোড এপিআইতে ব্যবহার করেছি

public protocol HierDecoder {
  func dech() throws -> String
  func dech() throws -> Int
  func dech() throws -> Bool

এর অর্থ এই যে কলগুলি যেখানে প্যারামিটারের প্রকারগুলি জানা যায় যেমন কোনও initকোনও বস্তুর খুব সহজেই কাজ করুন:

    private static let typeCode = "ds"
    static func registerFactory() {
        HierCodableFactories.Register(key:typeCode) {
            (from) -> HierCodable in
            return try tgDrawStyle(strokeColor:from.dech(), fillColor:from.dechOpt(), lineWidth:from.dech(), glowWidth: from.dech())
        }
    }
    func typeKey() -> String { return tgDrawStyle.typeCode }
    func encode(to:HierEncoder) {
        to.ench(strokeColor)
        to.enchOpt(fillColor)
        to.ench(lineWidth)
        to.ench(glowWidth)
    }

আপনি যদি মনোযোগ দিচ্ছেন, আপনি dechOptউপরের কলটি লক্ষ্য করবেন । আমি শক্তভাবে খুঁজে পেয়েছি যে একই ফাংশনটির নাম যেখানে ডিফারিয়েশনার একটি alচ্ছিক ফিরিয়ে দিচ্ছিল তত চাপের প্রবণতা ছিল কারণ কলিং প্রসঙ্গটি এটি একটি anচ্ছিক বলে প্রত্যাশা প্রবর্তন করতে পারে।


-5
int main() {
    auto var1 = method1(1);
}

সেক্ষেত্রে সংকলক ক) কলটি প্রত্যাখ্যান করতে পারে কারণ এটি অস্পষ্ট ছিল খ) প্রথম / শেষটি চয়ন করুন গ) প্রকারটি ছেড়ে var1যান এবং প্রকারের অনুক্রমের সাথে এগিয়ে যান এবং যত তাড়াতাড়ি অন্য কোনও অভিব্যক্তিটি var1নির্বাচনের জন্য ব্যবহারের ধরণটি নির্ধারণ করে সঠিক বাস্তবায়ন নীচের লাইনে, টাইপ অনুক্রমটি অ-তুচ্ছ বলে মনে করা খুব কমই সেই ধরণের অনুমিতি ব্যতীত অন্য কোনও বিন্দু প্রমাণ করে generally
back2dos

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

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