سعید نوری
سعید نوری
خواندن ۶ دقیقه·۷ سال پیش

طلوع، افول، و خیزش دوباره برنامه‌نویسی تابعی

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

او چیزی در این باره نمی‌دانست در نتیجه ما از پدرش سوال کردیم. پدرش یک کتاب از یک قفسه بلند برای ما پایین آورد، کتاب در مورد نوشتن بازی با زبان بیسیک بود. از همان جا سفر من در دنیای برنامه‌نویسی شروع شد. زمانی که در مدرسه به ما جبر یاد می‌دادند من از قبل آن را بلد بودم زیرا برنامه‌نویسی بر پایه جبر بنا نهاده شده است.


طلوع برنامه‌نویسی تابعی

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

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

این دو دانشمند با همکاری همدیگر نشان دادند که حساب لامبدا و ماشین تورینگ از لحاظ عملکرد معادل هم هستند.

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

حساب لامبدا سه ویژگی برجسته دارد:

  1. توابع همیشه بدون نام هستند. در جاوا اسکریپت طرف راست معادله const sum = (x, y) => x + y یک تابع بدون نام است یعنی این قسمت: x, y) => x + y)
  2. توابع در حساب لامبدا همیشه فقط یک ورودی می‌گیرند. اگر شما نیاز دارید که بیشتر از یک ورودی به تایع بدهید، تابع ورودی اول را می‌گیرد و یک تابع برمی‌گرداند که ورودی دوم را می‌گیرد، و به همین منوال تمام ورودی‌ها گرفته می‌شوند. تابع چندگانه x, y) => x + y) می‌تواند به صورت تابع یگانه x=>y=>x+y بیان شود. این تغییر شکل از تابع چندگانه به تابع یگانه اصطلاحاً کاری کردن (Currying) نامیده می‌شود.
  3. توابع عناصر درجه یک هستند. این یعنی توابع می‌توانند به عنوان ورودی توابع دیگر استفاده شوند، همچنین توابع می‌توانند به عنوان خروجی توابع دیگر را برگردانند.

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

روش کلاسیک ترکیب توابع اینجوری است که خروجی یک تابع به عنوان ورودی تابع دیگر استفاده می‌شود. به عنوان مثال ترکیب زیر:

f.g

می‌تواند اینطوری نوشته شود:

compose2 = f => g => x => f(g(x))

در مثال زیر شما می‌توانید نحوه استفاده از ترکیب توابع را ببینید:

double = n => n * 2
inc = n => n + 1
compose2(double)(inc)(3)

تابع compose2 تابع double را به عنوان آرگومان اول و تابع inc را به عنوان دوم می‌گیرد و ترکیب این دو تابع را بر روی آرگومان سوم یعنی عدد ۳ اعمال می‌کند.

عبارت صدا زدن تایع یعنی عبارت:

compose2(double)(inc)(3)

در واقع فراخوانی سه تابع مختلف است:

  1. اولین فراخوانی تابع double را پاس می‌دهد و یک تابع جدید برمی‌گرداند.
  2. تابع بازگردانده شده تابع inc را می گیرد و یک تابع جدید را برمی‌گرداند.
  3. تابع برگردانده شده از مرحله دوم عدد ۳ را می‌گیرد و ((f(g(x را معین می‌کند یعنی عبارت ((double(inc(3
  4. متغیر x برابر با ۳ می‌شود و به تابع inc پاس داده می‌شود.
  5. حاصل(inc(3 برابر با ۴ می‌شود.
  6. حاصل (double(4 برابر با ۸ می‌شود.
  7. عدد ۸ به عنوان خروجی تابع برگشت داده می‌شود.

هنگامی که نرم‌افزار نوشته می‌شود می‌تواند با یک گراف ترکیب توابع نشان داده شود. مثال زیر ا در نظر بگیرید:

append = s1 => s2 => s1 + s2
append('Hello, ')('world!')

شما می‌توانید مثال بالا را به صورت بصری مثل زیر نشان دهید:

حساب لامبدا در طراحی نرم‌افزار بسیار با نفوذ بود و تا قبل از حدود سال ۱۹۸۰ تعداد زیادی از شرکت‌های صاحب نام در عرصه کامپیوتر نرم افزارها را با استفاده از ترکیب توابع می‌ساختند. زبان لیسپ در سال ۱۹۵۸ ساخته شد و به میزان زیادی  تحت تاثیر حساب لامبدا بود. امروزه لیسپ دومین زبان قدیمی دنیا است که هنوز به صورت گسترده استفاده می‌شود.

من با لیسپ از طریق AutoLISP آشنا شدم. AutoLISP یک زبان اسکریپتی است که درمشهورترین نرم‌افزار  طراحی جهان یعنیاتوکد استفاده می‌شود. اتوکد آنقدر فراگیر است که تقریبا تمام برنامه‌های طراحی دیگر از AutoLISP به منظور سازگاری با اتوکد پشتیبانی می‌کنند. لیسپ همچنین یکی از زبان‌های آموزشی فراگیر در چارت درسی علوم کامپیوتر است به سه دلیل:

  1. سادگی آن باعث می‌شود یادگیری آن راحت باشد. یادگیری سینتکس لیسپ حدود یک روز طول می‌کشد.
  2. لیسپ تماما در مورد ترکیب توابع است و ترکیب توابع یک راه کارا در نوشتن نرم‌افزارهاست.
  3. بهترین مقاله‌ای که من در علوم کامپیوتر می‌شناسم از لیسپ استفاده کرده است: ساختار و تفسیر برنامه‌های کامپیوتری.


افول برنامه‌نویسی تابعی

زمانی بین سال‌های ۱۹۷۰ تا ۱۹۸۰، راهی که با آن نرم‌افزارها نوشته می‌شدند از ترکیب توابع جدا شد و تبدیل شد به دستورالعمل‌های خطی که کامپیوتر از آنها پیروی می‌کرد. سپس برنامه‌نویسی شی‌گرا از راه رسید. شی‌گرایی یک ایده عالی در مورد کپسوله‌سازی اجزا و ارسال پیام‌ها بود که توسط زبان‌های مشهور تحریف شد و تبدیل شد یک ایده وحشتناک از ارث‌بری سلسله مراتب و رابطه is-a برای استفاده مجدد.

برنامه‌نویسی تابعی به حاشیه رانده شد که یا توسط گیک‌ترین برنامه‌نویس‌ها استفاده می‌شد یا استادان دانشگاه‌ها و یا توسط بعضی از دانشجویان خوش‌شانس که از دنیای تسخیر شده توسط جاوا طی سال‌های ۱۹۹۰ تا ۲۰۱۰ گریخته بودند. برای اغلب ما به مدت ۳۰ سال متوالی نوشتن برنامه‌ها یک کابوس بود. سال‌های سیاه!


خیزش دوباره برنامه‌نویسی تابعی

حدود سال ۲۰۱۰ یک چیز عالی شروع به اتفاق افتادن کرد: جاوا اسکریپت منفجر شد! تا قبل از سال ۲۰۰۶ جاوا اسکریپت به عنوان یک زبان اسباب‌بازی تلقی می‌شد که با آن انمیشن‌های جالب به صفحات وب اضافه می‌کردند، اما جاوا اسکریپت ویژگی‌های قدرتمندی را در خودش پنهان کرده بود، به عنوان مثال مهم‌ترین ویژگی‌های حساب لامبدا. مردم در تاریکی شروع کردند به پچ‌پچ کردن در مورد یک چیز جالب جدید که «برنامه‌نویسی تابعی» نامیده می‌شد.

در سال ۲۰۱۵ ایده ساخت برنامه‌ها با استفاده از ترکیب توابع دوباره فراگیر شده بود. برای اینکه این کار ساده‌تر شود جاوا اسکریپت بعد از یک دهه اولین به روز رسانی عمده را دریافت کرد و توابع فلشی (arrow functions) به آن اضافه شد که این توابع کار ساختن و خواندن توابع، کاری کردن و عبارت‌های لامبدا را تسهیل کردند.

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

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


منبع: medium.com

این مطلب همچنین در این لینک در وبسایت شخصی من انتشار یافته است.

برنامه‌نویسیبرنامه‌نویسی تابعیبرنامه‌نویسی فانکشنالfunctional programming
علاقه‌مند به فناوری، توسعه دهنده پایتون و بک‌اند در آینده‌ای دور یا نزدیک!
شاید از این پست‌ها خوشتان بیاید