رفع لامدا
رفع لامدا هو عملية شاملة تُعيد هيكلة برنامج حاسوبي بحيث تُعرَّف الدوال بشكل مستقل عن بعضها البعض في نطاق عام. يحوّل الرفع الفردي دالة محلية (روتين فرعي) إلى دالة عامة. وهي عملية من خطوتين، تتكون من:
- إزالة المتغيرات الحرة في الدالة عن طريق إضافة المعاملات .
- نقل الوظائف من نطاق محدود إلى نطاق أوسع أو عالمي.
استُخدم مصطلح "رفع لامدا" لأول مرة من قِبل توماس جونسون حوالي عام 1982، وكان يُعتبر تاريخيًا آليةً لتنفيذ لغات البرمجة القائمة على البرمجة الوظيفية . ويُستخدم هذا المصطلح بالتزامن مع تقنيات أخرى في بعض المترجمات الحديثة .
رفع تعبير لامدا ليس هو نفسه تحويل الإغلاق . فهو يتطلب تعديل جميع مواقع الاستدعاء (بإضافة وسائط (معاملات) إضافية إلى الاستدعاءات) ولا يُنشئ إغلاقًا لتعبير لامدا المرفوع. في المقابل، لا يتطلب تحويل الإغلاق تعديل مواقع الاستدعاء، ولكنه يُنشئ إغلاقًا لتعبير لامدا يربط المتغيرات الحرة بالقيم.
يمكن استخدام هذه التقنية على الدوال الفردية، في إعادة هيكلة الشيفرة ، لجعل الدالة قابلة للاستخدام خارج نطاقها الأصلي. كما يمكن تكرار عمليات رفع لامدا لتحويل البرنامج. ويمكن استخدام عمليات الرفع المتكررة لتحويل برنامج مكتوب بلغة لامدا إلى مجموعة من الدوال التكرارية ، دون استخدام لامدا. وهذا يُظهر تكافؤ البرامج المكتوبة بلغة لامدا والبرامج المكتوبة كدوال. [ 1 ] ومع ذلك، لا يُظهر هذا سلامة استخدام لامدا للاستدلال، لأن اختزال إيتا المستخدم في رفع لامدا هو الخطوة التي تُدخل مشاكل في عدد عناصر لامدا، لأنه يُزيل القيمة من المتغير، دون التحقق أولاً من وجود قيمة واحدة فقط تُحقق شروط المتغير (انظر مفارقة كاري ).
يُعدّ رفع تعبيرات لامدا مكلفًا من حيث وقت المعالجة بالنسبة للمترجم. ويتمثل التنفيذ الفعال لرفع تعبيرات لامدا فيما يلي:[ 2 ] وقت المعالجة للمترجم.
في حساب لامدا غير المُنمّط ، حيث تكون الأنواع الأساسية دوالًا، قد يُغيّر رفعُ التعبير نتيجةَ اختزال بيتا لتعبير لامدا. ستكون للدوال الناتجة نفس المعنى، من الناحية الرياضية، لكنها لا تُعتبر نفس الدالة في حساب لامدا غير المُنمّط. انظر أيضًا: المساواة القصدية مقابل المساواة الامتدادية .
العملية العكسية لرفع لامدا هي خفض لامدا . [ 3 ]
قد يُسرّع حذف الدوال اللامدا عملية ترجمة البرامج للمترجم، وقد يزيد أيضًا من كفاءة البرنامج الناتج، وذلك بتقليل عدد المعاملات وحجم إطارات المكدس. مع ذلك، يُصعّب ذلك إعادة استخدام الدالة. فالدالة المحذوفة مرتبطة بسياقها، ولا يمكن استخدامها في سياق مختلف إلا بعد رفعها.
الخوارزمية
الخوارزمية التالية هي إحدى طرق رفع برنامج عشوائي باستخدام تعبير لامدا في لغة لا تدعم الإغلاقات ككائنات من الدرجة الأولى :
- أعد تسمية الدوال بحيث يكون لكل دالة اسم فريد.
- استبدل كل متغير حر بوسيطة إضافية للدالة المحيطة، وقم بتمرير تلك الوسيطة إلى كل استخدام للدالة.
- استبدل كل تعريف دالة محلية لا تحتوي على متغيرات حرة بدالة عامة مطابقة.
- كرر الخطوتين 2 و 3 حتى يتم التخلص من جميع المتغيرات الحرة والوظائف المحلية.
إذا كانت اللغة تحتوي على الإغلاقات ككائنات من الدرجة الأولى يمكن تمريرها كوسائط أو إرجاعها من وظائف أخرى، فسيتعين تمثيل الإغلاق بواسطة بنية بيانات تلتقط روابط المتغيرات الحرة.
مثال
يقوم برنامج OCaml التالي بحساب مجموع الأعداد الصحيحة من 1 إلى 100:
ليكن مجموع n = إذا كان n = 1 فإن 1 وإلا فليكن f x = n + x في f ( مجموع ( n - 1 ) ) المجموع 100( let recيُعرّف هذا sumكدالة يمكنها استدعاء نفسها). الدالة f، التي تجمع وسيط الدالة sum مع مجموع الأعداد الأقل من الوسيط، هي دالة محلية. ضمن تعريف f، n متغير حر. ابدأ بتحويل المتغير الحر إلى مُعامل:
ليكن مجموع n = إذا كان n = 1 فإن 1 وإلا فليكن f w x = w + x في f n ( مجموع ( n - 1 ) ) المجموع 100بعد ذلك، قم بتحويل f إلى دالة عامة:
ليكن rec f w x = w + x و sum n = إذا كان n = 1 فإن 1 وإلا f n ( sum ( n - 1 )) in sum 100فيما يلي نفس المثال، ولكن هذه المرة مكتوب بلغة جافا سكريبت :
// النسخة الأوليةدالة الجمع ( ن ) { دالة د ( س ) { إرجاع ن + س ؛ }إذا كان ( n == 1 ) فأرجع 1 ؛ وإلا فأرجع f ( sum ( n - 1 )); }// بعد تحويل المتغير الحر n إلى معامل رسمي wدالة الجمع ( ن ) { دالة f ( و ، س ) { إرجاع و + س ؛ }إذا كان ( n == 1 ) فأرجع 1 ؛ وإلا فأرجع f ( n , sum ( n - 1 )); }// بعد رفع الدالة f إلى النطاق العامدالة f ( w , x ) { إرجاع w + x ; }دالة المجموع ( ن ) { إذا كان ( ن == 1 ) أرجع 1 ؛ وإلا أرجع f ( ن ، مجموع ( ن - 1 )); }رفع لامدا مقابل إغلاقها
يُعدّ كلٌّ من رفع لامدا والإغلاق طريقتين لتنفيذ البرامج ذات البنية الكتلية . يُطبّق الرفع البنية الكتلية عن طريق إلغائها، حيث تُرفع جميع الدوال إلى المستوى العام. أما تحويل الإغلاق فيُوفّر "إغلاقًا" يربط الإطار الحالي بالإطارات الأخرى، ويستغرق وقتًا أقل في الترجمة.
يمكن تنفيذ الدوال التكرارية والبرامج ذات البنية الكتلية، سواءً مع رفع الذاكرة أو بدونه، باستخدام بنية قائمة على المكدس ، وهي بنية بسيطة وفعالة. مع ذلك، يجب أن تكون البنية القائمة على إطار المكدس صارمة (مُستعجلة) . تتطلب هذه البنية أن يكون عمر الدوال وفقًا لأسلوب " آخر ما يدخل، أول ما يخرج" (LIFO). أي أن آخر دالة بدأت حسابها يجب أن تكون أول دالة تنتهي.
تُطبَّق بعض لغات البرمجة الوظيفية (مثل هاسكل ) باستخدام التقييم الكسول ، الذي يؤجل الحساب حتى الحاجة إلى القيمة. تمنح استراتيجية التنفيذ الكسول المبرمج مرونةً كبيرة. يتطلب التقييم الكسول تأخير استدعاء الدالة حتى يُطلب الحصول على القيمة المحسوبة منها. يتمثل أحد تطبيقات هذه الاستراتيجية في تسجيل مرجع إلى "إطار" بيانات يصف الحساب، بدلاً من القيمة نفسها. لاحقًا، عند الحاجة إلى القيمة، يُستخدم الإطار لحسابها في الوقت المناسب تمامًا. ثم تحل القيمة المحسوبة محل المرجع.
يُشبه "الإطار" إطار المكدس ، مع اختلاف أنه لا يُخزّن على المكدس. يتطلب التقييم الكسول حفظ جميع البيانات اللازمة للحساب في الإطار. إذا كانت الدالة "مرفوعة"، فإن الإطار يحتاج فقط إلى تسجيل مؤشر الدالة ومعاملاتها. تستخدم بعض اللغات الحديثة جمع البيانات المهملة بدلاً من تخصيص الذاكرة على المكدس لإدارة دورة حياة المتغيرات. في بيئة مُدارة ومُجمّعة البيانات المهملة، يُسجّل الإغلاق مراجع الإطارات التي يمكن الحصول منها على القيم. في المقابل، تحتوي الدالة المرفوعة على معاملات لكل قيمة مطلوبة في الحساب.
التعبيرات اللفظية وحساب التفاضل والتكامل لامدا
تُعدّ عبارة let مفيدة في وصف عمليات الرفع والإسقاط، والعلاقة بين المعادلات التكرارية وتعبيرات لامدا. تحتوي معظم لغات البرمجة الوظيفية على تعابير let. كما أن لغات البرمجة ذات البنية الكتلية ، مثل ALGOL و Pascal، تُشابهها في أنها تسمح أيضًا بالتعريف المحلي للدالة لاستخدامها في نطاق محدود .
إن تعبير let المستخدم هنا هو نسخة متبادلة التكرار بالكامل من let rec ، كما هو مطبق في العديد من اللغات الوظيفية.
ترتبط تعابير let بحساب لامدا . يتميز حساب لامدا ببساطة تركيبه ودلالاته، وهو مناسب لوصف رفع تعبيرات لامدا. من الملائم وصف رفع تعبيرات لامدا بأنه تحويل من تعبير لامدا إلى تعبير let ، وحذف تعبيرات لامدا بأنه عكس ذلك. يعود ذلك إلى أن تعابير let تسمح بالاستدعاء الذاتي المتبادل، وهو، بمعنى ما، أكثر رفعًا مما يدعمه حساب لامدا. لا يدعم حساب لامدا الاستدعاء الذاتي المتبادل، ولا يمكن تعريف سوى دالة واحدة في النطاق العام الخارجي.
ترد قواعد التحويل التي تصف الترجمة بدون رفع في مقالة تعبير Let .
توضح القواعد التالية تكافؤ تعبيرات لامدا وليت،
| اسم | قانون |
|---|---|
| تكافؤ اختزال إيتا | |
| تكافؤ ليت-لامدا | |
| مجموعة لي |
سيتم تقديم دوال وصفية تصف رفع وخفض قيم لامدا. الدالة الوصفية هي دالة تأخذ برنامجًا كمعامل. يمثل البرنامج بيانات للبرنامج الوصفي. يقع البرنامج والبرنامج الوصفي على مستويين وصفيين مختلفين.
سيتم استخدام الاصطلاحات التالية للتمييز بين البرنامج والبرنامج الفوقي،
- سيتم استخدام الأقواس المربعة [] لتمثيل تطبيق الدالة في البرنامج الفوقي.
- سيتم استخدام الأحرف الكبيرة للمتغيرات في البرنامج الوصفي. أما الأحرف الصغيرة فتمثل المتغيرات في البرنامج.
- سيتم استخدامها للمساواة في البرنامج الوصفي.
- يمثل متغيرًا وهميًا، أو قيمة غير معروفة.
لتبسيط الأمور، سيتم تطبيق القاعدة الأولى التي تنص على التطابقات. تفترض القواعد أيضًا أن تعابير لامدا قد تمت معالجتها مسبقًا بحيث يكون لكل تجريد لامدا اسم فريد.
يُستخدم عامل الاستبدال على نطاق واسع. التعبيريعني ذلك استبدال كل ظهور للحرف G في L بالحرف S وإرجاع التعبير. تم توسيع التعريف المستخدم ليشمل استبدال التعبيرات، انطلاقًا من التعريف الوارد في صفحة حساب لامدا . يجب أن تقارن عملية مطابقة التعبيرات التعبيرات للتأكد من تكافؤها (إعادة تسمية المتغيرات).
رفع لامدا في حساب لامدا
تستبدل كل عملية رفع لدالة لامدا تجريدًا لدالة لامدا، وهو تعبير فرعي من تعبير لامدا، باستدعاء دالة (تطبيق) لدالة تقوم بإنشائها. المتغيرات الحرة في التعبير الفرعي هي معاملات استدعاء الدالة.
يمكن استخدام عمليات رفع لامدا على الدوال الفردية، في إعادة هيكلة الكود ، لجعل الدالة قابلة للاستخدام خارج نطاقها الأصلي. كما يمكن تكرار عمليات الرفع هذه، حتى لا يحتوي التعبير على أي تجريدات لامدا، لتحويل البرنامج.
مصعد لامدا
تُعطى عملية الرفع تعبيرًا فرعيًا ضمن تعبير رئيسي لرفعه إلى أعلى ذلك التعبير. قد يكون التعبير جزءًا من برنامج أكبر. يتيح ذلك التحكم في مكان رفع التعبير الفرعي. عملية الرفع لامدا المستخدمة لتنفيذ عملية رفع ضمن برنامج هي:
قد يكون التعبير الفرعي إما تجريدًا لـ lambda، أو تجريدًا لـ lambda مطبقًا على معلمة.
يوجد نوعان من المصاعد.
يحتوي الرفع المجهول على تعبير رفع يمثل تجريدًا لدالة لامدا فقط. ويُعتبر بمثابة تعريف لدالة مجهولة . يجب تحديد اسم لهذه الدالة.
يُطبَّق تجريد لامدا على تعبير الرفع المُسمّى. ويُعتبر هذا الرفع تعريفًا مُسمّى لدالة.
مصعد مجهول الهوية
يستمد المصعد المجهول تجريدًا لامدا (يسمى S ). لـ S ؛
- أنشئ اسمًا للدالة التي ستحل محل S (وتسمى V ). تأكد من عدم استخدام الاسم المحدد بواسطة V.
- أضف معلمات إلى V ، لجميع المتغيرات الحرة في S ، لإنشاء تعبير G (انظر make-call ).
إن رفع لامدا هو استبدال تجريد لامدا S بتطبيق دالة، بالإضافة إلى إضافة تعريف للدالة.
يحتوي التعبير الجديد لـ lambda على استبدال S بـ G: L [ S := G ] يعني استبدال S بـ G في L. تمت إضافة تعريف الدالة G = S إلى تعريفات الدوال .
في القاعدة المذكورة أعلاه ، G هي دالة التطبيق التي تحل محل التعبير S. ويتم تعريفها على النحو التالي:
حيث V هو اسم الدالة. يجب أن يكون متغيرًا جديدًا، أي اسمًا لم يُستخدم من قبل في تعبير لامدا.
أينهي دالة وصفية تُرجع مجموعة المتغيرات المستخدمة في E.
| مثال على المصعد المجهول. |
|---|
| على سبيل المثال، انظر إلى de-lambda في قسم التحويل من تعبيرات lambda إلى تعبيرات let . والنتيجة هي: |
إنشاء المكالمة
يتم إنشاء استدعاء الدالة G عن طريق إضافة معلمات لكل متغير في مجموعة المتغيرات الحرة (الممثلة بـ V ) إلى الدالة H.
| مثال على بناء الاستدعاء. |
|---|
مصعد يحمل اسمًا
المصعد المسمى يشبه المصعد المجهول باستثناء أنه يتم توفير اسم الوظيفة V.
أما بالنسبة للرفع المجهول، فإن التعبير G يُشتق من V بتطبيق المتغيرات الحرة لـ S. ويُعرَّف على النحو التالي:
| مثال على مصعد مُسمى. |
|---|
على سبيل المثال، انظر إلى de-lambda في قسم التحويل من تعبيرات lambda إلى تعبيرات let . والنتيجة هي: يعطي، |
تحويل لامدا-ليفت
تُحوّل عملية رفع تعبير لامدا إلى أعلى التعبير، حيث تُرفع جميع تجريدات لامدا إلى أعلى التعبير. ثم تُترجم هذه التجريدات إلى دوال تكرارية ، مما يُلغي تجريدات لامدا. والنتيجة هي برنامج وظيفي بالشكل التالي:
حيث M عبارة عن سلسلة من تعريفات الدوال، و N هو التعبير الذي يمثل القيمة التي يتم إرجاعها.
على سبيل المثال،
يمكن بعد ذلك استخدام دالة de-let meta لتحويل النتيجة مرة أخرى إلى حساب لامدا.
تتضمن عملية تحويل تعبير لامدا سلسلة من عمليات الرفع. كل عملية رفع تتضمن،
- يتم اختيار تعبير فرعي بواسطة الدالة lift-choice . يجب اختيار التعبير الفرعي بحيث يمكن تحويله إلى معادلة بدون تعابير لامدا.
- يتم تنفيذ عملية الرفع عن طريق استدعاء الدالة الوصفية lambda-lift ، الموضحة في القسم التالي.
بعد تركيب المصاعد، يتم دمج الأجزاء معًا في جزء واحد.
ثم يتم تطبيق حذف المعاملات لإزالة المعاملات غير الضرورية في تعبير "let". يسمح تعبير "let" لتعريفات الدوال بالإشارة إلى بعضها البعض مباشرةً، بينما تكون تجريدات لامدا هرمية تمامًا، ولا يجوز للدالة الإشارة إلى نفسها مباشرةً.
اختيار التعبير المناسب للرفع
هناك طريقتان مختلفتان لاختيار تعبير لرفعه. الأولى تُعامل جميع تجريدات لامدا على أنها تُعرّف دوالًا مجهولة. أما الثانية، فتُعامل تجريدات لامدا المُطبقة على مُعامل على أنها تُعرّف دالة. لتجريدات لامدا المُطبقة على مُعامل تفسيران: إما تعبير let يُعرّف دالة، أو يُعرّف دالة مجهولة. كلا التفسيرين صحيح.
هذان المسندان ضروريان لكلا التعريفين.
خالٍ من تعبيرات لامدا - تعبير لا يحتوي على أي تجريدات لامدا.
lambda-anon - دالة مجهولة. تعبير مثلحيث X خالية من لامدا.
اختيار الوظائف المجهولة فقط لأغراض الرفع
ابحث عن أعمق تجريد مجهول، بحيث يصبح عند تطبيق الرفع، الدالة المرفوعة معادلة بسيطة. لا يعتبر هذا التعريف تجريدات لامدا ذات المعامل تعريفًا لدالة. تُعتبر جميع تجريدات لامدا تعريفًا لدوال مجهولة.
lift-choice - أول مجهول يتم العثور عليه أثناء اجتياز التعبير أو لا شيء إذا لم تكن هناك دالة.
على سبيل المثال،
| قاعدة | نوع الوظيفة | خيار |
|---|---|---|
| 2 | ||
| 3 | ||
| 1 | حالا | |
| قاعدة | نوع الوظيفة | خيار |
|---|---|---|
| 2 | حالا | |
| 2 |
اختيار الدوال المسماة والمجهولة لرفع البيانات
ابحث عن أعمق تعريف للدالة، سواءً كانت مُسماة أو مجهولة، بحيث تصبح الدالة المرفوعة معادلةً بسيطةً عند تطبيق عملية الرفع. يُعرّف هذا التعريف تجريد لامدا الذي يحتوي على مُعامل فعلي كدالة. أما تجريدات لامدا التي لا تحتوي على تطبيق، فتُعامل كدوال مجهولة.
- لامدا-الاسم
- دالة مُسماة. تعبير مثلحيث M خالية من تعبيرات لامدا و N خالية من تعبيرات لامدا أو دالة مجهولة.
- اختيار المصعد
- أول دالة مجهولة أو مسماة يتم العثور عليها أثناء اجتياز التعبير، أو لا شيء إذا لم تكن هناك دالة.
على سبيل المثال،
| قاعدة | نوع الوظيفة | خيار |
|---|---|---|
| 2 | ||
| 1 | اسم | |
| قاعدة | نوع الوظيفة | خيار |
|---|---|---|
| 1 | حالا | |
أمثلة
على سبيل المثال، مُركِّب Y ،
تم رفعه على النحو التالي:
وبعد حذف المعلمة ،
كتعبير لامدا (انظر التحويل من تعبيرات let إلى تعبيرات لامدا )،
| تعبير لامدا | وظيفة | من | ل | المتغيرات | |
|---|---|---|---|---|---|
| 1 | حقيقي | ||||
| 2 | |||||
| 3 | |||||
| 4 | |||||
| 5 |
إذا اقتصر الأمر على رفع الدوال المجهولة فقط، فإن مُركِّب Y هو،
وبعد حذف المعلمة ،
كتعبير لامدا،
| تعبير لامدا | وظيفة | من | ل | المتغيرات | |
|---|---|---|---|---|---|
| 1 | حقيقي | ||||
| 2 | |||||
| 3 | |||||
| 4 | |||||
| 5 |
أول تعبير فرعي يتم اختياره للرفع هووهذا يحول تعبير لامدا إلىوينشئ المعادلة.
التعبير الفرعي الثاني الذي سيتم اختياره للرفع هووهذا يحول تعبير لامدا إلىوينشئ المعادلة.
والنتيجة هي،
والمثير للدهشة أن هذه النتيجة أبسط من تلك التي تم الحصول عليها من رفع الدوال المسماة.
تنفيذ
تطبيق الدالة على K ،
لذا،
أو
يستدعي مُركِّب Y مُعامله (الدالة) بشكل متكرر على نفسه. تُحدَّد القيمة إذا كانت للدالة نقطة ثابتة . لكن الدالة لن تنتهي أبدًا.
انخفاض قيمة لامدا في حساب التفاضل والتكامل لامدا
يُقلل حذف تعبيرات لامدا [ 4 ] نطاق الدوال، ويستخدم السياق الناتج من النطاق المُصغّر لتقليل عدد المعاملات. ويُسهّل تقليل عدد المعاملات فهم الدوال.
في قسم رفع تعبيرات لامدا ، تم شرح دالة وصفية لرفع تعبير لامدا الناتج أولاً، ثم تحويله إلى معادلة تكرارية. أما دالة إسقاط تعبيرات لامدا، فتقوم بالعكس، حيث تحول المعادلات التكرارية أولاً إلى تجريدات لامدا، ثم تحذف تعبير لامدا الناتج، ضمن أصغر نطاق يشمل جميع المراجع إلى تجريد لامدا.
يتم تنفيذ عملية إسقاط لامدا على مرحلتين،
انخفاض لامدا
يتم تطبيق دالة حذف لامدا على تعبير ضمن برنامج. ويتم التحكم في عملية الحذف بواسطة مجموعة من التعبيرات التي سيتم استبعادها من عملية الحذف.
أين،
- L هو التجريد اللامدا الذي سيتم حذفه.
- P هو البرنامج
- X عبارة عن مجموعة من التعبيرات التي يجب استبعادها من عملية الحذف.
تحول قطرة لامدا
يُخفي تحويل لامدا دروب جميع التجريدات في التعبير. ويُستثنى من ذلك التعبيرات الموجودة ضمن مجموعة من التعبيرات.
أين،
- L هو التعبير المراد تحويله.
- X عبارة عن مجموعة من التعبيرات الفرعية التي سيتم استبعادها من عملية الحذف.
يُغرق نظام sink-tran كل تجريد، بدءًا من الأعمق.
غرق التجريد
الغرق هو نقل تجريد لامدا إلى الداخل قدر الإمكان بحيث يظل خارج جميع المراجع إلى المتغير.
التطبيق - 4 حالات.
التجريد . استخدم إعادة التسمية لضمان أن تكون أسماء المتغيرات جميعها مميزة.
المتغير - حالتان.
اختبار الاستبعاد يمنع إسقاط التعبيرات،
مثال
| مثال على الغرق | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
على سبيل المثال،
|
إسقاط المعلمات
يُقصد بحذف المعاملات تحسين وظيفة ما بناءً على موقعها داخلها. أما رفع المعاملات (Lambda lift) فيضيف المعاملات الضرورية لنقل الوظيفة خارج سياقها. في عملية الحذف، تُعكس هذه العملية، ويمكن إزالة المعاملات الزائدة التي تحتوي على متغيرات غير مستخدمة.
حذف مُعامل يعني إزالة مُعامل غير ضروري من دالة، حيث يكون المُعامل الفعلي المُمرر هو نفس التعبير دائمًا. يجب أن تكون المتغيرات الحرة للتعبير حرة أيضًا في موضع تعريف الدالة. في هذه الحالة، يُستبدل المُعامل المحذوف بالتعبير الموجود في متن تعريف الدالة، مما يجعله غير ضروري.
على سبيل المثال، لنفترض،
في هذا المثال، يكون المعامل الفعلي للمعامل الرسمي o هو p دائمًا . وبما أن p متغير حر في التعبير بأكمله، يمكن حذف هذا المعامل. أما المعامل الفعلي للمعامل الرسمي y فهو n دائمًا . ومع ذلك، فإن n مرتبط في تجريد لامدا، لذا لا يمكن حذف هذا المعامل.
نتيجة حذف المعامل هي،
على سبيل المثال الرئيسي،
تعريف drop-params-tran هو،
أين،
إنشاء قوائم المعلمات
لكل تجريد يُعرّف دالة، قم بإنشاء المعلومات اللازمة لاتخاذ قرارات بشأن حذف الأسماء. تصف هذه المعلومات كل مُعامل؛ اسم المُعامل، والتعبير عن القيمة الفعلية، وإشارة إلى أن جميع التعبيرات لها نفس القيمة.
على سبيل المثال، في
معاملات الدالة g هي:
| المعامل الرسمي | جميعها لها نفس القيمة | التعبير الفعلي للمعامل |
|---|---|---|
| x | خطأ شنيع | _ |
| o | حقيقي | ص |
| y | حقيقي | ن |
يُعاد تسمية كل تجريد باسم فريد، وتُربط قائمة المعاملات باسم التجريد. على سبيل المثال، g لها قائمة معاملات.
تقوم الدالة build-param-lists بإنشاء جميع القوائم الخاصة بتعبير معين، وذلك من خلال المرور على التعبير. ولها أربعة معلمات؛
- التعبير اللامدا قيد التحليل.
- قائمة معلمات الجدول للأسماء.
- جدول قيم المعلمات.
- قائمة المعلمات المُعادة، والتي تُستخدم داخليًا بواسطة
التجريد - تعبير لامدا من الشكليتم تحليلها لاستخراج أسماء معلمات الدالة.
حدد الاسم وابدأ في إنشاء قائمة المعاملات الخاصة به، مع ملء أسماء المعاملات الرسمية. استقبل أيضًا أي قائمة معاملات فعلية من نص التعبير، وأرجعها كقائمة المعاملات الفعلية لهذا التعبير.
المتغير - استدعاء لدالة.
بالنسبة لاسم دالة أو معلمة، ابدأ بتعبئة قائمة المعلمات الفعلية عن طريق إخراج قائمة المعلمات لهذا الاسم.
التطبيق - تتم معالجة التطبيق (استدعاء الدالة) لاستخراج تفاصيل المعلمات الفعلية.
استرجع قوائم المعاملات الخاصة بالتعبير، والمعامل نفسه. استرجع سجل المعامل من قائمة المعاملات الخاصة بالتعبير، وتحقق من تطابق قيمة المعامل الحالية مع هذا المعامل. سجّل قيمة اسم المعامل لاستخدامها لاحقًا في عملية التحقق.
المنطق المذكور أعلاه دقيقٌ للغاية في طريقة عمله. لا يتم تعيين مؤشر القيمة نفسه إلى "صحيح" مطلقًا، وإنما إلى "خطأ" فقط في حال تعذّر مطابقة جميع القيم. تُسترجع القيمة باستخدام S لإنشاء مجموعة من القيم المنطقية المسموح بها لـ S. إذا كانت القيمة "صحيح" ضمن هذه المجموعة، فإن جميع قيم هذا المعامل متساوية، ويمكن حذف المعامل.
وبالمثل، تستخدم الدالة def نظرية المجموعات للاستعلام عما إذا تم إعطاء قيمة لمتغير ما؛
ليكن - تعبير ليكن.
و - للاستخدام في "let".
أمثلة
على سبيل المثال، بناء قوائم المعلمات لـ،
يعطي،
ويتم حذف المعامل o للحصول على،
| إنشاء قائمة المعلمات لـ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| مثال على قائمة معلمات البناء | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
يعطي،
بما أنه لا توجد تعريفات لـ،ويمكن تبسيط المعادلة إلى: بإزالة التعبيرات غير الضرورية، بمقارنة التعبيرين لـ، يحصل، لوصحيح؛ لوإذا كان هذا غير صحيح، فلا يوجد أي دلالة.وهذا يعني أنه قد يكون صحيحاً أو خاطئاً. لوصحيح؛ لوصحيح؛ لذاهذا غير صحيح. والنتيجة هي،
وباستخدام حجج مماثلة لتلك المستخدمة أعلاه، نحصل على: ومن السابق، |
مثال آخر هو،
هنا، x تساوي f. ويكون تعيين قائمة المعاملات كما يلي:
ويتم حذف المعامل x للحصول على،
| إنشاء قائمة المعلمات لـ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
يتم استخدام المنطق الموجود في برنامج equate في هذا المثال الأكثر صعوبة.
بعد جمع النتائج معًا، من التعريفين لـ؛ لذا استخدامو بالمقارنة مع ما سبق، لذا، في، يختزل إلى، أيضًا، يختزل إلى، لذا فإن قائمة المعاملات لـ p هي فعلياً؛ |
معلمات الإسقاط
استخدم المعلومات التي تم الحصول عليها من خلال إنشاء قوائم المعلمات لحذف المعلمات الفعلية التي لم تعد مطلوبة. تحتوي قائمة المعلمات على drop-params .
- تعبير لامدا الذي سيتم فيه حذف المعاملات.
- ربط أسماء المتغيرات بقوائم المعلمات (مضمنة في إنشاء قوائم المعلمات).
- مجموعة المتغيرات الحرة في تعبير لامدا.
- قائمة المعاملات المُعادة. معامل يُستخدم داخليًا في الخوارزمية.
التجريد
أين،
أين،
عامل
بالنسبة لاسم دالة أو معلمة، ابدأ بتعبئة قائمة المعلمات الفعلية عن طريق إخراج قائمة المعلمات لهذا الاسم.
التطبيق - تتم معالجة تطبيق (استدعاء دالة) لاستخراج
ليكن - تعبير ليكن.
و - للاستخدام في "let".
| حذف المعلمات من التطبيقات | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
من نتائج بناء قوائم المعلمات؛ لذا، لذا،
|
حذف المعاملات الرسمية
تقوم الدالة drop-formal بإزالة المعاملات الرسمية، بناءً على محتويات القوائم المنسدلة. معاملاتها هي:
- قائمة الحذف،
- تعريف الدالة (تجريد لامدا).
- المتغيرات الحرة من تعريف الدالة.
يُعرَّف حذف الصيغة الرسمية على النحو التالي:
ويمكن تفسير ذلك على النحو التالي:
- إذا كانت جميع المعلمات الفعلية لها نفس القيمة، وكانت جميع المتغيرات الحرة لتلك القيمة متاحة لتعريف الدالة، فقم بإسقاط المعلمة، واستبدل المعلمة القديمة بقيمتها.
- وإلا فلا تحذف المعامل.
- وإلا، فأعد جسم الدالة.
| حالة | تعبير |
|---|---|
| ) | |
مثال
بدءًا من تعريف دالة مُركِّب Y،
| تحويل | تعبير |
|---|---|
| ملخص * 4 | |
| لامدا-مجرد-ترجمة | |
| غرق-نقل | |
| غرق-نقل | |
| حذف المعامل | |
| بيتا ريدكس |
مما يعيد مُركِّب Y ،
انظر أيضاً
مراجع
- ↑ جونسون، توماس (1985). "رفع لامدا: تحويل البرامج إلى معادلات تكرارية". في: جوانو، جيه بي (محرر). لغات البرمجة الوظيفية وهندسة الحاسوب. FPCA 1985. سلسلة محاضرات في علوم الحاسوب. المجلد 201. سبرينغر. CiteSeerX 10.1.1.48.4346 . doi : 10.1007/3-540-15975-4_37 . ISBN 3-540-15975-4.
- ↑ مورازان، ماركو ت.؛ شولتز، أولريك ب. (2008). "الرفع الأمثل لدالة لامدا في زمن تربيعي". تنفيذ وتطبيق اللغات الوظيفية - أوراق مختارة منقحة . ص 37-56 . doi : 10.1007/978-3-540-85373-2_3 . ISBN 978-3-540-85372-5.
- ↑ دانفي، أو.؛ شولتز، يو بي (1997). "إسقاط لامدا" . إشعارات ACM SIGPLAN . 32 (12): 90-106 . doi : 10.1145/258994.259007 .
- ↑ دانفي، أوليفييه؛ شولتز، أولريك ب. (أكتوبر 2000). "حذف لامدا: تحويل المعادلات التكرارية إلى برامج ذات بنية كتلية" (ملف PDF) . علوم الحاسوب النظرية . 248 ( 1-2 ): 243-287 . CiteSeerX 10.1.1.16.3943 . doi : 10.1016/S0304-3975(00)00054-2 . BRICS-RS-99-27.
روابط خارجية
- شرح على موقع Stack Overflow، مع مثال بلغة JavaScript
- سلونيجر، كين؛ كورتز، باري. "5. بعض المناقشات حول تعابير let" (ملف PDF) . أسس لغات البرمجة . جامعة أيوا.
- تطبيق لغات البرمجة الوظيفية
- حساب التفاضل والتكامل لامدا
- بناء المترجم
- مقارنات لغات البرمجة
