منو
 صفحه های تصادفی
سعید جعفرزاده
تناول از میوه های بهشتی
رنگ اجسام
منطق دانان اسلامی
دندانهای سالم
تقوا مداری
کنج
خداوند در فلسفه فارابی
قصّه
دانشگاه آزاد اسلامی استان آذربایجان شرقی
 کاربر Online
756 کاربر online
تاریخچه ی: برنامه نویسی تابعی

V{maketoc}

__ برنامه نویسی تابعی __ یک (( دسته بندی برنامه نویسی)) است که با ((محاسبه)) به عنوان یک ارزیابی از ((تابع های ریاضی)) رفتار می کند.

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

!مقدمه

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

یک تابع از این جهت، صفر یا تعداد بیشتری پارامتر ورودی، و یک مقدار بازگشتی دارد. پارامترها – یا آرگومان ها، که گاهی به این نام خوانده می شوند- ورودی های تابع هستند، و مقدار بازگشتی، خروجی تابع است. تعریف تابع تشریح می کند که تابع چگونه باید برحسب توابع دیگر ارزیابی شود. به عنوان مثال، تابع''f(x) = x2 + 2'' برحسب توابع توان و جمع تعریف شده است. از بعضی دیدگاه ها، زبان باید توابع اساسی را داشته باشد تا نیاز به تعریف بیشتر نباشد.

توابع می توانند از راه های گوناگونی در یک زبان برنامه نویسی تابعی دستکاری شوند. با توابع به عنوان ((مقدارهای کلاس اول)) رفتار می شود، که باید گفته شود توابع می توانند پارامترها یا ورودی های توابع دیگر بوده ونیز مقادیر بازگشتی یا خروجی های یک تابع باشند. این به توابعی مثل mapcar در ((__LISP__)) و map در ((Haskell)) اجازه می دهد که هم یک تابع و هم یک لیست را به عنوان ورودی بردارند و تابع ورودی را برای هر عنصر از لیست بکار برند. توابع می توانند نامگذاری شوند، مانند زبان های دیگر، یا به صورت بی نام ( گاهی در حین اجرای برنامه) با استفاده از انتزاع lambda تعریف شده و به عنوان مقدار در توابع دیگر استفاده شوند. زبان های تابعی همچنین به توابع، امکان "پرداخت" شدن را می دهد. ((پرداخت)) یک تکنیک برای دوباره نویسی یک تابع با پارامترهای چندگانه به عنوان ترکیبی از توابع یک پارامتر است. یک تابع پرداخت شده می تواند برای یک زیر مجموعه از پارامترهایش به کار رود. نتیجه تابعی است جایی که پارامترها در این زیر مجموعه حالا به عنوان ثابت ها، ثابت شده اند و مقادیر بقیه ی پارامترها هنوز نامشخص است. این تابع جدید می تواند برای پارامترهای باقی مانده برای بدست آوردن مقدار تابع نهایی بکار رود.

به عنوان مثال، یک تابع add(x,y) = x +y می تواند پرداخت شود بنابراین مقدار بازگشتی (2)add – توجه داشته باشید که پارامتر y وجود ندارد – یک تابع بی نام خواهد بود که معادل تابع add2 (y) = 2 + y است.
این تابع جدید فقط یک پارامتر دارد و معادل جمع 2 با یک عدد است. دوباره تاکید می کنیم که چنین چیزی تنها به این دلیل ممکن است که با توابع به عنوان مقادیر کلاس اول رفتار میشود.

!تاریخچه

((حساب Lambda)) می تواند اولین زبان برنامه نویسی تابعی در نظر گرفته شود، اگر چه برای اجرا روی یک کامپیوتر طراحی نشده است. حساب Lambda یک مدل محاسبه است که به وسیله ی ((Alonzo Church)) در دهه ی ((1930)) طراحی شده است که یک راه خیلی رسمی برای توصیف ارزیابی تابع تامین می کند. اولین زبان برنامه نویسی تابعی بر اساس کامپیوتر ((زبان پردازش اطلاعات)) __(IPL) __ بود، که بوسیله ی Newell، Shaw، و Simon در ((شرکت RAND)) برای کامپیوتر __((JOHNNIAC)) __در اواسط دهه ی ((1950)) گسترش یافت. زبان برنامه نویسی تابعی پیشرفته تر __((LISP))__ بود که به وسیله ی ((John McCarthy)) در ((انستیتوی تکنولوژی ماساچوست)) برای کامپیوترهای علمی __((IBMسری 700/7000))__ در اواخر دهه ی ((1950)) گسترش یافت. در حالیکه __LISP __ یک زبان برنامه نویسی تابعی کامل نبود، ولی بسیاری از خصیصه هایی را که الان در زبان های برنامه نویسی تابعی مدرن یافت می شود را معرفی می کرد. زبان ((Scheme)) تلاش بعدی برای ساده سازی و گسترش __LISP __ بود. در دهه ی ((1970)) زبان ((ML)) در ((دانشگاه ادینبرگ)) ایجاد شد، و ((دیوید ترنر)) زبان ((Muranda)) را در ((دانشگاه کنت )) گسترش داد. زبان ((Haskell)) در اواخر دهه ی ((1980)) در یک تلاش برای جمع آوری نظرات در تحقیق برنامه نویسی تابعی ایجاد شد.

!مقایسه با برنامه نویسی آمرانه

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

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

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

!زبان های برنامه نویسی تابعی

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

برنامه نویسی تابعی اغلب بستگی زیادی به بازگشت دارد.(( زبان برنامه نویسی Scheme))
حتی نیاز به انواع مشخص بازگشت ((«بازگشت دنباله ای))) دارد که شناخته شود و به صورت اتوماتیک به وسیله کامپایلر بهینه شود.

درضمن، زبان های برنامه نویسی تابعی احتمال دارد ((شفافیت مرجعی)) را اجرا کند، تصور آشنایی است که مساویها می توانند با یکدیگر جایگزین شوند: اگر دو عبارت با مقدارهای مساوی تعریف شوند، یکی می تواند درهر عبارت بزرگتری، بدون تاثیر روی نتیجه ی محاسبه جایگزین دیگری شود. به عنوان مثال، در
z = f ( sqrt (2) , sqrt (2) );
ما می توانیم sqrt (2) را فاکتور بگیریم و بنویسیم
s = sqrt (2) ;
z = f ( s, s) ;
بنابراین ارزیابی اضافی از تابع ریشه ی دوم حذف می شود.
بدیهی است که چنین موردی همیشه در (( زبان آمرانه)) برقرار نیست. یک مورد مناسب، تابع getchar ( ) (( زبان برنامه نویسی C)) است، که اکیداً تابعی است نه از آرگومان هایش که از محتوای جریان ورودی stdin و مقداری که قبلاً خوانده شده است. به مثال روبرو توجه کنید:
z = f ( getchar ( ) , getchar ( ) ) ;
ما ''نمی توانیم'' getchar ( ) را مانند sqrt (2) حذف کنیم، چون در C، " getchar ( )" باید دو مقدار متفاوت را در دو باری که فراخوانی می شودبرگرداند.

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

با حذف این شکاف های اطلاعاتی مخفی، زبان های برنامه نویسی تابعی امکان برنامه های بهتر که برای طراحی و عیب یابی، ساده ترند را فراهم می کند. اگر چه، آنها محاسن دیگری نیز دارند.

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

!توابع مرتبه بالاتر

یک مکانیزم قدرتمند که گاهی اوقات در برنامه نویسی تابعی استفاده می شود عقیده ی ((توابع مرتبه بالاتر)) است. توابع مرتبه بالاتر، توابعی هستند که بتوانند توابع دیگر را به عنوان آرگومان قبول کنند و یا آنها را به عنوان نتیجه برگردانند، ((«کلمه مشتق)) در ((حساب)) یک نمونه ی معمول از یک تابعی است که تابعی را به تابع دیگر تصویر می کند.)

توابع مرتبه بالاتر درتئوری ((حساب Lambda)) قبل از این که تصور برنامه نویسی تابعی به وجود بیاید، مطالعه شده بودند، و روی طراحی بسیاری از زبان های برنامه نویسی تابعی، مانند ((Haskell)) تاثیر گذاشته اند، و حتی بذر دسته بندی ((برنامه نویسی سطح تابع)) را که شامل زبان هایی مثل Backus'((FP)) است را افشاندند.

!ملاحظات فضا و سرعت

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

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

برای زبان هایی که بیشتر وقتشان را روی انجام محاسبات عددی می گذرانند، بعضی از زبانهای تابعی (مثل ((OCmal)) و ((Clean))) می توانند به سرعت ((C)) نزدیک شوند، در حالی که برای برنامه هایی که ماتریس های بزرگ و بانک های اطلاعاتی چند بعدی را دستکاری می کنند، زبان های تابعی ((آرایه ای)) (مثل ((J)) و ((K))) معمولاً سریعتر از برنامه های C غیر بهینه هستند.

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

! زبان های نمونه

قدیمی ترین نمونه ی زبان تابعی ((__LISP__)) است ( با استفاده از اسم اصلی برای تاکید روی Lisp "خالص"). نمونه ی قانونی جدید ((Haskell)) است. بقیه شامل ((Scheme))، ((Erlang))، ((Clean))، و ((Miranda)) می باشد.

((طبقه بندی زبان های تابعی)) یک لیست جامعی را شامل می شود.

!همچنین ببینید

*((برنامه نویسی رویه ای))
*((دسته بندی های برنامه نویسی))
*((ارزیابی تنبل))
*((ارزیابی مشتاقانه))
*((لیست عنوان های برنامه نویسی تابعی))

تاریخ شماره نسخه کاربر توضیح اقدام
 شنبه 22 اردیبهشت 1386 [09:07 ]   5   زینب معزی      جاری 
 سه شنبه 11 مهر 1385 [13:11 ]   4   زینب معزی      v  c  d  s 
 پنج شنبه 23 شهریور 1385 [11:45 ]   3   زینب معزی      v  c  d  s 
 دوشنبه 03 اسفند 1383 [10:04 ]   2   نفیسه ناجی      v  c  d  s 
 شنبه 25 مهر 1383 [10:49 ]   1   10.1.1.9      v  c  d  s 


ارسال توضیح جدید
الزامی
big grin confused جالب cry eek evil فریاد اخم خبر lol عصبانی mr green خنثی سوال razz redface rolleyes غمگین smile surprised twisted چشمک arrow



از پیوند [http://www.foo.com] یا [http://www.foo.com|شرح] برای پیوندها.
برچسب های HTML در داخل توضیحات مجاز نیستند و تمام نوشته ها ی بین علامت های > و < حذف خواهند شد..