الخميس، 31 يناير 2013

حَبِّر الورقة !

الحكمة المأثورة لدي الطلبة في أيام الإمتحانات هي:"إذا لم تكن تعلم الإجابة الصحيحة فـ(حَبِّر الورقة)"، و معني  "حَبِّر الورقة" أن يقوم الطالب بإجابة السؤال (الذي لا يعرف إجابته الصحيحة) بأي شيءٍ يخطر بباله أنه يخص تلك المسألة !؛ لأن ترك السؤال بدون الإجابة عليه يعني أنه سيخسر الدرجة الخاصة به لا محالة، أما كتابة أي شيءٍ يخص الموضوع و لو من بعيدٍ فإنه يعني احتمالاً (حتي و إن كان ضئيلاً) في أن يجد مُصحِّح الامتحان ما يعطيه عليه أي درجة، و هذا يندرج أيضاً تحت المثل الشعبي "العِيار اللي ميصيبشي يِدْوِش" أي أن طلقة الرصاص إن لم تُصِب الخصم فهي قادرةٌ علي إرباكه و بلبلته !
و يمكننا أن نري أن تلك الحكمة يمكن تطبيقها علي المبرمج الذي يشعر بالملل أثناء كتابة أكواد المشاريع الكبيرة، كنتُ في السابق قد نصحتُ بالابتعاد عن الكود عندما تكون هناك مشكلةٌ صعبةٌ في المشروع؛ لأن الابتعاد عن الكود بتفاصيله الكثيرة قد يلفت الذهن إلي أمورٍ صغيرةٍ فيها حل المشكلة و لا يمكن التنبه إليها إلا عند تلافي تشويش التفاصيل الدقيقة للكود، لكن ماذا لو لم تكن هناك مشاكل في الكود سوي أن المبرمج من كثرة عمله في المشروع أصابه الملل ؟ و في نفس الوقت لا يستطيع ترك العمل علي المشروع لالتزامه بجدول مواعيدٍ دقيقٍ و حرِج ؟

الإجابة هينةٌ و بسيطة و يمكن اشتفافها من قاعدة "حَبِّر الورقة"، لا أعني أن يقوم المبرمج بكتابة أي شيءٍ في أكواده حتي لو كان خطأً؛ فهذه مصيبةٌ قد تجعله يحس بالمزيد من الملل و تؤخر العمل إلي أن يتم التخلص من الخُرافات التي كتبها. بل أقصد أن يقوم المبرمج بكتابة الأكواد التي لا تحتاج إلي تفكيرٍ عميق، و لا ابتكار خوارزماتٍ مُعقَّدةٍ لا يستطيع ذهنه المُتعَبُ التفكيرَ فيها، مثل تعديل الوراثة بين العديد من الأصناف classes inheritance في مشروعه، أو إضافة تعليقاتٍ comments لأجزاء من الكود لم يتم التعليق عليها كما يجب، أو تكملة عمل التوثيقات documentations للمشروع، او ما شابَههن من أمور.
فائدة هذا الأسلوب أنه لن يكون هناك وقتٌ ضائعٌ لم تتم الاستفادة منه، بل كل ما هنالك أن جدول الأعمال قد اختلف بعض الشيء، و تم إنجاز أشياءٍ كانت موجودةً في ترتيبٍ متأخر. و في نفس الوقت لم يكن هناك الضغط النفسي الذي يسببه الجهد العقلي علي المُرهَقين من المبرمجين.

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

الأحد، 20 يناير 2013

بسيطٌ و مُعقَّد

أمرٌ مدهشٌ جداً أن تَري أن خاصيتَيْن أساسيتَيْن في مُحررات النصوص مثل خاصية (تراجع undo) و خاصية (كرِّر redo) رغم بساطة مبدأيهما: إلا أنهما يحتاجان لانتباهٍ شديدٍ و تجريبٍ كثيرٍ حيت يتم بناؤهما بشكلٍ صحيح !

السبت، 19 يناير 2013

برنامج (الحاسب) 0.1

في الأيام الماضية بعدما انتهيتُ من العمل علي بناء الإصدارة 0.1 من بيئة أندلس، و حينما حاولتُ رفعها علي الشبكة و نشر خبر الانتهاء من الإصدارة حتي يتمكن الناس من تحميلها: وجدتُ أن الشبكة لا تعمل لأنني نسيت شحن الـ "usb modem" قبل انتهاء الشحن الشهري !
أصابني ضيقٌ شديدٌ لأنني كنتُ أريد أن أنتهي من الإعلان عن أول إصدارةٍ لأندلس و من كل ما يخصها قبل مطلع شمس اليوم الجديد، و بما أن الوقت ساعتها كان متأخراً (بعد منتصف الليل) فلم أجد حلاً سريعاً للأزمة، و لم يكن بمقدوري إلا الانتظار حتي الصباح للشحن ثم إتمام العمل. و بما أن أذان الفجر كان قد اقترب موعده قررتُ أن أظل مستيقظاً لأصلي الفجر ثم أنام بعدها.

تسليتُ قليلاً بمشاهدة بعض الفيديوهات للينوس تورفالدز و غيره، لا يزال لينوس تورفالدز قادراً علي إدهاشي بقوةٍ بسبب كمية الثقة بالنفس التي عنده، و تلك السهولة التي يتحدث بها عن إنشاء البرمجيات الضخمة بمفرده (أو علي الأقل بناء المرحلة الأولي منها)، و كان الفيديو الذي شاهدتُ جزءاً منه خاصاً بالمحاضرة التي ألقاها لينوس ضمن محاضرات google tech talk لعام 2007م، و قد سمعتُها بالكامل عدة مراتٍ من قبل !
ثم فجأةً خطرت ببالي فكرةٌ جيدة: لِمَ لا أكتب ذلك البرنامج الذي كنتُ أحتاجه منذ فترةٍ طويلةٍ و بحثتُ عن شبيهٍ له فلم أجد ؟!

الحكاية أنني كنتُ (و لا أزال) أحتاج إلي برنامجٍ يقوم بحساب عدد الأسطر البرمجية التي توجد في أكواد مشاريعي المختلفة المكتوبة بلغة الـjava؛ حتي أعلم إلي أي حدٍ وصلت الضخامة النصية لكل مشروع، و بالطبع
فإن مُفسِّر أُبْدِع علي رأس تلك المشاريع. و حينما بحثتُ عن هذه الخاصية في بيئة الـnetbeans لم أجدها، و حينما بحثتُ علي الشبكة عن برنامجٍ منفصلٍ يقوم بتلك المهمة لم أجد بُغيتي.
ساعتها قررتُ أن أكتب البرنامج بنفسي؛ للاستفادة منه كما سبق القول، و كذلك لاكتساب خبراتٍ جديدة (هدفي المقدس أبداً و دائماً).

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

في الختام أصبحت إمكانات البرنامج كما يلي:
- حساب العدد الكلي لأسطر الأكواد في المشاريع البرمجية،
- حساب العدد الكلي للملفات النصية داخل المشروع،
- إمكانية تخصيص عملية الحساب بأنواعٍ معينةٍ من الملفات (للتركيز علي ملفات لغة برمجةٍ معينة) عن طريق استخدام الامتدادات الخاصة بها،
- حساب عدد الملفات الخاص بكل امتدادٍ بمفرده و عدد الأسطر التي تخصه من عدد الأسطر الكلي.

و قد جربتُ البرنامج علي الكثير من المشاريع البرمجية، سواءٌ تلك التي كتبتُها أنا أو التي توافر لديَّ كودها المصدري، و منها الكود الخاص بمكتبة الـOpenCV في الإصدارة 2.0 منها، و بالطبع اهتممتُ بإجراء تحليلٍ لمشروع مُفسِّر أُبْدِع كما في الصورة:
و بعد أن انتهيتُ من بناء البرنامج كتطبيقٍ منفصلٍ قمتُ بحمد الله تعالي بدمجه داخل بيئة أندلس في الإصدارة 0.2 التي أعمل عليها هذه الأيام.

و قد كان هذا بعد عناءٍ شديد :)

يمكن لمن يرغب في استخدام البرنامج تحميله من هنا:
علي الـ4shared
علي الـsourceforge



و هناك كتيبٌ لتعليم كيفية تنصيبه و استخدامه، يمكن تحميله من هنا:
علي الـ4shared
علي الـsourceforge


كما أن البرنامج مفتوح المصدر open source لمن يرغب في استعمال أكواده أو البناء عليه، و يمكن تحميل كوده من هنا:
علي الـ4shared
علي الـsourceforge

الخميس، 17 يناير 2013

الإصدارة 0.1 من بيئة (أندلس)

بحمد الله تعالي تم بناء الإصدارة 0.1 من بيئة البرمجة المتكاملة (أندلس)، للبرمجة بلغة البرمجة العربية (إبداع). و هي برنامجٌ ذو واجهةٍ رسوميةٍ يمكن استدعاؤه عن طريق الاختصارات shortcuts أو يمكن أن يُستدعَي من خلال سطر الأوامر command line. و يمكنكم معرفة المزيد عن إطلاق أندلس من خلال الخبر علي الموقع الرسمي:

السبت، 12 يناير 2013

لغة الـC كلغة تمثيلٍ وسيط IR

عند بناء مُترجِمات لغات البرمجة programming languages compilers فإن جزءاً من أصعب الأجزاء التي يحتاج المبرمجون إلي بنائها هو النهاية الخلفية back end، المُترجِم في الأساس يتكون من ثلاثة أجزاءٍ رئيسةٍ هي:
  • النهاية الأمامية front end.
  • النهاية الوسطي middle end.
  • النهاية الخلفية back end.

و يقوم جزء الواجهة الأمامية بقراءة الكود الذي كتبه المُبرمِج و يكتشف الأخطاء التي فيه إن وُجِدت، فإن لم يكن هناك أخطاءٌ قام بتحويل ذلك الكود إلي ما يُسمَّي بشجرة السَّبْر الصافية abstract syntax tree، و التي هي عبارة عن مجموعةً من العُقَد nodes المتصلة ببعضها البعض و تُعبر عن سير البرنامج كما يريده المبرمج.
أما جزء الواجهة الوُسطَي  فيقوم بتحويل تلك الشجرة إلي لغةٍ وسيطة، لا تكون عالية المُستوَي كاللغة التي استخدمها المبرمج في الأصل، و لا تكون مُنخفضة المُستوي مثل لغات التجميع assembly languages. بل تكون وسطاً بين النوعين، و يمكن أن نصفها بأنها عبارة عن لغة تجميعٍ محمولة portable assembly language.
و في الختام يقوم جزء النهاية الخلفية بتحويل التمثيل الوسيط إلي كود تجميع خاصٍ بالمُعالِج processor المقصود. و من ثم يقوم ما يُسمَّي بالمُجمِّع assembler بتحويل كود التجميع إلي الأصفار و الآحاد و التي هي اللغة الحقيقية للآلات (هناك عملياتٌ أخري هنا و هناك، و لكني أحاول أن أُعطي فكرةً عامةً عن الأمر).

بناء المُترجِمات الاحترافية أمرٌ صعبٌ جداً و طويل الأمد للغاية، و تزيد صعوبته كلما زادت إمكانيات اللغة التي يتم بناء مُترجمِ لها. و لكن مِن أكثر الأجزاء صعوبةً و ثقلاً علي النفس: جزء الواجهة الخلفية؛ لأنه يُعتبر عملياً من أكثر الاجزاء  تعقيداً و ضخامةً و "حاجةً للتمديد مع الزمن". 
أما الضخامة و الصعوبة فشرحهما له مقامٌ آخر، و أما الحاجة للتمديد مع الوقت فتأتي كنتيجةٍ طبعيةٍ لمحاولتنا دعم أرضياتٍ جديدةٍ يمكن للمُترجِم أن يُنتِج لها برامج تعمل عليها، ففي البداية ستدعم الأرضيات الأكثر شهرةً مثل معماريتَيْ X86 و ARM مثلاً، ثم بعد ذلك ستجد أنك تحتاج لدعم PowerPC و غيره من المُعالِجات، و هكذا تكتشف أن أجزاء النهاية الخلفية صارت تتكاثر كالأرانب البرية !. 
و لهذا كله فما إن يري مبرمجو المُترجِمات أي فرصةٍ للتخلص من عبء بناء الواجهة الخلفية حتي يهرعوا إليها خِفافاً و ثِقالا !
و من هذه الفرص التي يُمكن أن تريح هؤلاء المبرمجين: إمكانية استخدام لغة برمجةٍ متوسطة المُستوي موجودةٍ بالفعل كلغة تمثيلٍ وسيط، و يمكن الاستفادة من هذا في الأمور التالية:
  • عدم الحاجة لبذل الجهد الشديد في بناء النهاية الخلفية من الصفر، و قد شرحنا العوامل التي تجعل هذا المجهود خرافياً. و بعد توفيره يمكن توجيهه إلي جزءٍ آخر من المشروع.
  • حينما تكون اللغة متوسطة المستوي لها مُترجِماتٌ يمكنها ترجمة الأكواد المكتوبة بها إلي كثيرٍ من المنصات المختلفة: فإن لغتنا الجديدة سيكون لها ذات الإمكانية. و هذا هامٌ بما لا يُقاس؛ تخيل أن تقوم بضربةٍ واحدةٍ بإعطاء لغتك إمكانية إنتاج برامجٍ تعمل علي عشرات المُعالِجات و أنظمة التشغيل المُختلِفة ! سيحقق هذا بلا شك طفرةً كبيرةً جداً في محمولية portability لغتك الجديدة. كما أنه حينما يكون هناك تحسيناتٌ مقبولةٌ في المُترجم الذي ستستعمله كنهايةٍ خلفيةٍ فسيجعلك هذا تضيف "كفاءة استغلال البرامج المكتوبة بلغتك لموارد الحاسوب" إلي قائمة المكاسب التي حصلتَ عليها بضربةٍ واحدة.
  • مهما كانت اللغة منخفضةً في مستواها فإنها بلا شكٍ ستكون أفضل عند برمجة البرامج الضخمة من أكواد التجميع assembly code؛ فهي علي الأقل ستُوفِّر لك مكوناتٍ أكثر قرباً للبرمجة عالية المستوي من تلك الأخيرة، و بهذا يُمكنك الانتهاء من بناء النهاية الوسطي ذاتها في وقتٍ أقل مما كان سيكون عليه في حالة الاعتماد علي لغةٍ وسيطةٍ أقرب للغة التجميع.
  • نظراً  لأن المجهود المبذول في تغيير قواعد لغتك الجديدة و معانيها سيكون أقل بالمقارنة مع الحالة التي تستخدم فيها أكواد التجميع بدلاً من اللغة متوسطة المستوي: فإنك سنكون أقدر علي تطوير لغتنك و أكثر جرأة. في الواقع أنا أكره التغييرات الجوهرية في لغات البرمجة و لا أطيق حدوثها، لكن هناك بعض الأحيان التي تحتاج فيها للتغير الكبير و/أو المتعدد في لغة البرمجة الخاصة بك، مثلاً لو كنتَ تعمل في بحثٍ تجريبيٍ و تريد أن تقوم بتجربة أكثر من شكلٍ من أشكال القواعد في لغتك لتختار الأنسب، من حيث التناسق مع بقية القواعد أو من حيث الأداء الأفضل أو غيرهن من عوامل المقارنة، أو أن تكون أستاذاً جامعياً يبني مُترجِماً يصلح أن يستخدمه طلابه لبناء العديد من لغات البرمجة استناداً إلي أكواده. في هاتين الحالتين و أمثالهن ستحتاج إلي مرونةٍ عاليةٍ في بناء المُترجِم، و قابلةٍ عاليةٍ لتسريع عملية التغيير في القواعد، و هو ما توفره هذه المنهجية.

و لكن يجب أن تكون اللغة التي سنستخدمها كلغة تمثيلٍ وسيطٍ  ينطبق عليها الشروط التالية؛ حتي يصير استعمالها مقبولاً:

  • أقل في المستوي من لغتك التي تبني لها مترجماً جديدا؛ لأنها لو كانت ذات مستويً مُقارِبٍ لها لأصبح الأمر مجرد ترجمة برنامجٍ من لغةٍ برمجةٍ إلي لغة برمجةٍ أخري، فتصير اللغة الجديدة مجرد واجهةٍ للغة القديمة.
  • ذات مستوي برمجةٍ منخفض بما يكفي للتعامل مع العتاد و استخدامها لذلك الغرض بحريةٍ و مرونة.
  • ذات محموليةٍ عالية؛ أي أن تكون البرامج المكتوبة باستخدام تلك اللغة الوسيطة قابلةً للترجمة علي العديد من المُعالِجات، و إعطاء نفس النواتج مهما اختلفت الأرضية التي تعمل عليها.
  • ذات توحيدٍ قياسيٍ عالٍ، أي أن قواعد تلك اللغة تكون مكتوبةً بشكلٍ واضحٍ بطريقةٍ يمكنك الاعتماد عليها، و حينما تكتب برنامجاً باستخدامها يعمل كما هو مشروحٌ في المواصفات القياسية للغة.
  • غير قابلةٍ لتدمير المفاهيم المنطقية للبرامج المُترجَمة إليها، أي أنه حينما تكتب برنامجاً باللغة الوسيطة لا يقوم المُترجِم علي سبيل المثال بالتغيير فيه بأي شكلٍ من الأشكال التي تضر بمنطقيات لغتك و ما يُفترَض أن يحدث في الأصل. و لو كانت قادرةً علي فعل هذا فيجب أن يكون هناك طريقةٌ لتجنبه في المُترجِم.
  • وجود مُترجِماتٍ لها إلي كثيرٍ من المعالجات المشهورة، فمن ضمن الأغراض الأساسية لهذه المنهجية: الاستفادة من ميزات اللغة منخفضة المستوي كلها و من أهمها قابلية برامجها للعمل علي أكثر من منصةٍ platform مشهورة.
  • أن تكون تلك المُترجِمات القوية مفتوحة المصدر open source، في الواقع يمكنك استخدام المُترجمات مغلقة المصدر كما تحب، و لكن استخدام النوع الذي تتوافر لديك أكواده أفضل بكثير؛ فربما تحتاج لمعرفة كيفية بناء المُترجم الذي تستعمله للأكواد، حينها لا تستطيع فعل ذلك مع المُترجمات مغلقة المصدر بينما يمكنك أن تفعل هذا مع الحرة. بل ربما تحتاج في بعض الأحيان لتعديل طريقة عمل المترجم بما يتوافق مع مشروعك الخاص تعديلاً كبيراً أو غير كبير، و هذا سيجعلك لا محالة تستخدم المترجمات الحرة.

لكن من العيوب التي أراها في هذه المنهجية ما يلي: 

  • تَحرِم المبرمج الذي يستخدمها من خبراتٍ كثيرةٍ كان سيحصل عليها من سلوك المنهج الأصلي (أعني بناء الواجهة الخلفية التي تُنتِج أكواد التجميع بنفسه). و هذا بالطبع أمرٌ يعتمد علي الخبرة التي يمتلكها ذلك المبرمج من الأصل؛ فلو كان صاحب خبرةٍ طويلةٍ في بناء المترجمات فلن يكون لهذا العيب وجود، أما لو كان مثلي قليل الخبرة فسيحتاج إلي شجاعة الأعتراف بأنه "لا مفر يا صاح، عليك وضع كلتا يدَيْك في صندوق التروس !". و كذا يعتمد الأمر علي الوقت المُتاح لإنجاز المشروع، و الدعم المادي المُتوافر له.
  • سوء انتقاء اللغة التي تعمل كلغةٍ وسيطةٍ  و/أو مُترجمها الذي سنستعمله كنهايةٍ خلفيةٍ ربما يؤدي إلي نقصٍ في المحمولية و/أو ضعف أداءٍ للبرامج المُنتَجة و/أو سوء استغلالها لموارد الحاسوب، أو حتي تغير المفاهيم المنطقية للبرنامج !
  • البطء في الترجمة لو كان مترجم اللغة الوسيطة بطيئاً، أو ظهور عللٍ في البرامج المُنتَجة إذا كان ذلك المُترجِم تظهر فيه عللٌ أثناء عمله. خذوا مثلاً تجميعة مُترجِمات الـgcc التي لم يدعمها فريق نظام الـ plan9 حتي فترةٍ قريبة (لا أعلم هل دعموه حتي الآن أم لا)، بل و قام أحد أعضاء الفريق بمهاجمتها بشدة أثناء أحد العروض التقديمية له عن plan9 في أحد محاضرات مؤتمر الـfosdem في عام 2006 بسبب العِلل التي تظهر فيه بعض الأحيان في ظروف تحسينٍ optimizaion مُعيَّنةٍ ! (أُنبِّه إلي أنه لا شأن لي بآرائهم في الـgcc؛ فلا أريد أن يسبني أحدهم بسبب هذا).


حسنٌ: هل تصلح الـC كلغة تمثيلٍ وسيط ؟:
أظن أن الـC من أفضل اللغات التي تنطبق عليها شروط اللغات الوسيطة السالفة الشرح؛ فلو حاولنا تطبيق الشروط التي وضعناها بالأعلي عليها فسنري أنها تنجح بامتياز:

  • الـC لغةٌ منخفضة المستوي جداً بحيث صار من الواضح أنها ليست إلا لغة تجميعٍ محمولة، مهلاً: قبل أن يبدأ أحدكم في التشنيع عليَّ أو مطالبتي بالتعلم قبل التكلم أريدكم أن تقرؤوا ما قاله لينوس تورفالدز linus torvalds عن هذا الأمر في إحدي تدويناته القصيرة (علي مدونته الشخصية التي هجرها منذ أعوام)، حيث كتب:
    Some people seem to think that C is a real programming language, but they are sadly mistaken. It really is about writing almost-portable assembly language, and it turns out that getting good results from SHA1 really is mostly about trying to fight the compilers tendency to try to be clever.

    و أُترجمها:
    يبدو أن بعض الناس يفكرون في الـC علي أنها لغة برمجةٍ حقيقية، لكنهم مع الأسف مخطئون؛ هي في الحقيقة ليست إلا لغة تجميعٍ محمولة (أي: للعمل علي أكثر من مُعالِج)، و اتضح في النهاية أن الحصول علي نتائجٍ جيدةٍ من خوارزمية SHA1 يعتمد في معظمه علي محاربة محاولات المُترجِم أن يكون ماهراً !

    و لينوس يقصد بـ"محاولات المُترجِم أن يكون ماهراً" أن يقوم المترجم بالتغيير في الأكواد التي يكتبها المبرمج للوصول إلي استغلالٍ أفضل للمعالج أو الذاكرة، و هو ما ينتج عنه أخطاءٌ في عمل البرنامج لو كان يعتمد علي الأوامر الأصلية دون غيرها و بذات الترتيب الذي كُتِبت به دون غيره، و هو ما لا يحدث إلا مع لغات التجميع، و لذا وصف لينوس لغة الـC بأنها ليست لغة برمجةٍ حقيقيةٍ بل لغة تجميعٍ محمولة.
    الآن يمكنكم شتمي كما تريدون و مطالبتي بالتعلم قبل التكلم، لكن رجاءاً اشتموا لينوس معي و طالبوه بالمثل ^_^
  • الـC ذات محموليةٍ عالية، صحيحٌ أنك ستواجه مشاكلاً مع اختلاف الإصدارات و اختلاف "رؤية" بناة المترجمات لكثيرٍ من الأمور، إلا أنك في النهاية ستستخدم مترجماً يخضع لرؤيةٍ واحدة (يمكنكم تسميتها: التوحيد القياسي للمُترجِم)، لذا فليست هناك مشكلة في هذه النقطة أو في نقطة التوحيد القياسي العالي.
  • يمكن لمترجمات الـC تدمير المفاهيم المنطقية للبرامج المُترجمة إليها عند استخدامها كنهايةٍ خلفية؛ و ذلك كما أوضحنا من خلال كلام لينوس السابق الذِكر بسبب محاولات مُترجِم الـC أن يكون ماهراً و يقوم بتحسين الكود الذي يعمل عليه، لكن في النهاية يمكنك إيقاف هذا السلوك و استخدامه كمجرد مُجمِّع، و ذلك كما وصفه لينوس في نفس التدوينة السابقة بقوله:

    but it was kind of fun in a "let's use the compiler as a glorified assembler" kind of way.


    و أُترجمها:
    لكن هذا كان مَرِحاً علي طريقة "فلنستخدم المُترجِم كمُجمِّعٍ ضخم" :) 
  • يوجد مُترجماتٌ لها إلي الأغلبية الساحقة من المُعالِجات، في الواقع يُقال أنه يمكنك أن تكتب برامج باستخدام لغة الـC لأي مُعالِج ظهر فوق سطح الأرض. و  أنا أظن أنك لو سألتَ كاتب سيناريو فيلم (يوم الاستقلال independence day) عن كيفية وضع أبطال الفيلم لفيروسٍ أرضيٍ علي حواسيب أجهزة المركبة الفضائية الأم الخاصة بغزاة الفضاء: فعلي الأرجح سينظر لك بقرفٍ و يقول" يا لك من أحمق: إنهم بالطبع يستعملون لغة الـC و نظام الـwindows"  :) 
  • توجد مجموعةٌ من أقوي المُترجِمات للـC كبرامج مفتوحة المصدر، علي الأرجح سمعتم عن الـgcc الخاص بمؤسسة الـfsf، و الذي كانت نواته الأولي خاصةً بلغة الـC فقط ثم تم ضم العديد من اللغات الأخري إليه ليصير تجميعةً من المُترجِمات. الحقيقة أنه يتم استخدام الـgcc علي نطاقٍ واسعٍ للغاية حتي في التطبيقات التجارية، و ربما لو ضغطتَ علي نفس كاتب السيناريو لقال لك أن غزاة الفضاء يستخدمون الـgcc لبناء برامجهم :)


هل هناك مُترجِماتٌ طبَّقت هذا الأمر عملياً ؟:
هناك مترجماتٌ قامت بالفعل باستخدام لغة الـC كتمثيلٍ وسيط، و منها مُترجِماتٌ عديدةٌ للغة الـeiffel، و جاء في موسوعة الويكيبيديا عن هذه النقطة ما نصه:

Although there is no direct connection between Eiffel and C, many Eiffel compilers (Visual Eiffel is one exception) output C source code as an intermediate language, to submit to a C compiler, for optimizing and portability.

و أُترجمه:
علي الرغم من أنه ليست هناك صِلةٌ مُباشِرةٌ بين الـeiffel و الـC، إلا أن العديد من مُترجِمات الـeiffel (الـVisual Eiffel استثناءٌ واحد) تُخرِج كود C كلغةٍ وسيطة؛ لإرساله إلي مُترجِم C؛ بسبب التحسين و المحمولية.

و بالإضافة إلي لغة الـeiffel فأظن أن هناك لغات برمجةٍ وظائفيةٍ functional programming languages فعلت المِثل، و إن كنتُ لا أتذكرها الآن.


هل من الممكن أن أفعل هذا مع مُفسِّر (أُبْدِع) ؟:
بصراحةٍ: فكرة الاعتماد علي لغة الـC كلغة تمثيلٍ وسيطٍ في أُبْدِع (حينما يتحول إلي مفسِّرٍ/مُترجِم) تُلح علي رأسي بقوة؛ فأنا أحتاج لتوفير كثيرٍ من الوقت لإخراج المواصفات القياسية النهائية من لغة إبداع إلي النور، و استخدام الـC سيوفر عليَّ أغلبية هذا الوقت. لكن المشكلة أنني سأضطر في النهاية (و في كل الأحوال) إلي بناء الواجهة الخلفية بنفسي لعديدٍ من الأسباب ليس هنا محلها !
لذا فمن الصعب حسم هذه المسألة حالياً.

شيءٌ أخير: هذا المقال يُظهِر أنني أكره الـC حينما يتم تقديمها كلغةٍ "عامَّة الأغراض عالية المُستوَي" بل و يثير هذا جنوني إلي أقصي الحدود، أما حينما يتم تقديمها كلغة "تجميعٍ محمولةٍ" يتحول كل كرهي لها إلي حبٍ و افتتان. ليس الأمر عجيباً إذا ما قارنتم بين رؤيتي للغات عالية المُستوَي عامة الأغراض و بين صفات لغة الـC و الأغراض  التي صُمِّمَت لأجلها.

أُشجِّع القراء علي الاستفادة من هذه المقالة في كتابة ورقةٍ علميةٍ شاملةٍ وافية، و ربما أقوم بفعل ذلك بنفسي في المستقبل بمشيئة الله تعالي.