البرمجة الوظيفية Functional Programming

اقرأ في هذا المقال


ما هي البرمجة الوظيفية Functional Programming؟

البرمجة الوظيفية (وتسمى أيضًا “FP”)، هي طريقة للتفكير في إنشاء البرامج من خلال إنشاء وظائف (أي دوال) خالصة، أي أنه لا يوجد استخدام للمتغيرات أو كائنات (objects) أو الأماكن المحجوزة في الذاكرة في نطاق مشترك، والبيانات القابلة للتغيير التي لوحظت في البرمجة الشيئية، وتُركز لغات البرمجة الوظيفية على التعبيرات (expressions) وتعريف الوظيفة بدلاً من تنفيذ العبارات، لذلك، بخلاف البرمجة الإجرائية التي تعتمد على الحالة المحلية (local) أو الحالة العالمية (global)، تعتمد قيمة المخرجات في البرمجة الوظيفية فقط على العبارات التي تم تمريرها إلى الدالة.

خصائص البرمجة الوظيفية:

  • تركز طريقة البرمجة الوظيفية على النتائج وليس على العملية.
  • تركز أيضاً على ما يجب حسابه.
  • البيانات غير قابلة لتعديل.
  • البرمجة الوظيفية تقسم المشكلة إلى دوال (functions).
  • إن البرمجة الوظيفية مبنية على مفهوم الدوال الرياضية التي تَستخدم التعبيرات الشرطية وتقنية الاستدعاء الذاتي لإجراء الحساب.
  • لا تدعم الحلقات التكرارية مثل (while, for)، والعبارات الشرطية مثل (If-Else).

أمثلة على لغات البرمجة الوظيفية:

الهدف من أي لغة برمجة وظيفية، هو محاكاة الوظائف الرياضية، ومع ذلك، فإن العملية الأساسية للحساب تختلف في البرمجة الوظيفية، بعض أبرز لغات البرمجة الوظيفية: هاسكل (Haskell)، (SQL)، (SML)، (Clojure)، (Scala)، (#F)، (ML)، (XSLT).

مفاهيم ومصطلحات البرمجة الوظيفية الأساسية:

وظائف نقية Pure Functions:

هذه الوظائف (الدوال)، لها خاصيتان رئيسيتان، أولاً، ينتجون دائمًا نفس الناتج لنفس العبارات التي تم تمريرها إلى الدالة، ثانيًا، ليس لديهم أي آثار جانبية، أي أنه يتم تعديل المتغيرات العامة (المرئية لجميع أنحاء الكود) أو ينتجون شيئًا ما، النتيجة الوحيدة للدالة النقية هي القيمة التي ترجعها.

من السهل تصحيح أخطاء البرامج التي تتم باستخدام البرمجة الوظيفية؛ لأن الوظائف الصافية ليس لها أي آثار جانبية أو مخفية في الإدخال والإخراج، تعمل “الدوال النقية” أيضًا على تسهيل كتابة التطبيقات المتوازية والمتزامنة، عندما تتم كتابة التعليمات البرمجية بهذا النمط، يمكن للمترجم (compiler) القيام بالعديد من الأشياء، إذ يمكنه موازنة التعليمات، والانتظار لتقييم النتائج عند الحاجة إليها، وحفظ النتائج، وذلك نظرًا لأن النتائج لا تتغير أبدًا طالما أن الإدخال لا يتغير.

الاستدعاء الذاتي:

لا توجد حلقات تكرارية (“for” أو “while”) في اللغات الوظيفية، فيتم تنفيذ التكرار في اللغات الوظيفية من خلال الاستدعاء الذاتي، فتقوم الدوال باستدعاء نفسها بشكل متكرر حتى تصل إلى الحالة الأساسية.

بيانات غير قابلة للتغيير Immutable Data:

أي أنه في البرمجة الوظيفية، لا يمكننا تعديل المتغير بعد أن يتم تعيين قيمة له، حيث أنه بدلاً من تعديل المتغير، يمكننا إنشاء متغيرات جديدة (لكن لا يمكننا تعديل المتغيرات الحالية)، وهذا يساعد حقًا في صيانة البرنامج طوال وقت تشغيل البرنامج، وبمجرد إنشاء متغير وتحديد قيمته، يمكننا أن نثق تمامًا بمعرفة أن قيمة هذا المتغير لن تتغير أبدًا.

الشفافية المرجعية:

يجب أن تؤدي البرامج الوظيفية العمليات كما لو كانت لأول مرة، لذلك، ستعرف ما قد يحدث أو لا يحدث أثناء تنفيذ البرنامج، وآثاره الجانبية، في مصطلح البرمجة الوظيفية يطلق عليه الشفافية المرجعية.

ففي البرامج الوظيفية المتغيرات بمجرد تعريفها لا تغير قيمتها في جميع أنحاء البرنامج، ولا تحتوي البرامج الوظيفية على جمل التعين (مثل “1+x=x”)، بدلاً من ذلك، إذا كان علينا تخزين بعض قيم، فإننا نحدد متغيرات جديدة، هذا يلغي أي فرصة لحدوث آثار جانبية؛ لأنه لا يمكن استبدال أي متغير بقيمته الفعلية في أي نقطة من التنفيذ.

نمطية:

يزيد التصميم المعياري من الإنتاجية، يمكن كتابة كود للوحدات الصغيرة بسرعة، ولديها فرصة أكبر لإعادة استخدامها، مما يؤدي بالتأكيد إلى تطوير أسرع للبرامج، بصرف النظر عن ذلك، يمكن اختبار الوحدات النمطية بشكل منفصل مما يساعدك على تقليل الوقت الذي تقضيه في اختبار الوحدة وتصحيح الأخطاء البرمجية.

قابلية الصيانة:

قابلية الصيانة هو مصطلح بسيط، يعني أنه من الأسهل القيام بصيانة برنامج مكتوب باستخدام البرمجة الوظيفية، حيث لا داعي للقلق بشأن أي تغيير خارج الوظيفة المحددة.

دالات ذات الترتيب الأعلى:

تأخذ “دالات الترتيب الأعلى” إما دوال أخرى ك (parameter) أو تُرجعها كنتائج، تسمح “دالات الترتيب الأعلى” بالتطبيقات الجزئية، تطبق هذه التقنية على (parameter) دالة واحدة تلو الأخرى، حيث يقوم كل تطبيق بإرجاع دالة جديدة تقبل (parameter) التالية.

مزايا وعيوب البرمجة الوظيفية:

المزايا:

1- من السهل فهم “الدوال النقية”؛ لأنها لا تغير أي حالات وتعتمد فقط على المدخلات المعطاة لها، أياً كان الناتج التي تنتجه الدوال فهي القيمة التي سيتم إرجاعها، يعطي توقيع الدالة (أي نوع البيانات التي يتم إرجاعها والمُعاملات) جميع المعلومات المتعلقة بهم.

2- إن قدرة لغات البرمجة الوظيفية على التعامل مع الدوال كقيم وتمريرها إلى دوال أخرى ك (parameters) يجعل الكود أكثر قابلية للقراءة والفهم بسهولة.

3- تصبح الاختبارات وتصحيح الأخطاء البرمجية أسهل، نظرًا لأن “الدوال النقية” تأخذ معاملات (parameters) فقط وتنتج مخرجات، فإنها لا تنتج أي تغييرات (أي لا تأخذ مدخلات من المستخدم ولا تنتج بعض المخرجات المخفية)، ولأن البرمجة الوظيفية تستخدم قيمًا غير قابلة للتغيير، فإنه يصبح من السهل التحقق من بعض المشكلات في البرامج المكتوبة باستخدامها.

4- إن قدرة لغات البرمجة الوظيفية على التعامل مع الدوال كقيم، وتمريرها إلى دوال أخرى كمعاملات تجعل الكود أكثر قابلية للقراءة والفهم بسهولة.

5- يتم استخدام البرمجة الوظيفية لتنفيذ التزامن أو التوازي؛ لأن الوظائف النقية لا تغير المتغيرات أو أي بيانات أخرى خارجها.

العيوب:

1- في بعض الأحيان، قد تؤدي كتابة “وظائف نقية” إلى تقليل قابلية قراءة الكود.

2- يمكن أن يشكل كتابة البرامج بتقنية الاستدعاء الذاتي بدلاً من استخدام الحلقات التكرارية تهديداً لبعض المبرمجين.

3- تعد كتابة “الوظائف النقية” أمرًا سهلاً، ولكن دمجها مع باقي التطبيقات وعمليات الإدخال والإخراج مهمة صعبة.

4- يمكن أن تؤدي القيم الغير قابلة للتغير و الاستدعاء الذاتي إلى انخفاض في الأداء.


شارك المقالة: