برنامه نویسی فانکشنال

قسمت اول مفاهیم و الگوهای برنامه نویسی تابعی Functional در جاوااسکریپت روزمرگی کدرها

این برنامه بر استفاده از عبارات برای توصیف منطق یک برنامه متمرکز است بدون اینکه لزوماً جریان کنترل یا تغییرات حالت آن مشخص شود. از یادگیری ماشین می توان در صنایع مختلف با اهداف مختلف استفاده کرد. ماشین لرنینگ باعث افزایش بهره وری در صنایع می شود، به بازاریابی محصول کمک کرده و پیش بینی دقیق فروش را ساده تر می کند. به سیستم های توصیه گر، الگوریتم های فرا ابتکاری و حرکت ربات ها کمک خواهد کرد. در بحث فروش میتواند محصولات مناسب تری را به مشتری پیشنهاد دهد( با کمک به تقسیم بندی بهتر و پیش بینی دقیق طول عمر محصولات ) و ... استفاده از سیستم های ماشین لرنینگ می تواند تا حد زیادی حجم کاری ما را کاهش دهد.

آنچه شما نیاز دارید سیاست سخت‌گیرانه‌تری برای تغییر ناپذیری آن است، Encapsulation استراتژی خوبی برای محافظت در برابر جهش است. برای ساختارهای ساده اشیا متناوب، یک گزینه خوب اتخاذ الگوی Value Object است که به آن الگوی Module نیز گفته می‌شود. استدلال و دیباگ آن آسان‌تر است زیرا به یک حالت تغییر پذیر بستگی ندارد. برای جلوگیری از محاسبه مجدد آن در آینده، مقدار بازگشتی می‌تواند کش شود تا از محاسبه مجدد در آینده جلوگیری شود. و آخرین نکته قبل از اینکه بحث currying را ببندیم، partial application است. Partial application و currying اغلب دست در دست هم هستند، گرچه که مفاهیم جداگانه‌ای دارند.

توابعی در زمینه کار با داده ها و متغیر ها – توابع کار با اعداد ریاضی – توابع کار با رشته های متنی و… هستند که نقش زیادی در کارایی و قدرت یک زبان برنامه نویسی دارند. مسلم است که نمی‌توان همه‌ی تابع‌ها را در یک برنامه به صورت تابع خالص نوشت، مثلا توابعی که چیزی را از فایل‌سیستم می‌خوانند یا یک صفحه وب را از اینترنت واکشی می‌کنند ممکن است که خروجی متغیری داشته باشند. ما به عنوان برنامه‌نویس باید سعی کنیم تا جای ممکن توابع را به صورت توابع خالص بنویسیم، اگر چه نوشتن ٪۱۰۰ توابع به صورت خالص ممکن نیست ولی با سعی و تلاش می‌توان حدود ٪۸۵ از توابع را به صورت توابع خالص نوشت. در میان شیوه‌های برنامه‌نویسی، برنامه‌نویسی تابع‌گرا در دسته برنامه‌نویسی اعلانی قرار می‌گیرد. در این شیوه از برنامه‌نویسی ما به سیستم می‌گوییم می‌خواهیم که چه چیزی اتفاق بیفتد به جای اینکه به سیستم بگوییم چگونه کار را انجام دهد. با این وجود، تابع reduce() هنوز هم یکی از مهم ترین توابع هاست.

در حالی که در FP خود شی اکنون یک شی با نام جدید است، که فهمیدن اینکه چه چیزی تغییر کرده را به طور قابل توجهی ساده میکند. ممکن است فکر کنید که منظور من از پارادایم های برنامه نویسی چیست؟ بسیار خب. قبل از اینکه این مسئله را بررسی کنیم بیایید ببینیم که شی گرایی و فانکشنال واقعا چه هستند. جالب است که برخی از زبان‌های شی گرا مانندJavaScript ، Python و PHP از مفاهیم فانکشنال پشتیبانی می‌کنند و این بدان معنی است که می‌توانید یک متد تابع گرا را در آنها پیاده سازی کنید. یکی از دلایل اصلی محبوبیت این رویکرد، قابلیت اطمینان و پیش‌بینی‌پذیری کدهایی است که به این شیوه نوشته می‌شوند. وقتی کدی بدون تغییرات جانبی (side effect) نوشته می‌شود، اشکال‌زدایی و نگهداری آن بسیار آسان‌تر است.

یک عبارت لامبدا فضای نامی ‌محلی خود را دارد، بنابراین یکسان بودن نام پارامتر های آن با نام های موجود در فضای نامی ‌سراسری مشکلی به وجود نمی‌آورد. یک عبارت لامبدا می‌تواند به متغیر های موجود در فضای نامی ‌سراسری دسترسی پیدا کند، اما نمی‌تواند آنها را ویرایش کند. همانطور که قبلاً در این مجموعه آموخته اید، همه چیز در یک برنامه پایتون، یک آبجکت یا یک شئ محسوب می‌شود. تمامی ‌آبجکت ها در پایتون دارای ساختار تقریبا یکسانی می‌باشند و توابع نیز استثناء نیستند. در جاوااسکریپت، مانند بسیاری از زبان‌های دیگر، انواع ابتدایی (String ، Number و ...) ذاتا قابل تغییر نیستند.

همین دوگانگی است که برنامه‌های کاربردی را ماژولار و بسیار موثر می‌کند. برنامه نویسی فانکشنال یا تابعی یا تابع گرا از پارادایم‌های برنامه‌نویسی است. البته، پایتون بعضی از قابلیت‌ها و ویژگی‌های لازم برای برنامه‌نویسی‌های دیگر را هم دارد. پس، می‌شود به این نتیجه رسید که هرکاری که در پایتون می‌شود با اعداد و حلقه‌ها کرد با توابع هم شدنی است. برای مثال، در پایتون با اپراتور + می‌شود دو شئ را به‌هم افزود.

از این رو، متد toString، اگرچه یک تابع خالص نیست، اما مانند آن رفتار می‌کند و یک نمایش رشته‌ای خالص از این شی است. ممکن است بگویید "من روزانه از توابع استفاده می‌کنم، پس تفاوت چیست؟" خوب، فقط استفاده از توابع نیست که به نتیجه برسد. به‌همین‌دلیل است که در آموزش پایتون علاوه‌بر بحث‌های  مربوط به توابع و اعداد و حلقه‌ها، برنامه‌ نویسی فانکشنال هم در سرفصل‌های آموزشی گنجانده شده است. برنامه نویسی تابعی (Functional Programming) یک الگوی سریع در حال رشد است. توسعه دهندگان به دلایل زیادی برنامه نویسی فانکشنال را یاد می گیرند.

فانکشن ضرب ناخالص است؛ چرا که با ورود آن به کنسول تأثیرات جانبی ایجاد می‌شود. ابتدا با یک فانکش ضرب که مثالی از یک تابع خالص است شروع می‌کنیم. این همیشه خروجی یکسانی را برای ورودی مشابه برمی‌گرداند و هیچ گونه تأثیر جانبی نیز ایجاد نمی‌کند. خوشبختانه، ما مجبور نیستیم هر یک از فانکشن هایمان را به صورت دستی تبدیل کنیم. کتابخانه‌هایی مثل Ramda و lodash فانکشن‌هایی دارند که این کار را برای ما انجام می‌دهند. در حقیقت، آن‌ها یک نوع ترکیبی از currying را انجام می‌دهند، که شما همزمان هم می‌توانید فانکشن را با یک آرگومان فراخوانی کنید، و هم می‌توانید به طور همزمان همه آرگومان ها را pass کنید.

همانطور که دیدید، تابع map() و filter() به عنوان توابع داخلی و پیش فرض پایتون باقی مانده اند اما reduce() دیگر تابع داخلی نیست. با این حال، همانطور که خواهید دید، در ماژول کتابخانه استاندارد موجود است. تابع reduce() هر بار روی دو عنصر یک تکرار‌شونده اجرا می‌شود و آن ها را به یک مقدار تبدیل می‌کند. در مثال بالا از پرانتز های اضافه برای نوشتن عبارت لامبدا استفاده کردیم. گذاشتن این پرانتز ها ضروری نیست اما کد شما را خوانا‌تر می‌کند.

برنامه نویسی تابع گرا یا فانکشنال در اکثر موارد متفاوت از شی گرا است. هر دو الگو دارای توابع و متغیرهایی هستند اما با آنها متفاوت رفتار می‌کنند. بنابراین اجازه ندهید که شباهت‌ها در تفاوت اختلافات قرار بگیرند. بسیاری از زبان‌های فانکشنال مانندElixir ،Erlang ،Elm ، Haskell، F# و ... درست است که تعریف دقیق برنامه نویسی فانکشنال تا حدودی پیچیده است اما هدف ما در اینجا ارائه تعریف دقیق آن نیست.

آیا این خوب است؟ خب این سؤال بدی است، چراکه هیچ‌کس بهترین کد را برای یک کار خاص در دست ندارد و این به عواملی بستگی دارد که با آن‌ها کار می‌کنید و اینکه چه کسی از آن کد نگهداری خواهد کرد. اما فکر می‌کنم برنامه نویسی فانکشنال چیزهای زیادی در محاسبات به شما یاد می‌دهد و هر چه بیشتر بدانید، احتمال بیشتری نیز وجود دارد تا بهرتین رویکرد را هنگام بروز مشکلات جدید انتخاب کنید. برنامه‌نویسی فانکشنال با تمرکز بر توابع خالص و داده‌های غیرقابل تغییر، کدهایی ساده، تست‌پذیر و خوانا تولید می‌کند. این رویکرد، به‌خصوص در زبان‌های محبوبی مثل Python و JavaScript، به توسعه‌دهندگان امکان می‌دهد تا پروژه‌هایی پویا و پایدار ایجاد کنند که هم در محیط‌های پیچیده و هم در کاربردهای تحلیلی عملکرد بالایی داشته باشند. پایتون دو تابع داخلی، map() و filter() را ارائه می‌کند که متناسب با الگوی برنامه نویسی فانکشنال است. تابع سومی‌نیز وجود داشت، reduce()، اما دیگر بخشی از زبان اصلی نیست.

کتابخانه‌هایی مثل Ramda و lodash نیز وجود دارند که روش‌های زیباتری را برای ترکیب فانکشن‌ها یا composing functions ارائه می‌دهند. به جای اینکه به سادگی مقدار برگشتی را از یک فانکشن به فانکشن دیگر pass کنیم، می‌توانیم کمی این فانکشن مرکب را با مفاهیم ریاضی حل کنیم. در‌واقع می‌توانیم یک فانکشن مرکب واحد ساخته شده از دیگر فانکشن‌ها ایجاد کنیم ( به عنوان مثال ، ( (f ∘ g)(x) ). سرانجام، برای نتیجه‌گیری، همیشه وظیفه برنامه‌نویسان یا توسعه‌دهندگان است که یک مفهوم زبان برنامه‌نویسی را انتخاب کنند که روند توسعه آن‌ها را پربار و آسان‌تر کند. طبق ویکی پدیا، Object Oriented Programming یک پارادایم برنامه نویسی بر اساس مفهوم شی است.

در این مقاله می‌خواهم دلیل اینکه چرا در وهله اول وقت خودم را صرف یادگیری برنامه نویسی فانکشنال کردم، به شما بگوییم. در زیر جدول مقایسه بین برنامه نویسی فانکشنال در مقابل برنامه نویسی OOP یا شی‌گرا آورده شده است. در زیر ۸ مقایسه اصلی و برتر بین برنامه نویسی شی‌گرا و فانکشنال آورده شده. آیا نمیشه در شی‌گرایی کاری کرد که کدها پیچیده نشن؟ با گذشت زمان و مطالعه‌ی بیشتر در این باره به این نتیجه رسیدم که اتفاقا این امر کاملا امکان پذیره. میشه کدهایی شی‌گرا نوشت که به همون اندازه‌ی کدهای فانکشنال ساده و موثر باشن. اما فکر میکنم که این کار نیاز به یک دیسیپلین خیلی بالایی داره و انجامش خیلی راحت نیست.

هر یک از این سه توابع، تابع دیگری را به عنوان یکی از آرگومان های خود دریافت می‌کنند. پایتون یکی از محبوب‌ترین زبان‌های برنامه‌نویسی برای مبتدیان است. این زبان به دلیل سینتکس ساده و خوانا، یادگیری را بسیار آسان می‌کند. Python کاربردهای گسترده‌ای دارد؛ از توسعه وب و تحلیل داده‌ها گرفته تا هوش مصنوعی و یادگیری ماشین. این زبان به خوبی توسط جامعه برنامه‌نویسی پشتیبانی می‌شود و منابع آموزشی بی‌شماری برای آن وجود دارد.

مثال هایی که در ادامه خواهید دید با این پیش فرض از تابع reduce() استفاده می‌کنند. این بدان معناست که توابع دارای همان خصوصیاتی هستند که مقادیری مانند رشته ها و اعداد دارند. هر کاری که بتوان با یک رشته یا عدد انجام داد را می‌توانید با یک تابع نیز انجام دهید. با استفاده از این روش، ما حلقه‌های خود را با توابع انتزاع می‌کنیم و در مقایسه با مثال قبلی، می‌بینید که این کد شما را از مسئولیت مدیریت صحیح یک شمارنده حلقه و دسترسی به آرایه آزاد می‌کند. به زبان ساده‌تر، هرچه کد شما بیشتر باشد، مکان‌های بیشتری برای بروز اشکال وجود دارد. همچنین حلقه‌های استاندارد قابل استفاده مجدد نیستند، مگر اینکه با توابع انتزاع شده باشند.

همانطور که در آموزشهای قبلی این مجموعه مشاهده کرده‌اید، همیشه می‌توانید یک تابع را به روش معمول تعریف کنید. یعنی ممکن است یک زبان این امکان را داشته باشد که بشود با آن به چند شکل مختلف برنامه‌نویسی کرد. افزون‌بر پارادایم‌هایی که نام برده شد، پارادایم یا برنامه‌نویسی فانکشنال، تابعی یا تابع گرا (Functional) یکی از پارادایم‌های اصلی و رایج در برنامه‌نویسی است. بسیار خب، دریافتیم که می‌توانیم ترکیب فانکشن را در جاوا اسکریپت نیز انجام دهیم. اما مسأله مهم چیست؟ خب اگر شما واقعاً از برنامه نویسی فانکشنال استفاده می‌کنید، در حالت ایده‌آل تمام برنامه‌ی شما چیزی جز فانکش‌های مرکب نخواهد بود. در کد شما هیچ حلقه‌ای (for, for...of, for...in, while, do ) وجود نخواهد داشت.

این تکنیک یک تابع را در یک زمان به آرگومان های خود اعمال می کند، زیرا هر برنامه یک تابع جدید را برمی گرداند که آرگومان بعدی را می پذیرد. درک If-clauses، حلقه‌های for و in-place mutation ها برای ما انسان‌ها راحت است، ‌زیرا به این ترتیب داده‌ها را به صورت شهودی پردازش می‌کنیم. من نظریه دسته‌ها را از مقاله‌ی نظریه‌ دسته‌ها برای برنامه‌نویسان یادگرفتم که روشی آسان و دردسترس برای این نظریه هستند. حالا اگه بخوایم شی‌گرایی رو تعریف کنیم چی؟ باید چند صحفه فقط به تعریف‌اش اختصاص بدیم. مطمئنا به‌عنوان یک توسعه‌دهنده متوجه شده‌اید که نرم‌افزار‌ها هر روز پیچیده‌تر می‌شوند و توسعه و نگهداری از یک برنامه به سادگی قبل نیست. همچنین وظیفه‌ی توسعه، تست، نگهداری و گسترش برنامه‌های پیچیده‌ای که روزانه میلیون‌ها نفر را تحت تاثیر قرار می‌دهند، برعهده‌ی شما است.

اگر این فانکشن اصرار بر ساخت یک network call یا ورود به کنسول داشته باشد، به یک type signature دارد. ناگفته نماند که چنین محدودیت‌هایی شما را وادار می‌کند که در مورد کدنویسی متفاوت فکر کنید؛ و برای من این مورد بسیار خوب است. درواقع بهینه‌سازی برای فانکشن‌های recursive هم کار خواهد کرد، اما برای سادگی کار، ما فقط روی یک فانکشن recursive متمرکز می‌شویم. یعنی حاصل تمام اعداد صحیح از n تا ۱ .ما می‌توانیم یک حلقه بنویسیم که آن را به راحتی برای ما محاسبه کند. ما در تک دیک تلاش می کنیم محتوایی دقیق، واضح و بدون اشتباه منتشر کنیم.

تغییر ناپذیری یا Immutability یکی از اصول اصلی برنامه نویسی فانکشنال است. شما با این اصل در کنار فانکشن‌های خالص(pure functions) استدالال برنامه‌ها و دیباگ آن‌ها را راحت می‌کنید. برنامه‌نویسی فانکشنال (Functional Programming) یک سبک برنامه‌نویسی است که تمرکز اصلی آن بر استفاده از توابع به‌عنوان واحد اصلی ساختار برنامه است. برخلاف رویکردهای دستوری که از دستورات و حلقه‌ها برای انجام کارها استفاده می‌کنند، در برنامه‌نویسی فانکشنال، کدها به شکلی ساختاریافته و بدون وابستگی به حالت‌های بیرونی نوشته می‌شوند. به این معنی که توابع نتیجه‌ای مشخص ارائه می‌دهند، بدون اینکه نیازی به تغییر وضعیت‌ها و متغیرهای بیرونی داشته باشند.

هر شیء میتواند داده هایی در خود داشته باشد، که آنها را با عنوان “صفت” میشناسیم. ویژگی اصلی اشیا، این هست که method ها میتوانند به داده های مرتبط با شی، دسترسی داشته باشند و گاهی آنها را اصلاح کنند. تغییر ناپذیری مربوط به تمام ساختار داده‌هایی است که شامل آرایه‌ها، مپ‌ها و ست‌ها هستند. و این به این معناست که ما نمی‌توانیم mutator method هایی مثل array.prototype.push را فراخوانی کنیم چراکه آن آرایه‌ موجود را تغییر می‌دهد. به جای اینکه آیتم جدیدی را به آرایه‌ی موجود اضافه کنیم، می‌توانیم یک آرایه جدید با همان آیتم‌های آرایه اصلی به علاوه‌ی یک آیتم اضافی ایجاد کنیم.

این مفهوم به به این معنی است که نگهداری (maintain) از برنامه نویسی فانکشنال آسان‌تر است، زیرا نیازی نیست نگران تغییر تصادفی چیزی خارج از تابع مشخص باشید. من عاشق برنامه نویسی فانکشنال هستم زیرا به من دلیل می‌دهد تا دوباره ریاضی بخوانم و این است که مرا مجبور می‌کند متفاوت فکر کنم تا روش‌های خوبی برای برنامه نویسی به وجود آید. Swift زبان برنامه‌نویسی اصلی اپل برای توسعه اپلیکیشن‌های iOS و macOS است. این زبان به دلیل سادگی و سرعت بالا، به سرعت مورد توجه توسعه‌دهندگان قرار گرفته است. Swift به شما امکان می‌دهد اپلیکیشن‌های کاربرپسند و پرسرعتی برای دستگاه‌های اپل ایجاد کنید. این زبان با ابزارهایی مانند Xcode ترکیب می‌شود تا فرآیند توسعه آسان‌تر و کارآمدتر شود.

همچنین می‌توانستیم از فانکشن‌های مرکب یا همان function composition که قبلاً درباره آن صحبت کردیم، استفاده کنیم. هر دو مثال با استفاده از Ramda است؛ توجه داشته باشید که Ramda دارای یک mean function  است که می‌توان به جای reduce از آن استفاده کرد. JavaScript نیز به دلیل ساختار و پشتیبانی گسترده از توابع، یکی از زبان‌هایی است که به‌خوبی با برنامه‌نویسی فانکشنال سازگار است. JavaScript توابع را به‌عنوان واحدهای درجه یک در نظر می‌گیرد و قابلیت‌های فراوانی برای کار با آن‌ها ارائه می‌دهد. استفاده از روش‌های فانکشنال در JavaScript برای توسعه‌ی اپلیکیشن‌های وبی بسیار کاربردی است و می‌تواند کدهای پویا و قابل تغییر را به‌سادگی مدیریت کند. با برنامه نویسی فانکشنال، برنامه‌ها به ناچار متفاوت به نظر می‌رسند.

بنابراین، در هنگام اجرای برنامه متوجه خواهید شد که چه اتفاقی خواهد افتاد و یا نخواهد افتاد و عوارض جانبی آن را مدنظر می‌گیرید. در اصطلاح برنامه نویسی فانکشنال به این اتفاق شفافیت ارجاعی (Referential transparency) می گویند. زبان های تابعی به جای اجرای statement ها (مجموعه ای از دستورالعمل ها) بر expression ها و declaration ها تاکید دارند. بنابراین، بر خلاف سایر رویه‌ها (procedures) که به یک وضعیت (state) محلی یا سراسری بستگی دارند، مقدار خروجی در برنامه نویسی تابعی فقط به آرگومان‌های ارسال شده به تابع بستگی دارد. ۲.برنامه نویسی فانکشنال داشتن یک مدل برنامه نویسی stateless است.

حتی اگه شما هم قادر به انجامش باشید، عامه‌ی برنامه‌نویس‌های شی‌گرا قادر به پیاده‌سازی کدهای شی‌گرای موثر نیستن. ما از const استفاده کردیم و متغییرها نمی‌توانند تغییر مجدد پیدا کنند، اما هنوز هم مشکلی وجود دارد، آبجکت می‌تواند تغییر کند. همانطور که در کد زیر مشخص است، برای به دست آوردن تغییر ناپذیری واقعی باید از تعیین مجدد متغییر جلوگیری کنید و همچنین به یک ساختار داده‌ی غیرقابل تغییر نیاز دارید. زبان جاوااسکریپت متد Object.freeze را برای جلوگیری از تغییر یک آبجکت در اختیار ما قرار می‌دهد. اگر به احتمال زیاد وب سایت یا برنامه‌های دسکتاپ را طراحی می‌کنید، از زبان‌های شی گرا مانندC ++ ،Java ،JavaScript ،Ruby ، PHP استفاده می‌کنید. برخی از مفاهیم این زبان‌های برنامه نویسی با یکدیگر مشترک هستند که باعث می‌شود در گروه OOP قرار بگیرند.

امیدوارم که ویدیوی بالای صفحه رو دیده باشید و یک درک کلی از مفهوم آموزش برنامه نویسی فانکشنال و نوشتن تابع در php بدست آورده باشید. اگر سوال یا موردی در زمینه توابع در برنامه نویسی دارید حتما بپرسید با افتخار پاسخگوی سوالات شما عزیزان هستیم. بسیاری از زبان های برنامه نویسی، تا حدی، از برنامه نویسی فانکشنال پشتیبانی می‌کنند. در بعضی از زبان ها، تقریباً تمامی ‌قسمت های یک کد از الگوی فانکشنال پیروی می‌کند. در مقابل، پایتون در کنار برنامه نویسی فانکشنال، از سایر مدل های برنامه نویسی نیز پشتیبانی می‌کند.

همچنین، به دلیل ساختار مستقل و استفاده از داده‌های غیرقابل تغییر، برنامه‌های فانکشنال برای پردازش موازی مناسب هستند. توجه داشته باشید که توابع Higher-Order می توانند خالص باشند و ناخالص شدن آنها بستگی به نحوه استفاده شما از آنها دارد. اگر تابعی که بعنوان آرگومان به آنها میدهید ناخالص باشد, این باعث میشود که آن قسمت که شما تابع را صدا کرده اید ناخالص شود. چرا که تابع زمانی خالص است که تمام توابعی که صدا میکند نیز خالص باشند. بطور مثال اگر ما تابعی را به map بدهیم که از یک متغییر عمومی استفاده میکند, آنوقت خروجی ما ناخالص است.

Map(, , ,..., ) applies تابع را روی عناصر هر یک از تکرار‌شونده ها به طور موازی اعمال می‌کند و یک تکرار‌شونده حاوی نتایج را برمی‌گرداند. این کد به شرطی که عناصر لیست همگی رشته باشند، به خوبی عمل می‌کند. Map(, ) یک تکرار‌شونده را بر‌می‌گرداند که حاوی نتایج اعمال تابع f روی تک تک عناصر تکرار‌شونده ورودی است. در حالت ایده‌آل، حلقه‌های دستی باید کاملا از کد شما حذف شود و به نفع توابع درجه یک مانند نقشه، کاهش و فیلتر که توابع را به عنوان پارامتر می‌پذیرد تا کد شما قابل استفاده مجدد و گسترش‌پذیر باشد. Closure یک تابع درونی است که می تواند به متغیرهای تابع والد دسترسی داشته باشد، حتی پس از اجرای تابع والد. ماژول های کوچک را می توان به سرعت کدگذاری کرد و شانس بیشتری برای استفاده مجدد دارند که مطمئناً منجربه توسعه سریع تر برنامه ها می شود.

در یک تابع متغییرهای داخلی یعنی متغییرهایی که در خود تابع تعریف میشوند و آرگومان های آن تابع. Filter(, ) تابع را روی هر عنصر تکرار‌شونده اعمال می‌کند و خروجی آن نیز یک تکرار‌شونده است که حاوی عناصریست که خروجی تابع ارزیابی برای آن ها truth بوده است. در مقابل، این تابع عناصری را که خروجی اجرای آن ها در تابع ، false است را کنار می‌گذارد. اگر چه map() هدف ما را در مثال بالا برآورده کرده است اما پایتونیک(!) تر است که ما از یک لیست برای جایگزینی حلقه در این مورد استفاده کنیم. اگر لیستی از رشته ها دارید، می‌توانید از map() برای اعمال تابع reverse() روی تمامی ‌عناصر آن لیست استفاده کنید. به طور معمول، اگر به آن یک لیست از مقادیر رشته ای را بدهید، این تابع آن ها را به ترتیب حروف الفبا مرتب می‌کند.

نتیجه آن غیر قابل پیش‌بینی است، زیرا متغیر شمارنده می‌تواند در هر زمان بین هر فراخوانی تغییر کند. برنامه نویسی تابعی یا FP روشی برای تفکر در مورد ساخت نرم افزار است که بر اساس برخی از اصول اساسی تعریف می شود و به شما امکان می دهد از مشکلات و خطاهای گیج کننده در کد جلوگیری کنید. البته شاید کافرما یا حتی اعضای تیم به این مسأله که شما چگونه چیزی را حل می‌کنید اهمیت ندهند و آن را درک نکند و این یکی از دلایلی است که من برنامه نویسی فانکشنال را یک سرگرمی برای خودم می‌دانم. اولین دلیل من برای برنامه نویسی فانکشنال این است که ریاضی را به برنامه نویسی بازمی‌گرداند. با انتخاب هدف مناسب، یادگیری زبان‌های پایه، استفاده از منابع آموزشی معتبر و تمرین مداوم، می‌توانید به یک برنامه‌نویس موفق تبدیل شوید.

به جای شلوغ کردن کدتان ، می‌توانید از عبارت لاندا برای تعریف یک تابع ناشناس استفاده کنید. توابع ناخالص (Impure functions) دقیقاً در مقابل توابع خالص (Pure function) قرار می‌گیرند. توابع ناخالص را نمی توان به صورت مجزا مورد استفاده قرار داد یا آزمایش کرد زیرا وابستگی دارند. این دیگه چجور پیشنهادیه؟ آیا اصلا میشه به این شکل با جاوا برنامه‌نویسی کرد؟ بله، میشه. اتفاقا اگر به این پیشنهاد عمل کنید کلی از دردسرهاتون کم میشه. از تاثیرات جانبی این پیشنهاد اینه که چون دست متدها برای ویرایش فیلدها بسته است، بنابراین مجبور میشید تعداد متدهای کلاس رو کم کنید.

از آن‌جا که ضرب برداری قابلیت جابه جایی دارد، پس تفاوت نمی‌کند که به چه ترتیبی بردارها را به فانکشن pass کنیم. بیایید از یک مثال متفاوت برای نمایش placeholder استفاده کنیم. Ramda از دو underscore (ـ) به عنوان placeholder استفاده می‌کند. در واقع هر تابعی را، که روی دنباله ای از عناصر اجرا می‌شود، می‌توان با تابع reduce() پیاده سازی کرد. در واقع گایدو راست می‌گفت که بهترین و ساده ترین نوع استفاده از تابع reduce() همان عملگر‌های انجمنی هستند.

به‌همین منظور باید از همان ابتدای توسعه، کدها را با ساختار مناسبی بنویسیم که درک، توسعه، دیباگینگ و نگهداری از آن آسان باشد و حتی قادر باشیم مجددا از آن کدها در بخش‌های دیگری استفاده کنیم. البته این موضوع برای مبتدیان بسیار دلهره‌آور خواهد بود زیرا آن‌ها در حال توسعه‌ی برنامه‌هایی هستند که فقط کار می‌کند و نوشتن کدهایی با این قابلیت‌ها دشوار است. نام فانکشن یک شناسۀ دلخواه است و برای انتخاب آن باید تمامی قواعد مربوط به انتخاب شناسه‌ها در زبان برنامه‌نویسی پایتون را رعایت کنیم که جهت مرور این قواعد می‌توانید به آموزش آشنایی با مفهوم متغیر در این زبان مراجعه کنید. به عبارت ساده‌تر، برنامه نویسی شی گرا از شما می‌خواهد که همه چیز را به عنوان یک موجودیت با استفاده از سینتکسی به نام کلاس تعریف کنید. توابع آماده php هم کمک زیادی به ما در برنامه نویسی میکنن حتما میدونید که کلی توابع آماده در php داریم بیش از 1000 تا…! که در زمینه های مختلف کار میکنن و ما میتونیم براحتی ازشون استفاده کنیم.

در برنامه‌نویسی نیز وظیفۀ هر فانکشن انجام یک کار است و بنابراین بهتر است که نام انتخابی برای آن متناسب با کاری باشد که انجام می‌دهد. برنامه نویسی فانکشنال اساسا از مدل ها و مفاهیم ریاضیاتی بهره برده است, در حالی که برنامه نویسی شئ گرا از ساختار کلی جهان و اشیا بهره برده است. اگر در دنیای توسعه نرم افزار و برنامه نویسی باشید, احتمالا در کنار برنامه نویسی شئ گرا, اسم برنامه نویسی Functional به گوشتون خورده. اینکه برنامه نویسی فانکشنال چی هست؟ چه فلسفه ای داره؟ چه مباحثی داره؟ و در آخر مزایا و معایب اون چیه؟ صحبت خواهیم کرد. در سطح بالا، برنامه نویسی فانکشنال به طور موثر تأثیر متقابل بین تجزیه (شکستن برنامه‌ها به قطعات کوچک) و ترکیب (پیوستن قطعات به یکدیگر) است.


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