কার্যকরী শৈলী ব্যতিক্রম হ্যান্ডলিং


24

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

def fn(*args):
    try:
        ... do something
    except SomeException:
        return None

এটি কি বিশুদ্ধতা লঙ্ঘন করে? এবং যদি তাই হয় তবে এর অর্থ কি, পাইথনে খাঁটি ত্রুটিগুলি পরিচালনা করা অসম্ভব?

হালনাগাদ

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

class Empty:
    def __repr__(self):
        return "Empty"


class Optional:
    def __init__(self, value=Empty):
        self._value = value

    @property
    def value(self):
        return Empty if self.isempty else self._value

    @property
    def isempty(self):
        return isinstance(self._value, BaseException) or self._value is Empty

    def __bool__(self):
        raise TypeError("Optional has no boolean value")


def optional(*exception_types):
    def build_wrapper(func):
        def wrapper(*args, **kwargs):
            try:
                return Optional(func(*args, **kwargs))
            except exception_types as e:
                return Optional(e)
        wrapper.__isoptional__ = True
        return wrapper
    return build_wrapper


class Carry:
    """
    >>> from functools import partial
    >>> @optional(ArithmeticError)
    ... def rdiv(a, b):
    ...     return b // a
    >>> (Carry() >> (rdiv, 0) >> (rdiv, 0) >> partial(rdiv, 1))(1)
    1
    >>> (Carry() >> (rdiv, 0) >> (rdiv, 1))(1)
    1
    >>> (Carry() >> rdiv >> rdiv)(0, 1) is Empty
    True
    """
    def __init__(self, steps=None):
        self._steps = tuple(steps) if steps is not None else ()

    def _add_step(self, step):
        fn, *step_args = step if isinstance(step, Sequence) else (step, )
        return type(self)(steps=self._steps + ((fn, step_args), ))

    def __rshift__(self, step) -> "Carry":
        return self._add_step(step)

    def _evaluate(self, *args) -> Optional:
        def caller(carried: Optional, step):
            fn, step_args = step
            return fn(*(*step_args, *args)) if carried.isempty else carried
        return reduce(caller, self._steps, Optional())

    def __call__(self, *args):
        return self._evaluate(*args).value

1
আপনার প্রশ্নের ইতিমধ্যে উত্তর দেওয়া হয়েছে, তাই কেবল একটি মন্তব্য: আপনি বুঝতে পেরেছেন যে আপনার ফাংশনটি ব্যতিক্রমী ক্রিয়াকলাপে প্রোগ্রামিংয়ে ব্যর্থ হয় কেন ? এটি কোনও সালিশী কৌতুক নয় :)
অ্যান্ড্রেস এফ

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

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

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

1
@ ইলিকর্ভিগো একটি পরিবর্তনশীল সেট করা সংজ্ঞা দ্বারা সম্পূর্ণ স্টপ রাষ্ট্রের পরিচয় দেয়। ভেরিয়েবলগুলির পুরো উদ্দেশ্য হ'ল তারা রাষ্ট্র ধরে। ব্যতিক্রম নিয়ে এর কোনও যোগসূত্র নেই। কোনও ফাংশনের রিটার্ন মান পর্যবেক্ষণ এবং পর্যবেক্ষণের ভিত্তিতে একটি ভেরিয়েবলের মান নির্ধারণ করা রাষ্ট্রকে মূল্যায়নের সাথে পরিচয় করে, তাই না?
ব্যবহারকারী 253751

উত্তর:


20

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

নীচের প্রকারটি কেন দরকারী? ওয়েল, এটি খালিটি জেনেও আসুন আমরা প্রোগ্রামের আচরণে কিছুটা ছাড় আনি। উদাহরণস্বরূপ, যদি আমাদের ফাংশন থাকে:

def do_thing(a: int) -> Bottom: ...

আমরা জানি যে do_thingকখনই ফিরতে পারে না, যেহেতু এটির জন্য একটি ধরণের মান ফিরে আসতে হবে Bottom। সুতরাং, কেবল দুটি সম্ভাবনা রয়েছে:

  1. do_thing থামছে না
  2. do_thing একটি ব্যতিক্রম নিক্ষেপ (একটি ব্যতিক্রম পদ্ধতি সহ ভাষায়)

নোট করুন যে আমি একটি টাইপ তৈরি করেছি Bottomযা পাইথন ভাষায় আসলে বিদ্যমান নেই। Noneএকটি ভুল নাম; এটি আসলে ইউনিট মান , ইউনিটের ধরণের একমাত্র মান , যা NoneTypeপাইথন নামে ডাকা হয় ( type(None)নিজের জন্য নিশ্চিত করার জন্য)।

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

def safe_div(num: int, den: int) -> Option[int]:
  return Some(num/den) if den != 0 else None

দুর্ভাগ্যক্রমে, যেহেতু পাইথনের প্রকৃত পরিমাণের পরিমাণ নেই, এটি একটি কার্যকর পন্থা নয়। আপনি পারে আসতে Noneবোঝান ব্যর্থতা একটি দরিদ্র-মানুষের বিকল্প টাইপ করবেন, কিন্তু এই সত্যিই কোন ভাল ফেরার চেয়ে Null। কোনও ধরণের সুরক্ষা নেই।

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


"নীচের মান" দ্বারা আমি আসলে "নীচের ধরণ" বোঝাতে চেয়েছিলাম, এজন্যই আমি লিখেছিলাম যে Noneসংজ্ঞাটি মেনে চলে না। যাইহোক, আমাকে সংশোধন করার জন্য ধন্যবাদ। আপনি কি ভাবেন না যে কেবল ব্যতিক্রমকে পুরোপুরি কার্যকর করা বন্ধ করতে বা alচ্ছিক মানটি ফিরিয়ে দেওয়ার জন্য পাইথনের নীতিগুলি ঠিক আছে? মানে, জটিল নিয়ন্ত্রণের ব্যতিক্রম ব্যবহার থেকে বিরত রাখা কেন খারাপ?
এলি করভিগো

@ ইলিকোড়ভিগো, আমি যা বলেছি কম-বেশি সেটাই তাই? ব্যতিক্রম আইডেম্যাটিক পাইথন।
বাগেরহেড

1
উদাহরণ হিসেবে বলা যায়, আমি আমার undergrad ছাত্র ব্যবহার করতে নিরুৎসাহিত try/except/finallyকরতে অন্য বিকল্প মত if/else, অর্থাত্ try: var = expession1; except ...: var = expression 2; except ...: var = expression 3..., যদিও এটি কোনো অনুজ্ঞাসূচক ভাষা (BTW, আমি দৃঢ়ভাবে ব্যবহার নিরুত্সাহিত না করার জন্য একটি সাধারণ ব্যাপার if/elseহিসাবে ভাল এই জন্য ব্লক)। আপনি কী বোঝাতে চেয়েছেন যে আমি অযৌক্তিক হয়েছি এবং "এটি পাইথন" বলে এই জাতীয় নিদর্শনগুলির অনুমতি দেওয়া উচিত?
এলি করভিগো

@ এলিকোর্ভিগো আমি আপনার সাথে সাধারণভাবে একমত (বিটিডব্লিউ, আপনি একজন অধ্যাপক?) নিয়ন্ত্রণ প্রবাহের জন্য ব্যবহার করা try... catch...উচিত নয় । কিছু কারণে পাইথন সম্প্রদায় যদিও এইভাবে কাজগুলি করার সিদ্ধান্ত নিয়েছে। উদাহরণস্বরূপ, safe_divআমি উপরে যে ফাংশনটি লিখেছি তা সাধারণত লেখা হবে try: result = num / div: except ArithmeticError: result = None। সুতরাং আপনি যদি তাদের সাধারণ সফ্টওয়্যার ইঞ্জিনিয়ারিং নীতিগুলি শিখিয়ে থাকেন তবে আপনার অবশ্যই এটি নিরুৎসাহিত করা উচিত। if ... else...এটি একটি কোড গন্ধ, তবে এটি এখানে প্রবেশ করা খুব দীর্ঘ।
উদ্যানক্ষেত্র

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

11

যেহেতু গত কয়েক দিন ধরে বিশুদ্ধতার প্রতি এত আগ্রহ রয়েছে, তাই খাঁটি ফাংশনটি কী দেখাচ্ছে তা আমরা কেন পরীক্ষা করি না।

একটি খাঁটি ফাংশন:

  • উল্লেখযোগ্য-স্বচ্ছ হয়; অর্থাত, প্রদত্ত ইনপুটটির জন্য, এটি সর্বদা একই আউটপুট উত্পাদন করে।

  • পার্শ্ব প্রতিক্রিয়া উত্পাদন করে না; এটি এর বাহ্যিক পরিবেশের ইনপুট, আউটপুট বা অন্য কিছু পরিবর্তন করে না। এটি কেবলমাত্র একটি ফেরতের মান উত্পাদন করে।

তাই নিজেকে জিজ্ঞাসা করুন। আপনার ফাংশনটি কোনও ইনপুট গ্রহণ করে এবং আউটপুট ফেরত ব্যতীত কিছু করতে পারে?


3
সুতরাং, এতে কিছু যায় আসে না, যতক্ষণ এটি কার্যকরীভাবে আচরণ করে ততক্ষণ ভিতরে ভিতরে এটি কতটা কুৎসিত লেখা হয়?
এলি করভিগো ২

8
ঠিক আছে, আপনি যদি নিছক বিশুদ্ধিতে আগ্রহী হন। অবশ্যই বিবেচনা করার মতো অন্যান্য বিষয় থাকতে পারে।
রবার্ট হার্ভে

3
শয়তানদের উকিল খেলতে, আমি যুক্তি দিয়েছি যে একটি ব্যতিক্রম ছোঁড়া কেবল আউটপুট এবং ফাংশনগুলির একটি ফর্ম যা নিক্ষেপ করা খাঁটি। এটা কি একটা সমস্যা?
বার্গি

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

2
@ ব্রিগ্রি নিক্ষেপ করার সময় যুক্তিযুক্ত বিশুদ্ধ হতে পারে, ব্যতিক্রমগুলি ব্যবহার করে আইএমও প্রতিটি ফাংশনের রিটার্নের ধরণের জটিলতার চেয়ে আরও বেশি কিছু করে। এটি ফাংশনগুলির সংমিশ্রণের ক্ষতি করে। map : (A->B)->List A ->List Bকোথায় A->Bত্রুটি করতে পারে তার বাস্তবায়ন বিবেচনা করুন । যদি আমরা f কে একটি ব্যতিক্রম ছুঁড়ে মারার অনুমতি দিই তবে map f L কিছু টাইপ ফিরে আসবে Exception + List<B>। পরিবর্তে যদি আমরা এটিকে কোনও optionalশৈলীর ফেরত দেওয়ার অনুমতি দিই তবে map f Lতার পরিবর্তে তালিকা <অপশনাল <B>> return ফিরে আসবে ` এই দ্বিতীয় বিকল্পটি আমার কাছে আরও কার্যকর বলে মনে করে।
মাইকেল অ্যান্ডারসন

7

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

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

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

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

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

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

Noneপরিবর্তে ফিরে আসা সম্পূর্ণ আলাদা। Noneএকটি নীচবিহীন মান; কোনও কিছু এর সমান হলে আপনি পরীক্ষা করতে পারেন এবং ফাংশনটির কলার ফিরে Noneআসা চলতে থাকবে, সম্ভবত Noneঅনুপযুক্ত ব্যবহার করে ।

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

কিন্তু যে না কার্মিক প্রোগ্রামারদের বলতে চাচ্ছি তা যখন তারা ব্যতিক্রম এড়াতে বলে। কার্যকরী প্রোগ্রামাররা "মোট ফাংশন" পছন্দ করেন। এগুলি সর্বদা প্রতিটি ইনপুটের জন্য তাদের রিটার্নের প্রকারের একটি বৈধ নন-ডাউন মান দেয় always সুতরাং যে কোনও ফাংশন যে ব্যতিক্রম ছুঁড়ে ফেলতে পারে তা মোট ফাংশন নয়।

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

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

সুতরাং একটি কার্যনির্বাহী প্রোগ্রামার যা আপনাকে ব্যতিক্রম এড়ানোর পরামর্শ দেয় আপনি তার পরিবর্তে এমন কোনও মান ফেরত দিতে পছন্দ করবেন যা ত্রুটি বা বৈধ মানকে এনকোড করে এবং এটি ব্যবহারের জন্য আপনি উভয় সম্ভাবনা পরিচালনা করার জন্য প্রস্তুত রয়েছেন requires Eitherপ্রকার বা Maybe/ Optionপ্রকারের মতো বিষয়গুলি আরও দৃ strongly়ভাবে টাইপ করা ভাষায় এটি করার জন্য কিছু সহজ পদ্ধতির (সাধারণত একটি বিশেষ Aউত্পাদনের সাথে প্রয়োজনীয় জিনিসগুলিকে আঠালো করতে সহায়তা করার জন্য বিশেষ বাক্য গঠন বা উচ্চতর ক্রমের সাথে ব্যবহৃত হয় Maybe<A>)।

হয় এমন একটি ফাংশন যা হয় None(যদি কোনও ত্রুটি ঘটে) বা কিছু মান (যদি কোনও ত্রুটি না ঘটে) উপরের কৌশলগুলি অনুসরণ করে না

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


1
+1 দুর্দান্ত উত্তর! এবং খুব ব্যাপক।
আন্দ্রেস এফ।

6

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

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

অন্যদিকে, আপনি যদি কোনও প্রদত্ত স্ট্রিং থেকে কোনও পূর্ণসংখ্যাকে পার্স করার চেষ্টা করছেন এবং ব্যর্থ হয় তবে কোনও ব্যতিক্রম ছুঁড়ে মারছেন, তবে তা খাঁটি হতে পারে, যতক্ষণ না কোনও ব্যতিক্রম আপনার কার্যকারিতা থেকে সরে যেতে পারে না।

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


আপনি নীচের প্রকারটি ফিরতে পারবেন না।
উদ্যানক্ষেত্র

1
@ গ্রেডেনহেড আপনি ঠিক বলেছেন, আমি ইউনিটের ধরণের কথা ভাবছিলাম। সংশোধন করা হয়েছে।
বিট্রি

আপনার প্রথম উদাহরণের ক্ষেত্রে, ফাইল সিস্টেমটি না এবং এর মধ্যে কোন ফাইলগুলি উপস্থিত থাকে কেবল ফাংশনটির একটি ইনপুট?
মূল্য 19

2
@ স্পষ্টতা বাস্তবে আপনার কাছে সম্ভবত ফাইলটির একটি হ্যান্ডেল বা পথ রয়েছে। যদি ফাংশনটি fখাঁটি হয়, আপনি f("/path/to/file")সর্বদা একই মানটি প্রত্যাশা করবেন। আসল ফাইলটি মুছে ফেলা বা দুটি নিমন্ত্রণের মধ্যে পরিবর্তিত হলে কী হবে f?
আন্দ্রেস এফ।

2
@ ভ্যালিলিটি ফাংশনটি বিশুদ্ধ হতে পারে যদি আপনি ফাইলটির হ্যান্ডেলের পরিবর্তে ফাইলটির আসল বিষয়বস্তু (যেমন বাইটের সঠিক স্ন্যাপশট) পাস করেন, তবে আপনি যদি গ্যারান্টি দিতে পারেন যে একই বিষয়বস্তুটি একই প্রবেশপথে চলে যায় বাইরে যায় তবে কোনও ফাইল অ্যাক্সেস করা এর মতো নয় :)
আন্দ্রেস এফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.