برنامه نویسی

چرا از پیشوند Maybe_ در توابع اکسیر اجتناب کنید؟

در زبان های کاربردی، مفاهیمی مانند مونادها نقش مهمی در مدیریت عوارض جانبی و زنجیره ایمن عملیات ایفا می کنند. نمونه معروف آن نوع است Maybe در Haskell، که محاسبات اختیاری را انتزاعی می کند و از رسیدگی صریح مقادیر از دست رفته اجتناب می کند. با این حال، Elixir، یک زبان کاربردی مدرن که بر روی BEAM (ماشین مجازی Erlang) ساخته شده است، مسیر متفاوتی را در طراحی زبان طی می کند.

این انتخاب پیامدهای مستقیمی برای نحوه برخورد ما با سناریوهای مشابه دارد و توضیح می دهد که چرا استفاده از پیشوند maybe_ در توابع عملی توصیه نمی شود. بیایید دلایل فنی و طراحی پشت این تصمیم را بررسی کنیم و اینکه Elixir چگونه جایگزین‌های همسو با اهداف شما را ارائه می‌دهد.

نقش مونادها و نوع Maybe

مونادها، در زبان‌هایی مانند Haskell، ساختارهای انتزاعی هستند که به شما امکان می‌دهند عملیات‌ها را زنجیره‌ای کنید، در حالی که به طور شفاف با عوارض جانبی یا مقادیر از دست رفته برخورد می‌کنید. نوع Maybeبه عنوان مثال، مقادیر اختیاری را نشان می دهد و دو مورد را محصور می کند: Just (یک ارزش فعلی) یا Nothing (عدم ارزش).

این بسیار قدرتمند است زیرا توسعه دهندگان را از نوشتن شرط های صریح برای هر موردی که ممکن است یک مقدار وجود داشته باشد یا نباشد، باز می دارد. این مثال را در Haskell ببینید:

safeDivide :: Int -> Int -> Maybe Int
safeDivide _ 0 = Nothing
safeDivide x y = Just (x `div` y)

result = Just 10 >>= (`safeDivide` 2) >>= (`safeDivide` 5)
-- Resultado: Just 1

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اینجا، اپراتور >>= به شما امکان می دهد تا تماس هایی را زنجیره ای کنید که به قوانین نوع احترام می گذارند Maybe. اگر هر مرحله ای برگردد Nothing، موارد بعدی به طور خودکار نادیده گرفته می شوند.

چرا اکسیر مونادها را قبول نمی کند؟

اکسیر با وجود کاربردی بودن، مونادها را مستقیما پیاده سازی نمی کند و این یک انتخاب آگاهانه است. طراحی زبان به سادگی و عملکرد در BEAM کمک می کند. چند دلیل اصلی برای این تصمیم وجود دارد:

  1. معناشناسی ساده و صریح: مونادها، اگرچه ظریف هستند، اما می توانند پیچیدگی مفهومی را برای کسانی که با پارادایم عملکردی آشنا نیستند، معرفی کنند. در Elixir، هدف این است که زبان را برای مخاطبان گسترده، از جمله توسعه دهندگان با پیشینه زبان های ضروری، در دسترس نگه دارد.

  2. BEAM در حال حاضر بسیاری از مشکلات را حل می کند: BEAM مکانیسم های قوی برای مقابله با خرابی ها و همزمانی، مانند پیوندها، سرپرستان و فرآیندهای مجزا ارائه می دهد. این نیاز به انتزاع هایی مانند مونادها برای کنترل جریان یا انتشار خطا را کاهش می دهد.

  3. جایگزین های اصطلاحی در اکسیر: ساختارهایی مانند تطبیق الگو، with و استفاده از تاپل ها ({:ok, value} یا {:error, reason}) راه‌های اصطلاحی و صریح را برای رسیدگی به جریان‌های داده یا خرابی‌های اختیاری ارائه می‌کند. این ابزارها در حال حاضر نیازهای رایج را بدون معرفی یک لایه اضافی از انتزاع برآورده می کنند.

مشکل پیشوند maybe_

وقتی از پیشوند استفاده می کنیم maybe_ برای نام‌گذاری توابع در اکسیر، به طور ضمنی در حال آوردن تداعی‌هایی از نوع آن هستیم Maybe از زبان هایی مانند Haskell. این یک انتظار اشتباه ایجاد می کند که این توابع مانند یک موناد رفتار می کنند، یعنی می توانند به طور خودکار زنجیره شوند و به طور ضمنی با مقادیر اختیاری سروکار دارند. با این حال، در اکسیر، هر کنترل جریان نیاز به ساختارهای واضح دارد.

def maybe_divide(_, 0), do: nil
def maybe_divide(x, y), do: x / y
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اسمی شبیه maybe_divide نشان می دهد که ما با انتزاعی مانند Maybe از Haskell، اما نتیجه تابع فقط صفر در شکست است. برای زنجیره ای کردن این تابع، باید منطق صریح ایجاد کنید:

result =
  case maybe_divide(10, 2) do
    nil -> nil
    value -> maybe_divide(value, 5)
  end
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این نشان دهنده ظرافت مرتبط با مونادها نیست و با روح طراحی صریح و ساده اکسیر مغایرت دارد.

راه حل اصطلاحی در اکسیر: with

اکسیر مشکل کنترل جریان و انتشار خطا را با ماکرو حل می کند with. این ساختار به شما امکان می دهد عملیات هایی را که ممکن است شکست بخورند زنجیره بزنید، اما وضوح و سادگی را حفظ می کند.

بازنویسی مثال قبلی با with:

  def safe_divide(_, 0), do: {:error, :division_by_zero}
  def safe_divide(x, y), do: {:ok, x / y}

  with {:ok, value1} <- safe_divide(10, 2),
       {:ok, value2} <- safe_divide(value1, 5) do
         {:ok, value2}
  end
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

O with نیاز به منطق صریح مورد را از بین می برد، کد را ساده می کند و کنترل جریان ظریفی را بدون تکیه بر مفاهیم پیچیده مانند مونادها ارائه می دهد.

نتیجه گیری: نقش طراحی اکسیر در نامگذاری و جابجایی جریان

پیشوند maybe_ در توابع اکسیر به خوبی مورد توجه قرار نمی گیرد زیرا با مفهوم مونادها که بخشی از طراحی زبان نیستند، ارتباط های گمراه کننده ای دارد. این می تواند با بیان این که یک انتزاع ضمنی برای برخورد با مقادیر اختیاری وجود دارد، به سردرگمی و انتظارات نادرست منجر شود، در حالی که در واقع اکسیر بر ساختارهای صریح و سرراست مانند تاپل ها متکی است.{:ok, valor} یا {:error, motivo}تطبیق الگو و با ماکرو. این ابزارها برای حل مشکلات مشابه به روشی واضح و اصطلاحی بیش از اندازه کافی هستند.

علاوه بر این، نام هایی مانند try_algo یا maybe_algo آنها همچنین با فلسفه زیربنای اکسیر و BEAM که اصل “بگذار خراب شود” را اتخاذ می کند، در تضاد هستند. در اکسیر، نه ما سعی می کنیم انجام دهیم چیزی؛ به سادگی ما انجام می دهیم، و هر گونه خرابی به طور صریح رسیدگی می شود یا به سیستم نظارت قوی BEAM واگذار می شود. این رویکرد شرط‌های دفاعی بیش از حد را حذف می‌کند و کد تمیزی را که با طراحی زبان همسو است، ترویج می‌کند.

یک مثال ساده را در نظر بگیرید:

# Não idiomático
def try_divide(_, 0), do: {:error, :division_by_zero}
def try_divide(x, y), do: {:ok, x / y}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مورد، نام try_divide واقعیت کد یا روشی که BEAM عملیات را مدیریت می کند را منعکس نمی کند. یک نام واضح تر و اصطلاحی تر به سادگی می تواند این باشد:

def safe_divide(_, 0), do: {:error, :division_by_zero}
def safe_divide(x, y), do: {:ok, x / y}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این رویکرد، نام دقیقاً همان کاری را که تابع انجام می‌دهد، بیان می‌کند: تقسیم امن را انجام می‌دهد و در صورت لزوم یک خطا را برمی‌گرداند. این با سادگی و وضوح مورد انتظار در طراحی اکسیر مطابقت دارد.

در نهایت با پرهیز از نامگذاری هایی مانند try_ ه maybe_، ما اطمینان می دهیم که کد ما منعکس کننده اصول اصلی اکسیر است: سادگی، کارایی، انعطاف پذیری و همسویی مستقیم با مقادیر اصلی BEAM. این زبان به گونه‌ای طراحی شده است که واضح و روشن باشد، و انتخاب نام‌گذاری و طراحی ما باید این فلسفه را تقویت کند و کدهای اصطلاحی، خوانا و قدرتمندتر را ترویج کند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا