برنامه نویسی تابعی چیست؟ + مزایا و معایب آن
برنامه نویسی تابعی (Functional Programming) یک الگوی سریع در حال رشد است. توسعه دهندگان به دلایل زیادی برنامه نویسی فانکشنال را یاد می گیرند. برخی می خواهند درک خود را از برنامه نویسی گسترش دهند و برخی دیگر می خواهند شغل جدیدی پیدا کنند. برخی افراد هم متوجه می شوند که برنامه نویسی تابعی نسبت به طرز فکر آنها طبیعی تر و منطقی تر است.
در این مقاله یاد خواهیم گرفت که برنامه نویسی تابعی چیست و با معروف ترین زبان های برنامه نویسی تابعی آشنا می شویم. سپس ویژگی هایی رایج زبان های تابعی را معرفی می کنیم و به بررسی زبان هایی که تابعی نیستند اما دارای برخی ویژگی های زبان تابعی هستند، میپردازیم.
برنامه نویسی تابعی چیست؟
تعریف برنامه نویسی تابعی کار راحتی نیست. تعاریف متناقضی در همه جا وجود دارد. زبان های تابعی به جای اجرای statement ها (مجموعه ای از دستورالعمل ها) بر expression ها و declaration ها تاکید دارند. بنابراین، بر خلاف سایر رویهها (procedures) که به یک وضعیت (state) محلی یا سراسری بستگی دارند، مقدار خروجی در برنامه نویسی تابعی فقط به آرگومانهای ارسال شده به تابع بستگی دارد.
Functional Programming روشی از برنامه نویسی است که شامل موارد زیر است:
- اقدامات – کدی که بر دنیای بیرون تأثیر می گذارد یا تحت تأثیر آن قرار می گیرد، مانند تابعی که ایمیل ارسال می کند.
- محاسبات – محاسبات از ورودی ها به خروجی ها، مانند تابعی که مالیات بر مبلغ فروش را محاسبه می کند.
- داده ها – حقایقی در مورد رویدادها (events) مانند قیمت یک محصول
ویژگی های برنامه نویسی تابعی
- روش برنامه نویسی فانکشنال بر نتایج تمرکز می کند نه فرآیند
- در این نوع برنامه نویسی تاکید بر چیزی است که باید محاسبه شود.
- داده ها تغییر ناپذیر هستند.
- برنامه نویسی تابعی مسئله را به توابع تجزیه میکند.
- این برنامه نویسی بر اساس مفهوم توابع ریاضی ساخته شده است که از عبارات شرطی و بازگشت برای انجام محاسبات استفاده می کند.
- از دستورات تکراری مانند حلقه تکرار (loop statements) و دستورات شرطی مانند If-Else پشتیبانی نمی کند.
تاریخچه Functional Programming
- اساس برنامه نویسی تابعی، حساب Lambda (یک نماد برای توصیف توابع و برنامه های ریاضی) است. در دهه 1930 برای موارد کاربرد، تعریف و بازگشت توابع توسعه یافت.
- LISP اولین زبان برنامه نویسی فانکشنال بود. مک کارتی آن را در سال 1960 طراحی کرد.
- در اواخر دهه 70، محققان دانشگاه ادینبورگ ML (زبان متا) را تعریف کردند.
- در اوایل دهه 80، زبان هوپ انواع داده های جبری را برای استدلال بازگشتی و معادله ای اضافه کرد.
- در سال 2004 زبان تابعی “Scala” ابداع شد.
زبان های برنامه نویسی تابعی
هدف هر زبان برنامه نویسی Functional تقلید از توابع ریاضی است. با این حال، فرآیند اساسی محاسبات در برنامه نویسی تابعی متفاوت است. در اینجا، برخی از برجسته ترین زبان های برنامه نویسی فانکشنال آورده شده است:
- Haskell
- SML
- Clojure
- Scala
- Erlang
- Clean
- F#
- ML/OCaml Lisp / Scheme
- XSLT
- SQL
- Mathematica
اصطلاحات و مفاهیم پایهای برنامه نویسی تابعی
داده های تغییرناپذیر
دادههای تغییرناپذیر به این معنی است که شما به راحتی بتوانید ساختارهای دادهای ایجاد کنید به جای اینکه ساختارهایی که از قبل وجود دارد را اصلاح کنید.
شفافیت ارجاعی
برنامههای تابع پذیر باید عملیاتهایی را انجام دهند که انگار برای اولین بار است که اجرا میشوند. بنابراین، در هنگام اجرای برنامه متوجه خواهید شد که چه اتفاقی خواهد افتاد و یا نخواهد افتاد و عوارض جانبی آن را مدنظر میگیرید. در اصطلاح برنامه نویسی فانکشنال به این اتفاق شفافیت ارجاعی (Referential transparency) می گویند.
ماژولار بودن
طراحی ماژولار (Modular design) بهره وری را افزایش می دهد. ماژول های کوچک را می توان به سرعت کدگذاری کرد و شانس بیشتری برای استفاده مجدد دارند که مطمئناً منجربه توسعه سریع تر برنامه ها می شود. جدا از آن، ماژول ها را می توان به طور جداگانه آزمایش کرد که به شما کمک می کند زمان صرف شده برای تست واحد و اشکال زدایی را کاهش دهید.
قابلیت نگهداری
این مفهوم به به این معنی است که نگهداری (maintain) از برنامه نویسی فانکشنال آسانتر است، زیرا نیازی نیست نگران تغییر تصادفی چیزی خارج از تابع مشخص باشید.
تابع درجه یک
“First-class Function” تعریفی است که به موجودیت های زبان برنامه نویسی نسبت داده می شود که هیچ محدودیتی در استفاده از آنها وجود ندارند. بنابراین، توابع درجه یک می توانند در هر نقطه از برنامه دیده شوند.
Closure
closure یک تابع درونی است که می تواند به متغیرهای تابع والد دسترسی داشته باشد، حتی پس از اجرای تابع والد.
توابع مرتبه بالاتر
توابع مرتبه بالاتر، توابع دیگر را به عنوان آرگومان می گیرند یا آنها را به عنوان نتیجه برمی گردانند. این تکنیک یک تابع را در یک زمان به آرگومان های خود اعمال می کند، زیرا هر برنامه یک تابع جدید را برمی گرداند که آرگومان بعدی را می پذیرد.
توابع خالص
Pure function تابعی است که ورودیهای آن به عنوان ورودی تعریف میشود و هیچکدام از آنها نباید مخفی باشند. خروجی ها نیز به عنوان خروجی تعریف میشود.
توابع خالص بر روی پارامترهای خود عمل میشوند. همچنین این تابع اگر چیزی را برنگرداند کارآمد نیست. علاوه بر این، Pure function خروجی مشابهی را برای پارامترهای که به آن داده شده ارائه می دهد.
به طور مثال :
1 2 3 4 |
Function Pure(a,b) } return a+b; { |
توابع ناخالص
توابع ناخالص (Impure functions) دقیقاً در مقابل توابع خالص (Pure function) قرار میگیرند. آنها ورودی یا خروجی خارج تابع دارند. به همین دلیل به آن ها ناخالص گفته می شود. توابع ناخالص را نمی توان به صورت مجزا مورد استفاده قرار داد یا آزمایش کرد زیرا وابستگی دارند.
به طور مثال :
1 2 3 4 |
;int z }()function notPure ;z = z+10 { |
ترکیب تابع
ترکیب تابع (Function composition) ترکیب 2 یا چند تابع برای ایجاد یک تابع جدید است.
Shared States
Shared states یک مفهوم مهم در برنامه نویسی شی گرا است. اساساً، این مفهوم ویژگی ها (properties) را به اشیاء اضافه می کند. به عنوان مثال، اگر هارد دیسک یک شی باشد، ظرفیت ذخیره سازی و اندازه دیسک را می توان به عنوان ویژگی اضافه کرد.
اثرات جانبی (Side effects)
اثرات جانبی هرگونه تغییر حالتی است که خارج از یک تابع صدا زده شده رخ میدهد. بزرگترین هدف هر زبان برنامه نویسی FP، به حداقل رساندن اثرات جانبی، با جداسازی آنها از بقیه کدهای نرم افزار است. در برنامه نویسی FP مهم است که اثرات جانبی را از بقیه منطق برنامه نویسی خود حذف کنید.
زبان های تابعی با بیشترین شغل درخواستی
ممکن است به فکر یادگیری یک زبان جدید برای استخدام در موقعیت شغلی برنامه نویسی تابعی باشید. مشاغل برنامه نویسی تابعی به ندرت یافت میشوند، اما کمابیش وجود دارند. برای به حداکثر رساندن شانس خودتان برای تصاحب یکی از شغل ها باید یکی از این زبان ها را انتخاب کنید. (این آمار مشاغل از سایت indeed.com گرفته شده است.)
سطح یک
این پنج زبان موقعیت های شغلی زیادی دارند. این لیست از ساده ترین به سخت ترین بر اساس (آغاز کار با هر یک از این زبانها) مرتب شده است.
سطح دو
این سه زبان به اندازه لیست قبلی موقعیت شغلی ندارند، اما هنوز فرصت های شغلی زیادی وجود دارد. این لیست از ساده ترین به سخت ترین بر اساس (آغاز کار با هر یک از این زبانها) مرتب شده است.
- Clojure
- Erlang
- Haskell
زبان های تابعی بر اساس پلتفرم
راه دیگر برای سازماندهی زبان های تابعی، بر اساس موجودیت های پلتفرمی است که مورد هدف قرار میدهید.
مرورگر (موتور جاوا اسکریپت)
از ساده ترین به سخت ترین بر اساس (آغاز کار با هر یک از این زبانها) مرتب شده است:
- Kotlin
- ClojureScript
- Elm
- ReasonML
- Scala.js
- PureScript
بک اند وبسایت
از ساده ترین به سخت ترین بر اساس (آغاز کار با هر یک از این زبانها) مرتب شده است:
- Elixir
- Kotlin
- Racket
- Swift
- Scala
- Clojure
- F#
- Rust
- Haskell
موبایل (iOS and Android)
- Native iOS
- Swift
- Kotlin
- Dalvik (JVM) Android
- Kotlin
- Scala
- Native Android
- Kotlin
- Xamarin iOS and Android
- #F
- React Native iOS and Android
- ClojureScript
- Scala.js
- #F
سیستم تعبیه شده (Embedded devices)
-
- Kotlin (Kotlin/Native)
- Rust
مزایای برنامه نویسی تابعی
- به شما امکان می دهد از مشکلات و خطاهای گیج کننده در کد جلوگیری کنید.
- تست و اجرای یونیت تست و اشکال زدایی کد FP آسانتر است.
- پردازش موازی و همزمان
- استقرار کد داغ (کدی که نیاز به بیلد گرفتن، دیپلوی کردن و … ندارد) و تحمل خطا
- ماژولاریتی بهتری را با کدهای کوتاه تر ارائه می دهد.
- افزایش بهرهوری توسعه دهنده
- از توابع تو در تو پشتیبانی می کند.
- استفاده از ساختارهای تابعمند مانند Lazy Map & Lists و غیره
- امکان استفاده موثر از حساب Lambda را فراهم می کند.
معایب برنامه نویسی فانکشنال
- الگوی برنامه نویسی تابعی کار آسانی نیست، بنابراین درک آن برای مبتدیها دشوار است.
- کنترل ابجکتهای زیادی در طول کدنویسی کار دشواری است.
- به تنظیمات محیطی گسترده نیاز دارد.
- استفاده مجدد بسیار پیچیده است و نیاز به بازسازی مداوم دارد.
- ممکن است ابجکتها مشکل را به درستی نشان ندهند.
مقایسه برنامه نویسی تابعی و برنامه نویسی شی گرا
برنامه نویسی تابعی
- FP از داده های Immutable استفاده می کند.
- از مدل مبتنی بر برنامه نویسی تعریفی (Declarative ) پیروی می کند.
- تمرکز اصلی این نوع برنامه نویسی بر روی: «چه کاری در برنامه انجام میدهید» است.
- پشتیبانی از برنامه نویسی موازی (Parallel Programming)
- توابع آن اثرات جانبی ندارد.
- کنترل جریان (Flow Control) با استفاده از فراخوانی تابع و فراخوانی تابع با بازگشت (توابع بازگشتی) انجام می شود.
- ترتیب اجرای مجموعه از دستورات (statements ) خیلی مهم نیست.
- از انتزاع بر داده ها (Abstraction over Data) و انتزاع بر رفتار (Abstraction over Behavior) پشتیبانی می کند.
برنامه شی گرا (OOP)
- OOP از داده های قابل تغییر استفاده می کند.
- از مدل برنامه نویسی دستوری پیروی می کند (یک پارادایم از برنامهنویسی است،که برنامهنویس، قدم به قدم، به چگونگی دستیابی به یک نتیجه خاص، توجه میکند).
- تمرکز اصلی این نوع برنامه نویسی بر روی: «اینکه چطور برنامه نویسی میکنید» است.
- هیچ پشتیبانی از برنامه نویسی موازی ندارد.
- متد ها میتوانند اثرات جانبی زیادی تولید کنند.
- فرآیند کنترل جریان با استفاده از حلقه ها و دستورات شرطی انجام می شود.
- ترتیب اجرای دستورالعملها مهم است.
- فقط از “انتزاع بر داده” پشتیبانی می کند.
جمع بندی
برنامه نویسی تابعی یا FP روشی برای تفکر در مورد ساخت نرم افزار است که بر اساس برخی از اصول اساسی تعریف می شود و به شما امکان می دهد از مشکلات و خطاهای گیج کننده در کد جلوگیری کنید.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.