علوم البرمجة

مقدمة في لغات البرمجة Intro to Programming Languages

1. مقدمة

أصبح التواصل مع الحاسوب أمرًا أبسط وألطف بكثيرٍ من ذي قبل، حيث وبفضل تطور تقنيات اللمس والتعرف على الكلام، أصبحت الحواسيب قادرة على “الإحساس” بنا وفهم كلامنا وحتى استخدام نفس لغتنا. بالجهة المعاكسة، وعندما نقوم بإرسال أمرٍ صوتيّ لهاتفنا الذكيّ أو لأحد المساعدات الرقمية الذكية، فإننا لا نستخدم “اللغة الأم” للحاسوب، بل ندع الجهاز المسكين يتولى عملية فهم كلامنا وتحليله ومن ثم تحويله للغته الأم التي يستطيع دماغ الحاسوب – أي المعالج – فهمها وتفسيرها. ما بين اللغة التي نستخدمها وبين اللغة التي يفهمها الحاسوب هنالك نمطٌ خاص من اللغات الوسيطة التي تتحمل عبء تأمين عملية تواصلٍ فعال بيننا وبين الأجهزة الرقمية من حولنا: إنها لغات البرمجة التي يستخدمها ملايين المبرمجين حول العالم لكتابة البرامج والتطبيقات المختلفة التي نستخدمها بكل تفاصيل حياتنا.

ببساطةٍ شديدة، فإن لغة البرمجة الحاسوبية Computer-Programming Language عبارة عن لغةٍ ذات قواعد وأطر محددة يمكن استخدامها من أجل كتابة البرامج والتطبيقات العاملة على الحواسيب بما يؤدي لتنفيذ خوارزميةٍ معينة سيؤدي إنجازها للحصول على ناتجٍ ما.

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

عبر هذا المقال سيتم تسليط الضوء على المفاهيم الأساسية المرتبطة بلغات البرمجة، أجيالها، تقسيماتها المختلفة وأكثر لغات البرمجة شعبيةً وانتشارًا في وقتنا الحاليّ.

2. نظرة عامة حول لغات البرمجة: كيف نتخاطب مع الحاسوب؟

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

ما يقوم به أي نظامٍ حاسوبيّ بأي لحظة زمنية هو تنفيذ تعليمة مُحددة، وعلى مستوى المعالج، فإن “تنفيذ” التعليمة يتطلب جلبها من الذاكرة لإخبار المُعالج ما هي المهمة التي يجب أن يقوم بها، وكيف يجب أن يقوم بها، وهكذا، يجب أن يكون هنالك “لغة” مُتفق عليها بين المعالج والذواكر وأي وحداتٍ أخرى كي يستطيعوا “التخاطب” مع بعضهم البعض، وهذه “اللغة” يجب أن تكون مفهومة للجميع. نحن كبشر نتواصل مع بعضها البعض باستخدام اللغات المنطوقة، وطالما أننا نستخدم نفس اللغة، فإن عملية التواصل ستكون ناجحة، وبنفس الطريقة يحتاج المعالج والذواكر للغةٍ موحدة يستطيعون التخاطب عبرها. هذه اللغة هي “لغة الآلة Machine Language” والتي تُعتبر أدنى مستويات لغات البرمجة حيث تتكون ببساطة من سلسلة من الأصفار والواحدات ذات أطوالٍ محددة. وبالتالي، وعند وصول سلسلة معينة من الأصفار والواحدات للمعالج فإن ذلك سُيخبر المعالج بضرورة تنفيذ أمرٍ ما. هذه السلسلة هي ما يُشار إليه بالـ “تعليمات Instructions“. ما سيقوم به المعالج هو تنفيذ هذه التعليمة ومن ثم إرسال النتيجة عبر النواقل مرةً أخرى إلى الذواكر أو إلى أي طرفيةٍ أخرى طلبت تنفيذ هذه التعليمة.

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

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

هذا الأمر، أي صعوبة التخاطب مع المعالج عبر لغة الآلة، هو ما أدى لتطوير طرق أخرى يمكن عبرها كتابة البرامج المختلفة عبر استخدام وسائل أكثر فهمًا وأقرب للغات المنطوقة التي نستخدمها كبشر في التواصل اليوميّ. أول هذه اللغات هي لغة التجميع Assembly Language التي حلّت محل لغة الآلة كوسيلةٍ لكتابة البرامج الحاسوبية حيث تتألف أي لغة تجميع من عددٍ محدد من التعليمات البسيطة التي يؤدي تنفيذها لإنجاز مهام “منخفضة المستوى Low Level” مثل وضع قيمة عددية ضمن مسجلٍ ما، نقل القيمة الموجودة ضمن مسجلٍ إلى مسجلٍ آخر، جمع عددين من مسجلين مختلفين ووضع الناتج ضمن مسجلٍ ثالث وهكذا.

أول الأسئلة التي ستتبادر إلى الذهن هي كيفية فهم المعالج للتعليمات المكتوبة بلغة التجميع، فهي ليست سلسلة من الأصفار والواحدات بل عبارة عن تعليمات مكتوبة بأحرفٍ باللغة الإنجليزية. الجواب ببساطة هو “المُجمّع Assembler” والذي بدوره عبارة عن برنامجٍ يقوم بقراءة الشيفرة المكتوبة بلغة التجميع ومن ثم يقوم بترجمتها إلى لغة الآلة التي يفهمها المعالج. هنالك أمرٌ هام جدًا يجب معرفته فيما يتعلق بلغة التجميع، وهي ارتباطها الوثيق بمعمارية التعليمات الخاصة بالمعالج Architecture’s Machine-Code Instructions، وهي الطريقة التي يستطيع عبرها المعالج أن يفهم التعليمات التي تأتي إليه. ما يتوّجب هنا معرفته أن لغة التجميع نفسها ترتبط بمعمارية المعالج، وبالتالي لا يوجد هنالك لغة تجميع موّحدة يمكن استخدامها مع كل أنواع المعالجات مهما اختلفت معمارياتها.

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

بهذه الصورة، يمكن تقسيم لغات البرمجة إلى ثلاثة مستويات أساسية:

  • لغة الآلة Machine Code: سلاسل من الأصفار والواحدات المقسمة إلى تعليماتٍ Instructions بحسب معمارية المعالج. بشكلٍ أكثر دقة، فإن لغة الآلة قد تأخذ شكل شيفرةٍ مرّمزة بالترميز الست-عشري Hexa-Decimal والتي يمكن على مستوى العتاد فهمها وتحويلها للشيفرة الثنائية Binary-Code، أي أصفار وواحدات والتي يستطيع العتاد فهمها وتنفيذها بشكلٍ مُباشر.
  • لغة التجميع Assembly Language: لغة نصية تتألف من عددٍ محدد من التعليمات المكتوبة باللغة الإنجليزية التي يتم تحويلها للغة الآلة عبر استخدام المجمع Assembler.
  • اللغات عالية المستوى High Level Languages: لغات نصية تتألف من عددٍ من القواعد والنصوص التي يمكن استخدامها لكتابة البرامج المختلفة. تتيح هذه اللغات قدراتٍ كبيرة من حيث سهولة كتابة البرامج بفضل نصوصها الأكثر فهمًا بالنسبة للبشر. يتم فهم هذا النمط من اللغات عبر تحويلها للغة الآلة عبر استخدام المترجمات Compilers أو المُفسرّات Interpreters.

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

3. أجيال لغة البرمجة Programming Languages Generations

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

1.3 لغات الجيل الأول والثاني First and Second Generations of Programming Languages

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

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

يجب الإشارة إلى أن مصطلحات “الجيل الأول” و “الجيل الثاني” لم تظهر فعليًا إلا بعد ظهور لغات الجيل الثالث التي اختلفت بشكلٍ كبير عن لغة الآلة ولغات التجميع.

2.3 لغات الجيل الثالث Third Generation Programming Languages

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

تُعتبر لغات فورتران FORTRAN، كوبول COBOL وألغول ALGOL من أوائل لغات البرمجة التي تنتمي للجيل الثالث وقد ظهرت جمعيها في منتصف وأواخر خمسينات القرن الماضي، ولاحقًا بدأت لغاتٌ أخرى بالظهور والتي تتيح قدراتٍ أكبر وأوسع، بدءًا من لغة “سي C وصولًا للغات “سي بلس بلس ++C“، “جافا Java“، “باسكال Pascal” والتي تُعتبر جميعها من لغات الجيل الثالث. تدعم مُعظم لغات الجيل الثالث البرمجة الهيكلية Structured Programming كما أن العديد منها يدعم مفهوم البرمجة غرضية التوجه Object-Oriented Programming، وتبقى الميزة الأساسية التي تجمعها هي عدم ارتباطها بمعمارية المعالج، حيث يمكن استخدام لغة مثل C من أجل كتابة برامج قابلة للتنفيذ على معمارياتٍ مختلفة للمعالجات.

3.3 لغات الجيل الرابع Fourth Generation Programming Languages

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

دخول الحواسيب مجالاتٍ مختلفة بدءًا من سبعينات القرن الماضي فتح الباب أمام أنواعٍ مختلفة من البيانات التي سيتم التعامل معها، وهكذا ظهر مصطلح لغات الجيل الرابع التي تشير إلى لغات البرمجة القادرة على التعامل مع كمياتٍ كبيرة ومتنوعة من البيانات، مثل اللغات المخصصة لإدارة قواعد البيانات Database Management، توليد التقارير، تطوير واجهات المستخدم الرسومية GUI أو التطوير بمجال الويب. يُمكن اعتبار لغات SQL، Ruby، R و PHP كأمثلة على لغات البرمجة من الجيل الرابع.

يجب الإشارة إلى أن العديد من لغات الجيل الثالث قد تطورّت بشكلٍ كبير عبر إصداراتها المختلفة وأصبحت تتضمن العديد من الميزات التي تم اعتبارها كخصائص تابعة للغات الجيل الرابع، وهذا ما جعل التمييز بين لغات الجيل الثالث والرابع أمرًا صعبًا، وبدلًا من استخدام مصطلح “لغات الجيل الرابع”، يتم تصنيف لغة مثل بايثون Python على أنها من لغات الجيل الثالث المتقدمة، أي المشابهة لما تقدمه لغة مثل ++C في كثيرٍ من خصائصها، ولكن مع قدراتٍ متقدمة في مجال التعامل مع البيانات وتحليلها، وهكذا لا يمكن اعتبار اللغتين من جيلين مختلفين.

4.3 لغات الجيل الخامس Fifth Generation Programming Languages

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

خلال ثمانينات القرن الماضي ومع تطور مجال الذكاء الاصطناعيّ Artificial Intelligence ظهرت فكرةٌ جديدة في مجال البرمجة: البرمجة المقيدة Constraints-based Programming، والتي تتلخص فكرتها بأن هدف البرمجة ليس كتابة الخوارزميات، بل تزويد البرنامج بعددٍ من الشروط والظروف المرتبطة بمشكلةٍ معينة، ومن ثم سيقوم البرنامج وحده بالعمل من أجل إنجاز المهمة المطلوبة وفقًا للظروف والشروط التي تم إدخالها إليه، أي أن لغة البرمجة نفسها عبارة عن آلة مخصصة لحل المشاكل أو إنجاز المهمات المرتبطة بمجالٍ ما. تُعتبر لغات OPS5 و Mercury من الأمثلة الشهيرة على لغات الجيل الخامس.

4. مفهوم نماذج البرمجة Programming Paradigm

بعيدًا عن المرحلة الزمنية التي ظهرت عبرها لغات البرمجة والتي تم استخدامها كوسيلةٍ لتقسيم لغات البرمجة إلى أجيالٍ مختلفة، فإن إحدى الطرق الشائعة التي يتم عبرها التفريق بين لغات البرمجة هي بحسب “إطار البرمجة” المستخدم.

للتوضيح، فإن البرمجة لا تقتصر فقط على كتابة النصوص Syntax باستخدام لغات البرمجة، فبغياب المعنى Semantics لن يمتلك البرنامج أي قيمة، وعندما نقول هنا “المعنى” فالمقصود هو الغاية المرجوة من البرنامج وكيفية الوصول لهذه الغاية. هكذا إذًا يمكن فهم البرمجة على أنها عملية تطوير خوارزميات قابلة للفهم من قبل الحاسوب لحل المشاكل المختلفة، وبما أنه يمكن حل أي مشكلة باستخدام العديد من الطرق، كذلك يمكن كتابة البرامج باستخدام مناهج وأطر مختلفة. الإطار البرمجيّ إذًا هو “الفلسفة” المتبعة بكتابة البرامج باستخدام لغات البرمجة، أو لنقل المنهجية الأساسية التي تستند إليها اللغة ويتوجب على المبرمج اتباعها أثناء كتابته للبرامج.

بشكلٍ عام، فإنه يمكن تقسيم الأطر البرمجية، أي المنهجية المستخدمة في كتابة البرامج، إلى الأقسام التالية:

  • البرمجة الحتمية Imperative Programming: بهذا النمط من البرمجة يقوم المبرمج بإخبار الآلة (المعالج) بطريقة وكيفية تنفيذ الخوارزمية المطلوبة لحل المشكلة، أي أن المبرمج سيقوم بتحديد خطوات حتمية وأكيدة سيتم عبرها الوصول للنتيجة المطلوبة. يمكن تقسيم البرمجة الحتمية بدورها إلى قسمين أساسيين: البرمجة الإجرائية Procedural Programming والبرمجة غرضية التوجه Object-Oriented Programming. تعني البرمجة الإجرائية قيام المبرمج بتجميع التعليمات ضمن “إجراءاتٍ Procedures” متنوعة تفضي بالنتيجة للوصول للغاية المطلوبة. هذه الإجراءات قد تكون التصريح عن توابع أو استخدام بنى التحكم مثل الحلقات التكرارية أو البنى الشرطية. بالنسبة للبرمجة غرضية التوجه، فهي تعني قيام المبرمج باستخدام “الأغراض Objects” والعلاقات فيما بينها من أجل تنفيذ الخوارزمية. الأغراض عبارة عن كائنات برمجية تتيح تضمين العديد من الأمور ضمن بنية واحدة، مثل تضمين التوابع، بنى التحكم، بنى المعطيات، المتحولات جميعها ضمن غرضٍ ما. بكل الأحوال، التفصيل بماهية البرمجة غرضية التوّجه وكيفية عمل الأغراض وعلاقاتها مع بعضها البعض هو خارج إطار هذا المقال.
  • البرمجة التفسيرية (التصريحية) Declarative Programming: يهدف هذا النموذج البرمجيّ بشكلٍ أساسيّ إلى كتابة وتطوير البرامج التي يمكن عبرها توصيف النتيجة أو الغاية المطلوب الوصول إليها بدون تحديد الخطوات أو التعليمات الواجب اتباعها للوصول للنتيجة. بشكلٍ مشابه للبرمجة الحتمية، هنالك عدد من الأطر الفرعية التي تندرج تحت البرمجة التفسيرية، وهي البرمجة الوظيفية Functional Programming المعتمدة بأساسها على حسابات توابع رياضية، وهي طريقة غير مرتبطة بأي لغة برمجة أي يمكن استخدامها ضمن لغاتٍ مختلفة، وهكذا أصبحت بعض اللغات الحتمية مثل ++C تدعم إطار البرمجة الوظيفية بدءًا من إصدار 11 ++C، وبعيدًا عن ذلك، فإن لغة جافاسكريبت JavaScript هي إحدى أشهر لغات البرمجة التي تدعم نموذج البرمجة الوظيفية. تتضمن البرمجة التفسيرية أطر ومناهج أخرى هي البرمجة المنطقية Logic Programming وبرمجة قواعد البيانات Database مثل لغة SQL.

على الرّغم من استخدام الأطر السابقة كوسيلةٍ لتصنيف لغات البرمجة، إلا أن البعض يُجادل بأنه من غير المنطقيّ وضع مثل هكذا تصنيفات، فقد تدعم لغة برمجة واحدة عدة أطر وطرق برمجية بنفس الوقت، مثل ++C التي تحصل على دعمٍ متزايد للعديد من الطرق عبر إصداراتها المختلفة، ولم يعد من الممكن اعتبارها تلك اللغة “الحتمية” التي نشأت في ثمانينات القرن الماضي. من ناحيةٍ أخرى، وبفضل اعتماد بعض اللغات على نماذج برمجة مختلفة، يتم تداول مصطلح “تعدد النماذج Multi-Paradigm” للإشارة للغات البرمجة التي يمكن أن يتم استخدامها لأغراضٍ مختلفة بفضل قدرتها على توفير طرق وآليات تنتمي لنماذج البرمجة المختلفة. من الأمثلة على هذه اللغات التي تندرج عادةً ضمن هذا التصنيف بايثون Python و #C.

5. المُترجمات والمُفسرّات Compilers and Interpreters

يمكن النظر للغات البرمجة وتصنيفها بحسب الآليات التي تستخدمها من أجل تنفيذ البرامج، وبشكلٍ رئيسيّ، يمكن تصنيف لغات البرمجة بهذا السياق إلى لغاتٍ مُترجمة Compiled Languages ولغاتٍ مُفسرّة Interpreted Languages.

ذكرنا سابقًا أن المعالج لا يفهم إلى لغة الآلة، أي اللغة الثنائية المكونة من سلاسل محددة من الأصفار والواحدات، وعند كتابة برنامج باستخدام أحد اللغات عالية المستوى، فإنه يجب نقل الشيفرة من صيغتها النصية التي إدخالها عبر أحد محررات النصوص إلى الصيغة الثنائية الرقمية التي يفهمها المعالج. تتولى برامج وسيطة مسؤولية إنجاز هذه المهمة، وهذه البرامج الوسيطة قد تكون “مترجمات Compilers” أو “مفسرّات Interpreters“.

يتلخص الفرق الأساسيّ بين المترجمات والمفسرات بمراحل تنفيذ البرنامج (الشيفرة المصدرية)، حيث تقوم المترجمات بإجراء مسحٍ للشيفرة المصدرية والتحقق من عدم أي وجود أي أخطاء، وفي حال غياب الأخطاء، سيتم توليد البرنامج التنفيذي Executable File القابل للتنفيذ من قبل المعالج. على الناحية الأخرى، لا تقوم المفسرّات بعملية مسحٍ للشيفرة المصدرية وإنما يتم تنفيذها مباشرةً بدءًا من أول تعليمة موجودة، وسيستمر تنفيذ البرنامج طالما أن المفسر لم يواجه أي خطأ. تعتبر لغات C و ++C من الأمثلة الشهيرة على اللغات المُترجمة، بينما تُعتبر لغات روبي Ruby وبايثون Python من الأمثلة الشهيرة على اللغات المُفسرّة.

اقرأوا أيضاً: ما هو الفرق بين المُترجم والمُفسّر في عالم لغات البرمجة؟ Compiler vs Interpreter

6. لغات توصيف العتاد Hardware Descriptive Languages

من بين كافة أنماط وأنواع لغات البرمجة المتوفرة والمستخدمة، تبرز عائلة فريدة من اللغات التي تختلف عن باقي أنماط لغات البرمجة من ناحية الفلسفة التي تتبعها والغاية المنشودة منها، وهنا نعني لغات توصيف العتاد HDL المستخدمة بشكلٍ أساسيّ في مجال برمجة المصفوفات الحقلية القابلة للبرمجة FPGAs.

عند كتابة برنامجٍ ما بإحدى لغات البرمجة عالية المستوى الشهيرة يعرف المبرمج مسبقًا ما هي مواصفات العتاد الصلب الذي سيتولى مسؤولية تنفيذ البرنامج: عدد أنوية المعالجة، سرعة الأنوية، حجم الذاكرة العشوائية، سعة التخزين، عدد المغارز الممكن استخدامها كمنافذ دخل/خرج، منافذ الحساسات، منافذ الاتصال التسلسليّ…إلخ. بهذه الصورة، فإن البرنامج سيكون مقيدًا بالعتاد المتوّفر، كما أن المبرمج لا يستطيع أن يغيّر شيئًا من طبيعة العتاد نفسه، بل عليه أن يتعامل معه كما هو.

بالنسبة للغات توصيف العتاد فإن الأمر مختلف: هدف هذه اللغات هو “إنشاء Synthesize” العتاد الصلب الذي سيتولى إنجاز مهمةٍ ما، وسيكون دور المبرمج هنا هو ليس فقط كتابة خوارزمية البرنامج، بل أيضًا توصيف الوحدات التي ستتولى تنفيذ الخوارزمية. لو أخذنا مثالًا شهيرًا مثل خوارزمية تعديل عرض النبضة PWM: Pulse Width Modulation، فإن البرنامج المكتوب بلغة مثل C على أحد المتحكمات الصغرية سيتطلب ضبط عددٍ من المسجلات الموجودة مسبقًا والمخصصة لهذه الوظيفة والتخاطب أيضًا مع المغارز Pins المخصصة لإرسال إشارة PWM. بحالة شريحة FPGA، على المبرمج أن يصف العدادات التي ستقوم بتوليد الإشارات الزمنية، ترددها، مصدر الساعة الخاصة بها، وكيفية توليد إشارة عرض النبضة اعتمادًا على عدادٍ زمنيّ. هذا البرنامج سيتم ترجمته إلى مسجلاتٍ ووحدات عتادية أخرى. الميزة الأساسية هنا أنه وبحالة المتحكمات الصغرية سيتوجب على المبرمج التقيد بحدود العتاد، فإذا كانت المؤقتات بدقة 8-بت ووجد أن برنامجه يتطلب مؤقتًا بدقة 10-بت عليه إيجاد حل برمجيّ لهذه المشكلة أو استخدام متحكم صغري آخر يوفر الدقة المطلوبة. بحالة شرائح FPGA وعبر استخدام لغات توصيف العتاد، سيستطيع المبرمج مباشرةً توصيف مؤقتٍ زمنيّ بدقةٍ قدرها 10-بت، وسيكون لاحقًا على تعديل دقته بما يتناسب مع التطبيق بدون الحاجة لتغيير العتاد.

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

تُعتبر لغات VHDL، Verilog و SystemVerilog من أشهر الأمثلة على لغات توصيف العتاد المستخدمة في مجال برمجة شرائح FPGAs.

7. أكثر لغات البرمجة شعبية Most Popular Programming Languages

على الرّغم من التشعب الكبير بأنواع وأنماط لغات البرمجة، وعلى الرّغم من توّفر العديد من اللغات المختلفة ضمن مجالاتٍ متنوعة، تتردد عدة أسماء على الدوام بفضل القدرات الكبيرة التي توّفرها وشتى المجالات التي يمكن استخدامها بها.

يوجد عدة معايير لتقييم لغات البرمجة بحسب شعبيتها وانتشارها، ولعل أشهرها هو التقييم السنويّ الذي تصدره شركة TIOBE الخاص بشعبية لغات البرمجة ومدى انتشارها بين المبرمجين حول العالم، أو تقييم مجلة IEEE Spectrum، وعلى الرّغم من بعض الاختلافات، إلا أنه يمكن عبر التقييمين معرفة أهم 10 لغات برمجة مستخدمة في الوقت الحاليّ.

بحسب تقييم TIOBE لشهر يناير/كانون الثاني لعام 2020، فإن أكثر لغات البرمجة شعبيةً هي:

  1. لغة جافا وبانتشارٍ قدره 16.8%
  2. لغة C وبانتشارً قدره 15.7%
  3. لغة بايثون وبانتشارٍ قدره 9.7%
  4. لغة ++C وبانتشارٍ قدره 5.5%
  5. لغة #C وبانتشارٍ قدره 5.3%
  6. لغة Visual-Basic .NET وبانتشارٍ قدره 5.28%
  7. لغة جافاسكريبت JavaScript وبانتشارٍ قدره 2.45%
  8. لغة PHP وبانتشارٍ قدره 2.4%
  9. لغة سويفت Swift وبانتشارٍ قدره 1.79%
  10. لغة SQL وبانتشارٍ قدره 1.5%

بحسب تقييم مجلة IEEE Spectrum لعام 2019 الذي يعطي كل لغة علامةً من 100، فإن أكثر لغات البرمجة شعبيةً هي:

  1. لغة بايثون بتقييمٍ قدره 100
  2. لغة جافا بتقييمٍ قدره 96.3
  3. لغة C بتقييمٍ قدره 94.4
  4. لغة ++C بتقييمٍ قدره 87.5
  5. لغة R بتقييمٍ قدره 81.5
  6. لغة جافاسكريبت بتقييمٍ قدره 79.4
  7. لغة #C بتقييمٍ قدره 74.5
  8. لغة ماتلاب Matlab بتقييمٍ قدره 70.6
  9. لغة سويفت Swift بتقييمٍ قدره 69.1
  10. لغة جو Go بتقييمٍ قدره 68

هنالك بعض المعايير الأخرى التي يأخذها بعض المطورين بعين الاعتبار، مثل عدد الأسئلة والمشاركات المتعلقة بإحدى لغات البرمجة على منصات التطوير التفاعلية مثل Stack Overflow أو منصة GitHub. بكل الأحوال، وبنظرةٍ سريعة على مختلف التقييمات، يمكن القول أن أكثر لغات البرمجة استخدامًا وانتشارًا في الوقت الحاليّ هي بايثون Python المستخدمة بشكلٍ كبير في تطبيقات تحليل البيانات، الذكاء الاصطناعيّ وتطوير الويب. جافاسكريبت JavaScript هي إحدى اللغات واسعة الانتشار خصوصًا بمجال تطوير الويب، تطبيقات الأجهزة الذكية والتطوير بمجال Backend. جافا Java من اللغات عالية المستوى القديمة (نسبيًا) التي لا تزال تحظى بزخمٍ وشعبيةٍ كبيرتين بسبب الاعتمادية الكبيرة عليها بمجال تطوير تطبيقات الهواتف الذكية العاملة على هواتف أندرويد، فضلًا عن استخدامها بمجال تطوير الويب وتطبيقات الشركات والبيانات الضخمة Big Data. بالنسبة للاعبين الجدد، فإن لغة #C الخاصة بمايكروسوفت هي إحدى اللغات متزايدة الشعبية والمستخدمة في مجال البرمجة من ناحية المخدم Server-Side Programming، تطوير التطبيقات، تطوير الويب، تطوير الألعاب والبرامج والخدمات العاملة على نظام تشغيل ويندوز. بالعودة للغات القديمة، فإن لغة سي C هي إحدى اللغات الكلاسيكية التي لا تزال حاضرة بقوة في مجال البرمجة وذلك بفضل استخدامها الكبير بمجال تطبيقات إنترنت الأشياء IoT وأنظمة التشغيل بالزمن الحقيقي Real-Time Operating Systems، فضلًا عن كونها العمود الفقريّ لبرمجة الأنظمة المدمجة Embedded Systems والأهم استخدامها الكبير بمجال برمجة أنظمة التشغيل System Programming، وبنفس السياق، فإن لغة سي بلس بلس ++C التي ظهرت أساسًا لتكون نسخةً أوسع وأشمل وبقدراتٍ أكبر من C هي إحدى اللغات الكلاسيكية التي لا تزال حاضرة بقوة بفضل قدرتها على دعم عددٍ كبير من التطبيقات والمجالات، إلا أن مجالات استخدامها الأساسية تشابه إلى حدٍ كبير مجالات استخدام C وهي برمجة الأنظمة المضمنة، برمجة أنظمة التشغيل واستخدامها بمجال إنترنت الأشياء وأنظمة الزمن الحقيقي، وبالإضافة إلى ذلك، فهي أيضًا مستخدمة بمجالات تعلم الآلة والتعلم العميق.

مقالات ذات صلة

‫21 تعليقات

زر الذهاب إلى الأعلى