استراتيجية التقييم

في لغات البرمجة ، تُعرَّف استراتيجية التقييم بأنها مجموعة من القواعد لتقييم التعبيرات . [ 1 ] يُستخدم هذا المصطلح غالبًا للإشارة إلى المفهوم الأكثر تحديدًا لاستراتيجية تمرير المعاملات [ 2 ] التي تُحدد نوع القيمة التي تُمرَّر إلى الدالة لكل معامل ( استراتيجية الربط ) [ 3 ] ، وما إذا كان سيتم تقييم معاملات استدعاء الدالة، وإذا كان الأمر كذلك، فما هو ترتيب التقييم ( ترتيب التقييم ). [ 4 ] يختلف مفهوم استراتيجية الاختزال [ 5 على الرغم من أن بعض المؤلفين يخلطون بين المصطلحين، ولا يوجد اتفاق واسع النطاق على تعريف كل منهما. [ 6 ] تُعد استراتيجية التقييم في لغة البرمجة جزءًا من دلالاتها عالية المستوى . بعض اللغات، مثل PureScript ، لها متغيرات ذات استراتيجيات تقييم مختلفة. بعض اللغات التصريحية ، مثل Datalog ، تدعم استراتيجيات تقييم متعددة.

كما هو الحال في الرياضيات، فإن التقييم هو عملية إيجاد القيمة المقابلة لتعبير ما. [ 7 ] [ 8 ]

تتألف اتفاقية الاستدعاء من التفاصيل الخاصة بالمنصة على مستوى منخفض لتمرير المعلمات.

مثال

على سبيل المثال، قد يقوم استدعاء دالة f(a, b)أولاً بتقييم الوسيطين ` ax` و`y` b، ثم يخزن النتائج في مراجع أو مواقع ذاكرة `x` ref_aو`y` ref_b، ثم يُقيّم جسم الدالة باستخدام تلك المراجع المُمررة. يُمكّن هذا الدالة من البحث عن قيم الوسائط الأصلية المُمررة من خلال فك مرجعية المعاملات (تستخدم بعض اللغات عوامل تشغيل مُحددة لهذا الغرض)، وتعديلها عبر التعيين كما لو كانت متغيرات محلية، وإرجاع القيم عبر المراجع. هذه هي استراتيجية التقييم بالمرجع. [ 9 ]

طاولة

هذا جدولٌ يُبيّن استراتيجيات التقييم واللغات المُمثلة لها، مُصنّفةً حسب سنة تطبيقها. وقد رُتّبت اللغات المُمثلة ترتيبًا زمنيًا، بدءًا باللغة (أو اللغات) التي طبّقت الاستراتيجية، ثم اللغات البارزة التي تستخدمها. [ 10 ] : 434

استراتيجية التقييماللغات التمثيليةالسنة التي تم فيها طرحها لأول مرة
الاتصال عن طريق المرجعفورترانPL/I1958
الاتصال بالقيمةALGOL ، C ، [ 11 ] Scheme ، MATLAB [ 12 ]1960
الاتصال بالاسمALGOL 60 ، محاكاة1960
اتصل عن طريق النسخ والاستعادةFortran IV ، Ada [ 13 ]1962
دعوة من خلال التوحيدمقدمة1965 [ 14 ] [ 15 ]
اتصل عند الحاجةSASL ، [ 16 ] Haskell ، R [ 17 ]1971 [ 18 ]
اتصل عبر المشاركةكلو ، جافا ، بايثون ، روبي ، جوليا1974 [ 19 ]
معلمات الاستدعاء بالمرجعC++ ، PHP ، [ 20 ] C# ، [ 21 ] Visual Basic .NET [ 22 ]1985 [ 23 ]
استدعاء بالمرجع إلى ثابتسي++ ، سي1985 [ 23 ]

أوامر التقييم

بينما يحدد ترتيب العمليات شجرة بناء الجملة المجردة للتعبير، فإن ترتيب التقييم يحدد الترتيب الذي يتم به تقييم التعبيرات. على سبيل المثال، برنامج بايثون

دالة f ( x ): اطبع ( x , end = "" ) أرجع xاطبع ( f ( 1 ) + f ( 2 ))

تُعزى هذه المخرجات 123إلى ترتيب التقييم من اليسار إلى اليمين في لغة بايثون، ولكن يوجد برنامج مشابه مكتوب بلغة OCaml :

let f x = print_int x ; x ;; print_int ( f 1 + f 2 )

تُعزى هذه المخرجات 213إلى ترتيب التقييم من اليمين إلى اليسار في لغة OCaml.

يظهر ترتيب التقييم بشكل أساسي في التعليمات البرمجية ذات التأثيرات الجانبية ، ولكنه يؤثر أيضًا على أداء التعليمات البرمجية لأن الترتيب الصارم يعيق جدولة التعليمات . لهذا السبب، تركت معايير لغات البرمجة مثل C++ الترتيب غير محدد تقليديًا، على الرغم من أن لغات مثل Java وC# تُعرّف ترتيب التقييم من اليسار إلى اليمين [ 10 ] : 240-241، وقد أضاف معيار C++17 قيودًا على ترتيب التقييم. [ 24 ]

تقييم صارم

الترتيب التطبيقي هو نوع من ترتيبات التقييم حيث تُقيّم وسائط الدالة بالكامل قبل تطبيقها. [ 25 ] وهذا يجعل الدالة صارمة ، أي أن نتيجتها غير مُعرّفة إذا كانت أي من وسائطها غير مُعرّفة، ولذلك يُطلق على التقييم بالترتيب التطبيقي عادةً اسم التقييم الصارم . علاوة على ذلك، يتم استدعاء الدالة فور مصادفتها في الإجراء، ولذلك يُطلق عليه أيضًا التقييم المُستعجل أو التقييم الجشع . [ 26 ] [ 27 ] يشير بعض المؤلفين إلى التقييم الصارم باسم "الاستدعاء بالقيمة" نظرًا لأن استراتيجية الربط بالقيمة تتطلب تقييمًا صارمًا. [ 4 ]

تُقيّم لغات Common Lisp و Eiffel وJava وسائط الدوال من اليسار إلى اليمين. أما لغة C، فلا تُحدد ترتيب الوسائط. [ 28 ] تتطلب لغة Scheme أن يكون ترتيب التنفيذ هو التنفيذ التسلسلي لتبديل غير مُحدد للوسائط. [ 29 ] وبالمثل، لا تُحدد لغة OCaml ترتيب الوسائط، ولكنها عمليًا تُقيّمها من اليمين إلى اليسار نظرًا لتصميم آلتها المجردة . [ 30 ] جميع هذه اللغات تُقيّم الوسائط تقييمًا صارمًا.

تقييم غير صارم

ترتيب التقييم غير الصارم هو ترتيب تقييم غير صارم، أي أن الدالة قد تُرجع نتيجة قبل تقييم جميع وسائطها بالكامل. [ 31 ] : 46-47. المثال النموذجي هو التقييم بالترتيب العادي ، الذي لا يُقيّم أيًا من الوسائط إلا عند الحاجة إليها في جسم الدالة. [ 32 ] يتميز التقييم بالترتيب العادي بأنه ينتهي دون خطأ في أي وقت كان أي ترتيب تقييم آخر سينتهي فيه دون خطأ. [ 33 ] اسم "الترتيب العادي" مُشتق من حساب لامدا، حيث يجد اختزال الترتيب العادي شكلًا عاديًا إن وُجد (إنها استراتيجية اختزال "تطبيعية" ). [ 34 ] يُصنف التقييم الكسول في هذه المقالة كتقنية ربط وليس كترتيب تقييم. لكن هذا التمييز لا يُتبع دائمًا، إذ يُعرّف بعض المؤلفين التقييم الكسول على أنه تقييم بالترتيب العادي أو العكس، [ 25 ] [ 35 ] أو يخلطون بين عدم الصرامة والتقييم الكسول. [ 31 ] : 43-44

تستخدم التعبيرات المنطقية في العديد من اللغات شكلاً من أشكال التقييم غير الصارم يُسمى التقييم المختصر ، حيث يُقيّم التعبير الأيسر، ولكن قد يُتجاهل التعبير الأيمن إذا أمكن تحديد النتيجة - على سبيل المثال، في التعبير الانفصالي (أو) حيث trueيُصادف الشرط، أو في التعبير العطفي (و) حيث falseيُصادف الشرط، وهكذا. [ 35 ] وبالمثل، تستخدم التعبيرات الشرطية التقييم غير الصارم - حيث يُقيّم فرع واحد فقط. [ 31 ]

مقارنة بين التقييم التطبيقي والتقييم العادي

في التقييم بالترتيب العادي، تُتجاهل التعبيرات التي تحتوي على عمليات حسابية مكلفة، أو أخطاء، أو حلقات لا نهائية، إن لم تكن ضرورية، [ 4 ] مما يسمح بتحديد بنيات تدفق التحكم المُعرَّفة من قِبل المستخدم، وهي ميزة غير متوفرة في التقييم بالترتيب التطبيقي. يستخدم التقييم بالترتيب العادي هياكل معقدة مثل الدوال غير المُقيَّمة للتعبيرات غير المُقيَّمة، مقارنةً بمكدس الاستدعاءات المستخدم في التقييم بالترتيب التطبيقي. [ 36 ] تاريخيًا، افتقر التقييم بالترتيب العادي إلى أدوات تصحيح أخطاء عملية نظرًا لتعقيده. [ 37 ]

استراتيجيات الربط الصارمة

الاتصال بالقيمة

في أسلوب الاستدعاء بالقيمة (أو التمرير بالقيمة)، تُربط القيمة المُقَيَّمة لتعبير الوسيط بالمتغير المُناسب في الدالة (غالبًا عن طريق نسخ القيمة إلى منطقة ذاكرة جديدة). إذا كانت الدالة أو الإجراء قادرًا على إسناد قيم إلى مُعاملاته، فسيتم إسنادها إلى متغيره المحلي فقط ، أي أن أي شيء يُمرَّر إلى استدعاء الدالة يبقى دون تغيير في نطاق المُستدعي عند انتهاء الدالة. على سبيل المثال، في لغة باسكال ، سيؤدي تمرير مصفوفة بالقيمة إلى نسخ المصفوفة بأكملها، ولن يكون أي تغيير يطرأ على هذه المصفوفة مرئيًا للمُستدعي: [ 38 ]

البرنامج الرئيسي ؛ يستخدم crt ؛إجراء PrintArray ( a : مصفوفة من الأعداد الصحيحة ) ; متغير i : عدد صحيح ; بداية حلقة تكرارية من أجل i := Low ( a ) إلى High ( a ) do Write ( a [ i ]) ; WriteLn () ; نهاية الحلقة ;الإجراء Modify ( الصف : مصفوفة من الأعداد الصحيحة ) ؛ ابدأ PrintArray ( الصف ) ؛ // 123 الصف [ 1 ] := 4 ؛ PrintArray ( الصف ) ؛ // 143 نهاية ؛Var A : Array of integer ; begin A := [ 1 , 2 , 3 ] ; PrintArray ( A ) ; // 123 Modify ( A ) ; PrintArray ( A ) ; // 123 end .

الانحراف الدلالي

بالمعنى الدقيق، في حالة "الاستدعاء بالقيمة"، لا يمكن للمستدعي رؤية أي عمليات تُنفذها الدالة المُستدعاة، إلا كجزء من القيمة المُعادة. [ 19 ] وهذا يُشير إلى شكل من أشكال البرمجة الوظيفية البحتة في دلالات التنفيذ. مع ذلك، أصبح التعبير المُلتف "الاستدعاء بالقيمة حيث تكون القيمة مرجعًا" شائعًا في بعض اللغات، مثل لغة جافا. [ 39 ] بالمقارنة مع "التمرير بالقيمة" التقليدي، فإن القيمة المُمررة ليست قيمة بالمعنى المتعارف عليه للقيمة، مثل عدد صحيح يُمكن كتابته كقيمة حرفية، بل هي مُعرّف مرجعي داخلي خاص بالتنفيذ . وتكون التغييرات التي تطرأ على هذا المُعرّف المرجعي مرئية للمستدعي. وبسبب هذه التغييرات المرئية، يُشار إلى هذا الشكل من "الاستدعاء بالقيمة" بشكل أدق باسم " الاستدعاء بالمشاركة " . [ 19 ]

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

الاتصال عن طريق المرجع

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

بسبب اختلاف قواعد اللغة، غالبًا ما يكون الفرق بين الاستدعاء بالمرجع (حيث يكون نوع المرجع ضمنيًا) والاستدعاء بالمشاركة (حيث يكون نوع المرجع صريحًا) غير واضح للوهلة الأولى. ويمكن التحقق من ذلك ببساطة عن طريق التحقق من إمكانية كتابة swap(a, b)دالة تقليدية في اللغة. [ 39 ] على سبيل المثال في لغة فورتران:

البرنامج الرئيسي ضمني لا شيء عدد صحيح :: a = 1 عدد صحيح :: b = 2 استدعاء تبديل ( a , b ) طباعة * , a , b ! 2 1 يحتوي  روتين فرعي تبديل ( a , b ) عدد صحيح ، نية ( inout ) :: a , b عدد صحيح :: مؤقت مؤقت = a a = b b = مؤقت نهاية الروتين الفرعي تبديل نهاية البرنامج الرئيسي

لذا، فإنّ نية لغة فورتران inoutتُطبّق مبدأ الاستدعاء بالمرجع؛ إذ يُمكن تحويل أي متغير ضمنيًا إلى مُعرّف مرجعي. في المقابل، أقرب ما يُمكن الوصول إليه في جافا هو:

public class Main { static class Box { int value ; public Box ( int value ) { this . value = value ; } }static void swap ( Box a , Box b ) { int temp = a . value ; a . value = b . value ; b . value = temp ; }public static void main ( String [] args ) { Box a = new Box ( 1 ); Box b = new Box ( 2 ); swap ( a , b ); System . out . printf ( "a = %d, b = %d%n" , a . value , b . value ); // الناتج: a = 2, b = 1 } }

حيث يجب استخدام نوع صريح Boxلإنشاء مؤشر. لغة جافا تعتمد على المشاركة في الاستدعاءات، ولكنها لا تعتمد على الاستدعاء بالمرجع. [ 39 ]

اتصل عن طريق النسخ والاستعادة

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

تتشابه دلالات الاستدعاء بالنسخ والاستعادة في كثير من الحالات مع الاستدعاء بالمرجع، لكنها تختلف عندما يشير وسيطان أو أكثر من وسائط الدالة إلى نفس المتغير في بيئة المُستدعي. في حالة الاستدعاء بالمرجع، تؤثر الكتابة إلى أحد الوسيطين على الآخر أثناء تنفيذ الدالة. أما في حالة الاستدعاء بالنسخ والاستعادة، فلا تؤثر الكتابة إلى أحد الوسيطين على الآخر أثناء تنفيذ الدالة، ولكن في نهاية الاستدعاء، قد تختلف قيم الوسيطين، ويكون من غير الواضح أي وسيط يُنسخ أولاً، وبالتالي ما هي القيمة التي يتلقاها متغير المُستدعي. [ 41 ] على سبيل المثال، تُحدد لغة آدا أن عملية النسخ لكل in outمُعامل outتتم بترتيب عشوائي. [ 42 ] من البرنامج التالي (غير مسموح به في آدا 2012) [ 43 ] ، يتضح أن سلوك GNAT هو النسخ من اليسار إلى اليمين عند العودة:

باستخدام Ada.Text_IO ؛ استخدم Ada.Text_IO ؛الإجراء Test_Copy_Restore هو الإجراء Modify ( A , B : in out Integer ) هو: ابدأ A := A + 1 ; B := B + 2 ; نهاية Modify ; X : Integer := 0 ; ابدأ Modify ( X , X ); Put_Line ( "X = " & Integer ' Image ( X )); نهاية Test_Copy_Restore ; -- $ gnatmake -gnatd.E test_copy_restore.adb; ./test_copy_restore -- test_copy_restore.adb:12:10: تحذير: القيمة الفعلية القابلة للكتابة لـ "A" تتداخل مع القيمة الفعلية لـ "B" [-gnatw.i] -- X = 2

إذا أعاد البرنامج القيمة 1 فسيكون ذلك بمثابة نسخ من اليمين إلى اليسار، وبموجب دلالات الاستدعاء بالمرجع، سيعيد البرنامج القيمة 3.

عندما يتم تمرير المرجع إلى المتصل دون تهيئته (على سبيل المثال، outمعلمة في لغة Ada بدلاً من in outمعلمة)، يمكن تسمية استراتيجية التقييم هذه بـ "الاستدعاء عن طريق النتيجة".

وقد حظيت هذه الاستراتيجية باهتمام في المعالجة المتعددة واستدعاءات الإجراءات عن بعد ، [ 44 ] على عكس الاستدعاء بالمرجع، فهي لا تتطلب اتصالاً متكرراً بين سلاسل التنفيذ للوصول إلى المتغيرات.

اتصل عبر المشاركة

الاستدعاء بالمشاركة (المعروف أيضًا باسم "التمرير بالمشاركة" أو "الاستدعاء بالكائن" أو "الاستدعاء بمشاركة الكائن") هو استراتيجية تقييم وسيطة بين الاستدعاء بالقيمة والاستدعاء بالمرجع. فبدلاً من أن يكون كل متغير مُعرَّضًا كمرجع، فإن فئة محددة من القيم، تُسمى "المراجع" أو " الأنواع المُغلَّفة " أو "الكائنات"، هي التي تحمل دلالات مرجعية، وعناوين هذه المؤشرات هي التي تُمرَّر إلى الدالة. وكما هو الحال في الاستدعاء بالقيمة، فإن قيمة العنوان المُمرَّر هي نسخة، والتعيين المباشر لمعامل الدالة يستبدل النسخة ولا يكون مرئيًا للدالة المُستدعِية. وكما هو الحال في الاستدعاء بالمرجع، فإن تغيير هدف المؤشر يكون مرئيًا للدالة المُستدعِية. وتكون تغييرات الكائن القابل للتغيير داخل الدالة مرئية للمُستدعي لأن الكائن لا يُنسخ أو يُستنسخ - بل يُشارك ، ومن هنا جاء اسم "الاستدعاء بالمشاركة". [ 19 ]

لاحظت باربرا ليسكوف هذه التقنية لأول مرة عام 1974 في لغة CLU . [ 19 ] وتُستخدم هذه التقنية في العديد من اللغات الحديثة مثل بايثون (حيث تُسمى القيم المشتركة "كائنات")، [ 45 ] وجافا (كائنات)، وروبي (كائنات)، وجافا سكريبت (كائنات)، وسكيم (هياكل البيانات مثل المتجهات)، [ 46 ] وأبل سكريبت (القوائم، والسجلات، والتواريخ، وكائنات البرمجة النصية)، وOCaml و ML (المراجع، والسجلات، والمصفوفات، والكائنات، وأنواع البيانات المركبة الأخرى)، ومابل (الجداول والجداول)، و Tcl (كائنات). [ 47 ] مصطلح "الاستدعاء بالمشاركة" كما هو مستخدم في هذه المقالة ليس شائع الاستخدام؛ إذ يختلف المصطلح بين المصادر المختلفة. على سبيل المثال، في مجتمع جافا، يُقال إن جافا تعتمد على الاستدعاء بالقيمة. [ 39 ]

بالنسبة للكائنات غير القابلة للتغيير ، لا يوجد فرق حقيقي بين الاستدعاء بالمشاركة والاستدعاء بالقيمة، إلا إذا كانت هوية الكائن مرئية في اللغة. يُعد استخدام الاستدعاء بالمشاركة مع الكائنات القابلة للتغيير بديلاً عن معلمات الإدخال/الإخراج : لا يتم تعيين قيمة للمعلمة (لا يتم استبدال الوسيطة ولا تتغير هوية الكائن)، ولكن يتم تغيير الكائن (الوسيطة). [ 48 ]

على سبيل المثال، في لغة بايثون، تكون القوائم قابلة للتغيير ويتم تمريرها باستخدام الاستدعاء عن طريق المشاركة، لذا:

def f ( l : list [ int ]) -> None : l . append ( 1 )m : list [ int ] = [] f ( m ) print ( m )

تُخرج [1]هذه الطريقة مخرجات لأنها appendتُعدّل الكائن الذي يتم استدعاؤها عليه.

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

def f ( l : list [ int ]) -> None : l = l + [ 1 ] print ( l ) # [1]m : list [ int ] = [] f ( m ) print ( m ) # []

الاتصال عن طريق العنوان

الاستدعاء بالعنوان ، أو التمرير بالعنوان، أو الاستدعاء/التمرير بالمؤشر، هي طريقة لتمرير المعاملات حيث يُمرر عنوان الوسيط كمعامل رسمي. داخل الدالة، يمكن استخدام العنوان (المؤشر) للوصول إلى قيمة الوسيط أو تعديلها. على سبيل المثال، يمكن تنفيذ عملية التبديل كما يلي في لغة C: [ 49 ]

#include <stdio.h>void swap ( int * a , int * b ) { int temp = * a ; * a = * b ; * b = temp ; }int main () { int a = 1 ; int b = 2 ; swap ( &a a , & b ); printf ( "%d %d \n " , a , b ); // 2 1 return 0 ; }

يعتبر بعض المؤلفين استخدام &`async` جزءًا من بنية استدعاء الدالة swap. وبناءً على هذا الرأي، تدعم لغة C استراتيجية تمرير المعاملات بالمرجع. [ 50 ] بينما يتبنى مؤلفون آخرون وجهة نظر مختلفة، مفادها أن التنفيذ المقدم لـ `async` swapفي لغة C ليس سوى محاكاة لاستدعاء المعاملات بالمرجع باستخدام المؤشرات. [ 51 ] ووفقًا لوجهة نظر "المحاكاة" هذه، فإن المتغيرات القابلة للتغيير في لغة C ليست من الدرجة الأولى (أي أن قيم l ليست تعبيرات)، بل أنواع المؤشرات هي كذلك. وبناءً على هذه الوجهة، فإن برنامج التبديل المقدم هو اختصار برمجي لبرنامج يستخدم المؤشرات بشكل كامل، [ 52 ] على سبيل المثال هذا البرنامج ( readوقد assignتمت إضافتهما لتسليط الضوء على أوجه التشابه مع Boxبرنامج Java لاستدعاء المعاملات بالمشاركة المذكور أعلاه ):

#include <stdio.h>int read ( int * p ) { return * p ; }void assign ( int * p , int v ) { * p = v ; }void swap ( int * a , int * b ) { int temp_storage ; int * temp = & temp_storage ; assign ( temp , read ( a )); assign ( a , read ( b )); assign ( b , read ( temp )); }int main () { int a_storage ; int * a = & a_storage ; int b_storage ; int * b = & b_storage ; assign ( a , 1 ); assign ( b , 2 ); swap ( a , b ); printf ( "%d %d \n " , read ( a ), read ( b )); // 2 1 return 0 ; }

لأن في هذا البرنامج، swapيتم التعامل مع المؤشرات ولا يمكن تغيير المؤشرات نفسها، ولكن فقط القيم التي تشير إليها المؤشرات، فإن هذا الرأي يرى أن استراتيجية التقييم الرئيسية للغة C تشبه إلى حد كبير أسلوب الاستدعاء بالمشاركة.

يزيد C++ الأمر تعقيدًا من خلال السماح swapبالإعلان عنه واستخدامه باستخدام صيغة "مرجع" خفيفة للغاية: [ 53 ]

void swap ( int & a , int & b ) { int temp = a ; a = b ; b = temp ; }int main () { int a = 1 ; int b = 2 ; swap ( a , b ); std :: println ( "{} {}" , a , b ); // 2 1 return 0 ; }

من الناحية الدلالية، هذا يعادل أمثلة لغة C. ولذلك، يعتبر العديد من المؤلفين أن استدعاء المعاملات بالعنوان استراتيجية فريدة لتمرير المعاملات تختلف عن استدعاء المعاملات بالقيمة، واستدعاء المعاملات بالمرجع، واستدعاء المعاملات بالمشاركة.

دعوة من خلال التوحيد

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

استراتيجيات الربط غير الصارمة

الاتصال بالاسم

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

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

تستطيع لغات .NET محاكاة الاستدعاء بالاسم باستخدام المندوبين أو Expression<T>المعاملات. ينتج عن استخدام المعاملات شجرة بناء جملة مجردة تُعطى للدالة. توفر لغة إيفل وكلاءً يمثلون عمليةً يتم تقييمها عند الحاجة. يمكن لبرامج جافا تحقيق تقييم مماثل عند الحاجة باستخدام تعابير لامدا والواجهة java.util.function.Supplier<T>.

اتصل عند الحاجة

الاستدعاء عند الحاجة هو شكل مُخزَّن مؤقتًا من الاستدعاء بالاسم، حيث يتم تخزين قيمة وسيط الدالة، في حال تقييمه، لاستخدامها لاحقًا. إذا كان الوسيط نقيًا (أي خاليًا من الآثار الجانبية)، فإن هذا يُنتج نفس نتائج الاستدعاء بالاسم، مما يوفر تكلفة إعادة حساب الوسيط.

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

في تطبيق R لخاصية الاستدعاء حسب الحاجة، يتم تمرير جميع الوسائط، مما يعني أن R يسمح بآثار جانبية عشوائية.

يُعدّ التقييم الكسول التطبيق الأكثر شيوعًا لدلالات الاستدعاء عند الحاجة، ولكن توجد اختلافات أخرى مثل التقييم التفاؤلي . تُطبّق لغات .NET الاستدعاء عند الحاجة باستخدام النوع Lazy<T>.

يُعد اختزال الرسم البياني تطبيقًا فعالًا للتقييم الكسول.

استدعاء بواسطة توسيع الماكرو

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

اتصل بالمستقبل

"الاستدعاء المستقبلي"، المعروف أيضًا باسم "الاستدعاء المتوازي بالاسم" أو "التقييم المتساهل"، [ 54 ] هو استراتيجية تقييم متزامنة تجمع بين الدلالات غير الصارمة والتقييم الفوري. تتطلب هذه الطريقة جدولة ديناميكية دقيقة وتزامنًا، لكنها مناسبة للأجهزة ذات المعالجة المتوازية الضخمة.

تُنشئ هذه الاستراتيجية وعدًا (وعدًا) لجسم الدالة ولكل وسيط من وسائطها. تُحسب هذه الوعدات بالتزامن مع سير بقية البرنامج. عندما يتطلب وعد (أ) قيمة وعد آخر (ب) لم يُحسب بعد، يتوقف الوعد (أ) مؤقتًا حتى ينتهي الوعد (ب) من الحساب ويُصبح له قيمة. إذا كان الوعد (ب) قد انتهى من الحساب بالفعل، تُعاد القيمة فورًا. تتوقف العبارات الشرطية مؤقتًا حتى يتم تقييم شرطها، ولا تُنشئ دوال لامدا وعدات إلا بعد تطبيقها بالكامل. [ 55 ]

إذا تم تنفيذ ذلك باستخدام العمليات أو الخيوط، فإن إنشاء كائن مستقبلي سيؤدي إلى إنشاء عملية أو أكثر جديدة أو خيط واحد أو أكثر (للوعود)، وسيؤدي الوصول إلى القيمة إلى مزامنة هذه العمليات مع الخيط الرئيسي، ويؤدي إنهاء حساب الكائن المستقبلي إلى إنهاء الوعود التي تحسب قيمته. أما إذا تم تنفيذه باستخدام روتين فرعي ، كما هو الحال في async/await في .NET ، فإن إنشاء كائن مستقبلي يستدعي روتينًا فرعيًا (دالة غير متزامنة)، والذي قد يُفسح المجال للمستدعي، ثم يُفسح المجال له مرة أخرى عند استخدام القيمة، مما يُحقق تعدد مهام تعاوني.

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

f x = 1 / x g y = 1 main = print ( g ( f 0 ))

قد gينتهي الأمر قبل ذلك f، ويخرج 1، أو قد ينتج عنه خطأ بسبب التقييم 1/0. [ 31 ]

يُشبه أسلوب "الاستدعاء حسب المستقبل" أسلوب "الاستدعاء حسب الحاجة" في أن القيم تُحسب مرة واحدة فقط. ومع المعالجة الدقيقة للأخطاء وعدم الإنهاء، ولا سيما إنهاء العمليات المستقبلية في منتصفها إذا تبيّن عدم الحاجة إليها، يتمتع أسلوب "الاستدعاء حسب المستقبل" بنفس خصائص الإنهاء التي يتمتع بها أسلوب "الاستدعاء حسب الحاجة". [ 55 ] مع ذلك، قد يُجري أسلوب "الاستدعاء حسب المستقبل" عمليات تخمينية غير ضرورية مقارنةً بأسلوب "الاستدعاء حسب الحاجة"، مثل التقييم العميق لبنية بيانات كسولة. [ 31 ] ويمكن تجنب ذلك باستخدام عمليات مستقبلية كسولة لا تبدأ الحساب إلا بعد التأكد من الحاجة إلى القيمة.

التقييم المتفائل

التقييم التفاؤلي هو أحد أشكال التقييم حسب الحاجة، حيث يتم تقييم وسيط الدالة جزئيًا بأسلوب التقييم حسب القيمة لفترة زمنية محددة (يمكن تعديلها أثناء التشغيل ). بعد انقضاء هذه الفترة، يتوقف التقييم وتُطبَّق الدالة باستخدام التقييم حسب الحاجة. [ 56 ] يتجنب هذا الأسلوب بعض تكاليف وقت التشغيل المرتبطة بالتقييم حسب الحاجة، مع الحفاظ على خصائص الإنهاء المطلوبة.

انظر أيضاً

مراجع

  1. أراكي، شوتا؛ نيشيزاكي، شين-يا (نوفمبر 2014). "تقييم حسابات RPC وRMI بالاسم". نظرية وممارسة الحوسبة . ص  1. doi : 10.1142/9789814612883_0001 . ISBN 978-981-4612-87-6تم الاطلاع عليه بتاريخ 21 أغسطس 2021 .
  2. تورباك، فرانكلين؛ جيفورد، ديفيد (18 يوليو 2008). مفاهيم التصميم في لغات البرمجة . مطبعة معهد ماساتشوستس للتكنولوجيا. ص 309. ISBN  978-0-262-30315-6.
  3. كرانك، إريك؛ فيليسين، ماتياس (1991). "تمرير المعاملات وحساب لامدا". وقائع الندوة الثامنة عشرة لجمعية ACM SIGPLAN-SIGACT حول مبادئ لغات البرمجة - POPL '91 . ص 2. CiteSeerX 10.1.1.23.4385 . doi : 10.1145/99583.99616 . ISBN   0897914198. S2CID 5782416 . 
  4. 1 2 3 فيلهلم، راينهارد؛ سيدل ، هيلموت (10 نوفمبر 2010). تصميم المترجم: الأجهزة الافتراضية . سبرينغر العلوم والإعلام التجاري. ص. 61. ردمك  978-3-642-14909-2.
  5. ^ نيتا، ستيفانيا لوريدانا؛ ميهايليسكو، ماريوس (2017). "مقدمة" . العملي المتزامن هاسكل . ص. 3. دوى : 10.1007/978-1-4842-2781-7_1 . رقم ISBN  978-1-4842-2780-0.
  6. بيرس، بنجامين سي. (2002). أنواع ولغات البرمجة . مطبعة معهد ماساتشوستس للتكنولوجيا . ص 56. ISBN  0-262-16209-1.
  7. "تقييم (فعل)، المعنى أ". قاموس أكسفورد الإنجليزي . 2023. doi : 10.1093/OED/3423541985 . الرياضيات. حساب "قيمة" (تعبير كمي)؛ إيجاد تعبير عددي لـ (أي حقيقة أو علاقة كمية).
  8. "تبسيط (فعل)، المعنى 4.أ". قاموس أكسفورد الإنجليزي . 2023. doi : 10.1093/OED/1018661347 . التعبير عن (معادلة أو تعبير رياضي آخر) بشكل يسهل فهمه أو تحليله أو التعامل معه، على سبيل المثال عن طريق تجميع الحدود المتشابهة أو استبدال المتغيرات.
  9. دانيال ب. فريدمان؛ ميتشل واند (2008). أساسيات لغات البرمجة ( الطبعة الثالثة). كامبريدج، ماساتشوستس: مطبعة معهد ماساتشوستس للتكنولوجيا . ISBN  978-0262062794.
  10. 1 2 سكوت، مايكل لي (2016). براغماتية لغات البرمجة ( الطبعة الرابعة). والتهام، ماساتشوستس: إلسيفير. ISBN  9780124104778.
  11. كيرنيغان، برايان دبليو؛ ريتشي، دينيس إم. (1988). لغة البرمجة سي ( الطبعة الثانية). إنجلوود كليفس، نيوجيرسي: برنتيس هول. ص 28. ISBN   978-0131103627.
  12. "تجنب النسخ غير الضرورية للبيانات - MATLAB وSimulink" . www.mathworks.com . تاريخ الاسترجاع: 28 يناير 2023 .
  13. هاستي، ريبيكا. "تمرير المعاملات" . CS 536: مقدمة في لغات البرمجة والمترجمات . جامعة ويسكونسن . تم الاطلاع عليه بتاريخ 22 أغسطس 2021 .
  14. جيه إيه روبنسون (يناير 1965). "منطق موجه نحو الآلة قائم على مبدأ الاستدلال" . مجلة ACM . 12 (1): 23-41 . doi : 10.1145/321250.321253 . S2CID 14389185 . هنا: القسم 5.8، صفحة 32
  15. جيه إيه روبنسون (1971). "المنطق الحسابي: الحساب الموحد" . الذكاء الآلي . 6 : 63-72 .
  16. بوندي، آلان؛ والين، لينكولن (1984). "SASL". كتالوج أدوات الذكاء الاصطناعي . ص 117. doi : 10.1007/978-3-642-96868-6_222 . ISBN  978-3-540-13938-6ربما كانت أول لغة تستغل بشكل منهجي قوة التقييم الكسول.
  17. فاي، كولين (30 يوليو 2018). "حول التقييم الكسول" . مدونة آر . تم الاطلاع عليه بتاريخ 21 أغسطس 2021 .
  18. وادزورث، كريستوفر ب. (1971). دلالات وبراغماتية حساب لامدا (دكتوراه). جامعة أكسفورد.
  19. 1 2 3 4 5 ليسكوف، باربرا؛ أتكينسون، روس؛ بلوم، توبي؛ موس، إليوت؛ شافرت، كريغ؛ شيفلر، كريغ؛ سنايدر، آلان (أكتوبر 1979). "دليل مرجعي لـ CLU" (ملف PDF) . مختبر علوم الحاسوب . معهد ماساتشوستس للتكنولوجيا. الصفحات 14-15 . مؤرشف (ملف PDF) من الأصل بتاريخ 22-09-2006 . تم الاطلاع عليه بتاريخ 19-05-2011 . 
  20. "PHP: المرور بالمرجع - دليل المستخدم" . www.php.net . تم الاطلاع عليه بتاريخ 4 يوليو 2021 .
  21. فاغنر، بيل (12 أبريل 2023). "تمرير المعاملات - دليل برمجة C#" . وثائق مايكروسوفت . تم الاسترجاع في 10 سبتمبر 2023 .
  22. دولارد، كاثلين (15 سبتمبر 2021). "تمرير الوسائط بالقيمة وبالمرجع - فيجوال بيسك" . وثائق مايكروسوفت . تم الاسترجاع في 10 سبتمبر 2023 .
  23. 1 2 "تاريخ لغة C++" . en.cppreference.com . تم الاطلاع عليه بتاريخ 11 يونيو 2022 .
  24. فيليبك، بارتلومي (16 أغسطس 2021). "ترتيب تقييم التعبيرات الأكثر صرامة في C++17" . قصص C++ . تم الاسترجاع في 24 أغسطس 2021 .
  25. 1 2 أبيلسون، هارولد ؛ سوسمان، جيرالد جاي (1996). "الترتيب العادي والترتيب التطبيقي" . بنية وتفسير برامج الحاسوب ( الطبعة الثانية). كامبريدج، ماساتشوستس: مطبعة معهد ماساتشوستس للتكنولوجيا . ISBN  0-262-01153-0أُرشف من المصدر الأصلي بتاريخ 2005-03-02 . تم الاطلاع عليه بتاريخ 2006-03-06 .انظر أيضًا الحاشية رقم 576.
  26. ريس، ريتشارد م. (14 أكتوبر 2015). تعلم البرمجة الوظيفية بلغة جافا . دار نشر باكت المحدودة. ص 106. ISBN  978-1-78528-935-4.
  27. أنتاني، فيد؛ تيمز، سيمون؛ مانتيلا، دان (31 أغسطس 2016). جافا سكريبت: البرمجة الوظيفية لمطوري جافا سكريبت . دار نشر باكت المحدودة. ص 614. ISBN  978-1-78712-557-5.
  28. سيكورد، روبرت سي. "EXP30-C. لا تعتمد على ترتيب التقييم للآثار الجانبية" . معيار ترميز SEI CERT C. جامعة كارنيجي ميلون . تم الاطلاع عليه بتاريخ 23 أغسطس 2021 .
  29. أنغلاد، س.؛ لاكرامب، ج. ج.؛ كوينيك، س. (أكتوبر 1994). "دلالات التركيبات في لغة سكيم" (ملف PDF) . ACM SIGPLAN Lisp Pointers . المجلد السابع (4): 15-20 . doi : 10.1145/382109.382669 . S2CID 2987427 . 
  30. "لماذا يتم تقييم وسائط الدوال في لغة OCaml من اليمين إلى اليسار؟" . OCaml . 30 نوفمبر 2017.
  31. 1 2 3 4 5 تريمبلاي، ج. (أبريل 2000). "التقييم المتساهل ليس صارمًا ولا كسولًا". لغات الحاسوب . 26 (1): 43-66 . CiteSeerX 10.1.1.137.9885 . doi : 10.1016/S0096-0551(01)00006-6 . 
  32. جورج، لاي (مارس 1987). التقييم الفعال للترتيب الطبيعي من خلال معلومات الصرامة (رسالة ماجستير). جامعة يوتا. ص 10. 
  33. بورنينغ، آلان (خريف 1999). "التقييم التطبيقي مقابل التقييم العادي في اللغات الوظيفية" (ملف PDF) . CSE 505: مفاهيم لغات البرمجة . جامعة واشنطن . تاريخ الاسترجاع: 23 أغسطس 2021 .
  34. مازولا، جويرينو؛ ميلمايستر، جيرار؛ فايسمان، جودي (21 أكتوبر 2004). الرياضيات الشاملة لعلماء الحاسوب 2. سبرينغر ساينس آند بيزنس ميديا. ص 323. ISBN  978-3-540-20861-7.
  35. 1 2 ستورم، أوليفر (11 أبريل 2011). البرمجة الوظيفية في لغة سي شارب: تقنيات البرمجة الكلاسيكية للمشاريع الحديثة . جون وايلي وأولاده. ص 91. ISBN  978-0-470-74458-1.
  36. مارلو، سيمون. "لماذا لا يمكنني الحصول على تتبع المكدس؟" . ورشة عمل مطوري هاسكل 2012. تم الاطلاع عليه بتاريخ 25 أغسطس 2021 .
  37. نيلسون، هنريك (1999). "التتبع خطوة بخطوة: تصحيح الأخطاء بأسعار معقولة للغات البرمجة الوظيفية الكسولة". وقائع المؤتمر الدولي الرابع لجمعية ACM SIGPLAN حول البرمجة الوظيفية . الصفحات 36-47 . CiteSeerX 10.1.1.451.6513 . doi : 10.1145/317636.317782 . ISBN   1581131119. S2CID 13954359 . 
  38. "معاملات المصفوفة المفتوحة" . www.freepascal.org . تم الاطلاع عليه بتاريخ 20 يناير 2024 .
  39. 1 2 3 4 "جافا تعتمد على تمرير القيمة، اللعنة!" . 16 مايو 2001. تم الاطلاع عليه بتاريخ 24 ديسمبر 2016 .
  40. ^ كوينين، فرانس. "تمرير المعلمة" . cgi.csc.liv.ac.uk . تم الاسترجاع 22 يناير 2024 .
  41. "الاستدعاء بالمرجع، مشاكل التسمية البديلة" (ملف PDF) . دورة MPRI 2-36-1: إثبات البرنامج (ملاحظات المحاضرة) . صفحة 53. مؤرشف من الأصل (ملف PDF) بتاريخ 25 يونيو 2024. 
  42. دليل مرجعي للغة آدا 2022 (ملف PDF) . 13 أكتوبر 2023. ص 215. 
  43. بارنز، جون (2013). منطق لغة آدا 2012: اللغة، المكتبات القياسية (ملف PDF) . هايدلبرغ: سبرينغر. الصفحات 15-16 ، 87-88 . ISBN  978-3-642-45210-9.
  44. ثورلو، روبرت (مايو 2009). "RPC: مواصفات بروتوكول استدعاء الإجراءات عن بُعد، الإصدار 2" . tools.ietf.org . IETF . تم الاطلاع عليه في 7 أبريل 2018 .
  45. لوند، فريدريك. "استدعاء بواسطة كائن" . Effbot.org . مؤرشف من الأصل بتاريخ 19-05-2011 . تم الاسترجاع بتاريخ 19-05-2011 .
  46. جونز، ريس برايس (2010). "هل لغة Scheme تعتمد على تمرير القيم؟" . مختبر لغات البرمجة CS 145، المختبر 9: تمرير المعاملات . جامعة جورج واشنطن. مؤرشف من الأصل في 16 أكتوبر 2014. تم الاطلاع عليه في 20 يناير 2024 .
  47. " إجراءات مكتبة Tcl - صفحة دليل Tcl_Obj" . www.tcl.tk.
  48. "CA1021: تجنب استخدام المعاملات الخارجية" . مايكروسوفت. 15 نوفمبر 2016.
  49. ليو، راي (نوفمبر 1996). لغة سي++ البسيطة (بأسلوب سهل) . شركة ليو سودو. الصفحات 79-80 . رقم ISBN  978-0-9654634-1-6.
  50. داندامودي، سيفاراما ب. (15 يوليو 2005). دليل برمجة لغة التجميع في لينكس . سبرينغر ساينس آند بيزنس ميديا. ص 232. ISBN  978-0-387-25897-3.
  51. سريفاستافا، إس كيه؛ سريفاستافا، ديبالي (6 يونيو 2018). ج في العمق . منشورات بي بي بي. ص 206. ISBN  978-93-87284-94-4.
  52. "المتغيرات القابلة للتغيير وأنواع المراجع" . okmij.org . تم الاطلاع عليه بتاريخ 20 يناير 2024 .
  53. فيرمير، ديرك (28 يونيو 2011). البرمجة متعددة الأنماط باستخدام لغة C++ . سبرينغر ساينس آند بيزنس ميديا. الصفحات 10-11 . ISBN  978-1-4471-0311-0.
  54. ماكولين، توماس غوينفرين؛ موريل، توبياس. "لعبة النماذج: دراسة قابلية استخدام المصطلحات الوظيفية في برمجة أسلوب اللعب" (ملف PDF) . جامعة آلبورغ. ص 6. تاريخ الاطلاع: 11 يناير 2022 . 
  55. 1 2 شاوزر، كلاوس إي؛ غولدشتاين، سيث سي. (1995). "ما مدى المرونة التي تتطلبها البرامج المتساهلة؟" (ملف PDF) . وقائع المؤتمر الدولي السابع حول لغات البرمجة الوظيفية وهندسة الحاسوب - FPCA '95 . الصفحات 216-225 . doi : 10.1145/224164.224208 . ISBN  0897917197S2CID 2045943. تم الاطلاع عليه بتاريخ 7 يناير 2022 . 
  56. إينالز، روبرت؛ بيتون جونز، سيمون (أغسطس 2003). التقييم التفاؤلي: استراتيجية تقييم سريعة للبرامج غير الصارمة . المؤتمر الدولي للبرمجة الوظيفية. مطبعة ACM. مؤرشف من الأصل في 22 أغسطس 2025.

للمزيد من القراءة

  • أداة عرض هندسة التفاعل التفاعلية عبر الإنترنت ، والتي تطبق آلة قائمة على الرسم البياني للعديد من استراتيجيات التقييم الشائعة.