دالة خالصة

في برمجة الحاسوب ، الدالة النقية هي دالة لها الخصائص التالية: [ 1 ] [ 2 ]

  1. تكون قيم الإرجاع للدالة متطابقة لنفس الوسائط (لا يوجد اختلاف مع المتغيرات الثابتة المحلية ، أو المتغيرات غير المحلية ، أو وسائط المرجع القابلة للتغيير ، أو تدفقات الإدخال ، أي الشفافية المرجعية )، و
  2. لا توجد آثار جانبية للوظيفة (لا يوجد تغيير في المتغيرات غير المحلية، أو وسائط مرجعية قابلة للتغيير، أو تدفقات الإدخال/الإخراج).

أمثلة

الدوال البحتة

الأمثلة التالية لوظائف C++ هي وظائف نقية:

  • floor، إرجاع الجزء الصحيح من عدد؛
  • max، إرجاع القيمة القصوى من بين قيمتين.
  • الدالة f ، المعرفة على النحو التالي
    void f () { static std :: atomic < unsigned int > x = 0 ; ++ x ; }
    xلا يمكن ملاحظة قيمة إلا داخل استدعاءات أخرى لـ f()، ولأن f()لا تُبلغ قيمة xإلى بيئتها، فهي لا تختلف عن دالة void f() {}لا تفعل شيئًا. تجدر الإشارة إلى أن xيُستخدم لمنع حدوث تضارب في البيانات نتيجةً std::atomicللتعديلات التي تُجريها عدة سلاسل عمليات متزامنة ، وهو ما يُعرف بسلوك غير مُحدد في لغتي C و C++.f()

الدوال غير النقية

تعتبر دوال C++ التالية غير نقية لأنها تفتقر إلى الخاصية 1 المذكورة أعلاه:

  • بسبب اختلاف قيمة الإرجاع مع متغير ثابت
    int f () { static int x = 0 ; ++ x ; return x ; }
  • بسبب تباين قيمة الإرجاع مع متغير غير محلي
    int f () { return x ; }
    وللسبب نفسه، على سبيل المثال، فإن دالة مكتبة C++ sin()ليست نقية، لأن نتيجتها تعتمد على وضع التقريب IEEE الذي يمكن تغييره في وقت التشغيل.
  • بسبب اختلاف قيمة الإرجاع مع وسيط مرجعي قابل للتغيير
    int f ( int * x ) { return * x ; }
  • بسبب اختلاف قيمة الإرجاع مع تدفق الإدخال
    دالة f () { int x = 0 ; std :: cin >> x ; return x ; }

تعتبر دوال C++ التالية غير نقية لأنها تفتقر إلى الخاصية 2 المذكورة أعلاه:

  • بسبب طفرة في متغير ثابت محلي
    void f () { static int x = 0 ; ++ x ; }
  • بسبب طفرة في متغير غير محلي
    void f () { ++ x ; }
  • بسبب تغيير وسيط مرجعي قابل للتغيير
    void f ( int * x ) { ++* x ; }
  • بسبب طفرة في تدفق الإخراج
    void f () { std :: cout << "Hello, world!" << std :: endl ; }

تعتبر دوال C++ التالية غير نقية لأنها تفتقر إلى الخاصيتين 1 و 2 المذكورتين أعلاه:

  • بسبب اختلاف قيمة الإرجاع مع متغير ثابت محلي وتغيير متغير ثابت محلي
    int f () { static int x = 0 ; ++ x ; return x ; }
  • بسبب تغير قيمة الإرجاع مع تدفق الإدخال وتغير تدفق الإدخال
    دالة f () { int x = 0 ; std :: cin >> x ; return x ; }

الإدخال/الإخراج في الدوال البحتة

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

تضمن النقطة الثانية أن التسلسل الوحيد القابل للاستخدام كوسيط يجب أن يتغير مع كل عملية إدخال/إخراج؛ أما النقطة الأولى فتسمح باستدعاءات مختلفة لدالة تُنفذ عمليات الإدخال/الإخراج بإرجاع نتائج مختلفة نظرًا لتغير وسائط التسلسل. [ 3 ] [ 4 ]

إن موناد الإدخال/الإخراج هو أسلوب برمجة يستخدم عادة لتنفيذ عمليات الإدخال/الإخراج في لغات البرمجة الوظيفية البحتة.

التخزين المؤقت

يمكن تخزين مخرجات دالة نقية مؤقتًا في جدول بحث. أي نتيجة تُعاد من دالة معينة تُخزن مؤقتًا، وفي المرة التالية التي تُستدعى فيها الدالة بنفس معلمات الإدخال، تُعاد النتيجة المخزنة مؤقتًا بدلًا من حساب الدالة مرة أخرى.

يمكن إجراء التخزين المؤقت عن طريق تغليف الدالة بدالة أخرى ( دالة التغليف ). [ 5 ]

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

برنامج مكتوب بلغة C لحساب المضروب المخزن مؤقتًا ( يتوقف assert()البرنامج مع رسالة خطأ إذا كانت وسيطته خاطئة؛ على جهاز 32 بت، fact(12)لا يمكن تمثيل القيم التي تتجاوز [ 6 ] ) .

static int fact ( int n ) { return n <= 1 ? 1 : fact ( n - 1 ) * n ; }دالة ` fact_wrapper` تأخذ وسيطين: `int n` و` int`. تقوم الدالة بتعريف متغير ثابت ` cache` يحتوي على مصفوفة من 13 عنصرًا . تتحقق الدالة من أن ` n` أقل من أو يساوي 0 وأقل من 13 عنصرًا . إذا كان ` n` يساوي صفرًا ، فإن ` n` يساوي صفرًا . ثم تقوم الدالة بإرجاع ` n` .

تحسينات المُترجم

تُتيح الدوال التي تتمتع بالخاصية الثانية المذكورة أعلاه فقط - أي التي لا تُحدث أي آثار جانبية - تقنيات تحسين المُصرّف، مثل حذف التعبيرات الفرعية المشتركة وتحسين الحلقات ، على غرار عوامل التشغيل الحسابية. [ 7 ] ومن الأمثلة على ذلك في لغة C++ length، الدالة التي تُعيد حجم سلسلة نصية، والذي يعتمد على محتويات الذاكرة التي تُشير إليها السلسلة، وبالتالي فهي تفتقر إلى الخاصية الأولى المذكورة أعلاه. ومع ذلك، في بيئة أحادية الخيوط ، فإن كود C++ التالي

std :: string s = "Hello, world!" ; int a [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; int l = 0 ;for ( int i = 0 ; i < 10 ; ++ i ) { l += s.length ( ) + a [ i ] ; }

يمكن تحسينها بحيث يتم حساب قيمة s.length()مرة واحدة فقط، قبل الحلقة.

تسمح بعض لغات البرمجة بتعريف خاصية نقية لدالة:

اختبار الوحدة

بما أن الدوال النقية لها قيم إرجاع متطابقة لنفس الوسائط ، فإنها مناسبة تمامًا لاختبار الوحدات .

انظر أيضاً

مراجع

  1. بارتوش ميليفسكي (2013). "أساسيات لغة هاسكل" . مدرسة هاسكل . FP Complete. مؤرشف من الأصل بتاريخ 27-10-2016 . تم الاطلاع عليه بتاريخ 13-07-2018 .
  2. برايان لونسدورف (2015). "دليل البروفيسور فريسبي الكافي إلى حد كبير للبرمجة الوظيفية" . جيت هاب . تم الاسترجاع في 20 مارس 2020 .
  3. بيتون جونز، سيمون ل. (2003). لغة هاسكل 98 والمكتبات: التقرير المنقح (ملف PDF) . كامبريدج، المملكة المتحدة: مطبعة جامعة كامبريدج. ص 95. ISBN  0-521 826144تم الاطلاع عليه بتاريخ 17 يوليو 2014 .
  4. هانوس، مايكل. "الكاري: لغة منطق وظيفية متكاملة" (PDF) . www-ps.informatik.uni-kiel.de . معهد المعلوماتية، جامعة كريستيان ألبرختس في كييل. ص. 33. مؤرشفة من الأصلي (PDF) في 25 يوليو 2014 . تم الاسترجاع 17 يوليو 2014 . 
  5. ألي، ر. (2017). برمجة PHP الوظيفية الاحترافية: استراتيجيات تطوير التطبيقات لتحسين الأداء، والتزامن، وقابلية الاختبار، واختصار الكود . سبرينغر لينك : بوخر. أبريس. ص 109. ISBN   978-1-4842-2958-3تم الاطلاع عليه بتاريخ 2024-02-04 .
  6. «حصلت على نتيجة غير صحيحة لحساب مضروب العدد 13، كيف يمكنني إصلاح ذلك؟» . Stack Overflow . تم الاطلاع عليه بتاريخ 24 سبتمبر 2025 .
  7. "سمات الوظائف الشائعة - استخدام مجموعة مترجمات جنو (GCC)" . gcc.gnu.org، مجموعة مترجمات جنو . مؤسسة البرمجيات الحرة . تم الاطلاع عليه بتاريخ 28-06-2018 .
  8. سمة نقية في لغة فورتران
  9. سمة نقية في لغة D
  10. "سمات الوظائف الشائعة" . استخدام مجموعة مترجمات GNU (GCC ). تم الاسترجاع في 22 يوليو 2021 .
  11. سمة constexpr في لغة C++