السلام عليكم و رحمة الله و بركاته...
أعلم أن عنوان الموضوع مستفز قليلاً و لكنه صحيح نسبياً!
دائماً ما يتردد على مسامعنا, أن لغات البرمجة متساوية, و هذا كلام صحيح و غير صحيح في الوقت نفسه. لغات البرمجة متساوية من ناحية أن أي عملية منطقية أو حسابية يمكن أن يتم إعادة كتابتها بلغة البرمجة الأخرى بشكل كامل. الموضوع يدخل في علم الحاسوب البحت, فمثلاً ما يمكن كتابته بـ ++C يمكن كتابته بـ Java و العكس صحيح! علماء الحاسوب يستطيعون إثبات ذلك لك. لغات البرمجة تسمى Turing Complete.. ببساطة شديدة, الحاسوب الوهمي الذي اخترعه Alan Turing و الذي كان يضم عمليات بسيطة جداً جداً يمكنه محاكاة أعقد الحواسيب الحالية.
و لغات البرمجة أصلاً ماهي إلا حواسيب وهمية.... علماء الحاسوب أثبتوا بأن ما يمكن فعله بأعقد تلك الحواسيب يمكن محاكاته بآخر... و بالتالي فإن لغات البرمجة سواء كانت عالية المستوى أو منخفضة متماثلة تماماً في قدراتها.
بالطبع لغة كـ SQL أو الـ Macros الموجود في C ليست Turing Complete و بالتالي لا يمكنها محاكاة كل شيء...
لغات البرمجة تعطيك أدوات, سواء لعمليات التكرار أو العمليات المنطقية و هكذا, و تختلف كل لغة عن الأخرى سواء كان اختلافاً في المظاهر كما في اللغات الـ Imperative كـ C و JAVA و #C .... أو أن يكون هذا الاختلاف جذرياً كما في الـ Functional Paradigm و لغاته الشهيرة كـ Lisp و Haskell.. و هلم جرا :) و ما يمكنك فعله بإحداها يمكن فعله بالأخرى و لكن بطريقة أخرى ربما لا توفرها الأولى...
المهم...
منذ أكثر من عقد من الزمان, تم إدخال ما يسمى بالـ Meta programming لتصبح جزءاً من تقاليد و صلب ++C, و لكنها بقيت غامضة و غريبة, و اعتبرت كالشعوذة حقيقة!
الـ Meta programming تتضمن الـ Templates الشبيهة بالـ Generics في لغات البرمجة الأخرى, و لكنها مختلفة من حيث المبدأ قليلاً,
معظم اللغات يتم التعامل مع الـ Generics فيها وقت الـ Runtime بينما الـ Templates يتم التعامل معها وقت الـ Compile Time.. الفكرة مشوشة حتى الآن صحيح!
الـ Templates في ++C ليست فقط أنواع مجهولة كالـ Generics و لكنها تتضمن أدوات كالـ Macros الخاصة بـ C,
يقال! و لكن ليس لدي مصدر مثبت و إنما كلام مبرمجين :lol: أن أول مرة يتم إكتشاف حقيقة الـ Templates في مؤتمر كان منعقداً في التسعينات, و كان المؤتمر قبل أن يتم توحيد مواصفات ++C في عام 98 حيث كان العمل جارياً لتوحيد تلك المواصفات.
ظهر أحد المبرمجين بقطعة من الكود, و طلب تجربتها, و حين تمت تجربتها أصدر المترجم المستخدم أخطاء عديدة!
يقال أن الحاضرين أصابتهم الدهشة ليس لأن البرنامج أصدر بعض الأخطاء و لكن لأن قائمة ببعض الأعداد الأولية ظهرت ضمن الأخطاء :lol:
و كانت تلك هي البداية......
بكل بساطة, الـ Templates في ++C هي لغة برمجة كاملة Turing Complete و لكن هذه اللغة يتم تنفيذها وقت ترجمة البرنامج! و لا يتنج عنها كود بالمعنى المعروف.... الـ Templates لغة Functional و ليست Imperative بالمناسبة :)
إن كنت لاتعرف, فإن أشهر مكتبات ++C المساة STL و Boost هما مكتبتان تعتمدان على الـ Templates بشكل أساسي جداً, أكثر من مفاهيم البرمجة الكائنية حقيقة....
سأعطيك مثالاً على قوة الـ Meta programming, من المكتبة الشهيرة Boost, و بالتحديد من أروع ما رأيت Spirit :)
مكتبة Spirit كتبها أحد المهندسين الخبراء لتقوم بمهمة محددة, ببساطة هي LL Praser Generator, شبيهة بـ Yacc الغني عن الوصف, Yacc بالطبع يعتبر مدفعية ثقيلة بالمقارنة مع spirit...
Yacc يقوم بانتاج LR Parsers, بالتالي يعتبر ذا امكانيات أكبر من Spirit...
لا يوجد كتاب عن لغات البرمجة, إلا و يتضمن في بدايته شرحأً عن كيفية إنشاء Expression Evaluator بسيط,
و موضوعنا لا يختلف عن ذلك,
فمثلاً الـ EBNF Grammar قد تبدو قريبة للتالي :
و كمثال على العبارات الصحيحة تبعاً لقواعدنا :
الآن :) هل تستطيع لغة البرمجة المفضلة لديك فعل التالي ؟
هذا كود ++C حقيقي! و هو Parser كامل للقواعد الذي ذكرناها في البداية!
الحقيقة أني أشرت في موضوع سابق إلى أن ++C تمكنك من إنشاء Domain Specific Languages ضمنها, تحديداً في هذا الموضوع, و أتى الموضوع اليوم على بالي و أحببت المشاركة بهذه اللمحة.
Meta Programming - يا أيها الزمن القديم عد من جديد! مناقشة لعملية إنتاج الكود عن طريق كود آخر!
كما ترى استطعنا محاكاة EBNF بسهولة بالغة و اصبحت عملية إنشاء parser عن طريق spirit مجرد كتابة القواعد ضمن ++C بالطبع مع بعض التعديلات الطفيفة ...
حتى لو استطاعت لغتك فعل ذلك, فلابد أن تعرف شيئاً مهماً, هو أن تلك الأسطر من الكود لا يتم تنفيذها وقت تشغيل البرنامج و هذا ما أقصده بأن الـ Templates هي لغة برمجة للـ Compile Time.
ببساطة, أسطر الكود ستستخدم في بناء قطعة أخرى من الكود وقت "الترجمة" و قطعة الكود تلك قد تكون كائناً كما في حالتنا هذه, بحيث أن الكائن الجديد "مفصل" تماماً على قدر المهمة التي احتجناها فقط :)
بمعنى أن Parser للغتنا هو ما سيكون ضمن الملف التنفيذ للكود و الذي نتعامل معه من مكان آخر في الكود و ليس أسطر الكود التي رأيتها!
الأمثلة الذكورة بالطبع تجدها في الوثائق الخاصة بالمكتبة الرائعة على العنوان التالي:
تحياتي....


