الفصل الرابع

فن البرمجة وعلمها وهندستها

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

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

البرامج أدوات حدية

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

إذن، البرامج لها وجه مجرَّد وآخر مادي، ولذلك نقول إنها أدوات حدية. وتبعات هذه الحدية كبيرة ومثيرة للجدل على حد سواء.

أولًا، ينجذب البعض من أوساط علم الكمبيوتر إلى فكرة التجريد في البرامج ويرون أن البرامج كائناتٌ «رياضية». في نظرهم، البرمجة نوع من الأنشطة الرياضية التي تتضمن المسلَّمات والتعريفات والمبرهنات والبراهين. ويشدِّد علماء كمبيوتر آخرون على جانبها المادي ويرون أن البرامج كائناتٌ «تجريبية». ففي نظرهم، البرمجة نشاطٌ هندسي تجريبي يتضمن المهام الهندسية العادية، مثل تحديد المتطلبات والتصميم والتنفيذ وإجراء التجارب التي تختبر الأدوات الناتجة وتُقيِّمها.

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

في واقع الأمر، تأثَّرت الدراسات العلمية لعملية المعرفة أو الإدراك تأثرًا كبيرًا بتشبيه العقل بالبرامج. ومن تبِعات هذا التأثر تطويرُ فرع من فروع علم الكمبيوتر يسمَّى «الذكاء الاصطناعي»، يحاول إنشاء أدوات حوسبية تشبه العقل وتشبه الدماغ. ومن التبِعات أيضًا تحويلُ علم النفس المعرفي إلى مجالٍ أشملَ يسمَّى «العلوم المعرفية»، من الفرضيات الجوهرية فيه أنه يمكن تصميمُ العمليات العقلية في صورة عمليات حوسبية على غرار البرامج.

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

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

الخوارزميات + لغات البرمجة = البرامج

يترتَّب على هذه الصيغة في حد ذاتها عدة نتائج.

إحدى هذه النتائج نشوء نظرية لغات البرمجة باعتبارها فرعًا من فروع علم الكمبيوتر. وقد أدَّى هذا حتمًا إلى نشوء علاقة بين هذه النظرية وعلم اللغويات الذي يهتم بتراكيب اللغة الطبيعية.

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

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

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

ويوضح الشكل ٤-١ بطريقة تخطيطية العلاقات العديدة التي بين البرامج والبرمجة وبين تلك الكيانات والمجالات العلمية الأخرى. الكيانات المكتوبة داخل الأشكال المستطيلة مجالاتُ مساهمة من خارج علم الكمبيوتر؛ والكيانات المكتوبة في الأشكال البيضاوية مجالاتٌ تندرج تحت علم الكمبيوتر.
fig3
شكل ٤-١: البرمجة وما يرتبط بها من فروع من داخل علم الكمبيوتر وعلوم من خارجه.

اللغة والفكر والواقع والبرمجة

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

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

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

لذا، لنتناول لغات البرمجة أولًا. أما طبيعة البرامج فستبرز بصورة طبيعية من هذه المناقشة.

لغات البرمجة كأدوات مجردة

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

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

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

في هذا الفصل وما بعده من فصول إلى نهاية الكتاب، يشير مصطلح «لغة البرمجة» إلى اللغات العالية المستوى ما لم يُذكر غير ذلك صراحةً.

وعلى خلاف اللغات الطبيعية، لغاتُ البرمجة لغاتٌ مبتكرة أو مُصمَّمة. ومن ثَم فهي أدوات. وتنطوي على استخدام الرموز. وكما سنرى، لغة البرمجة هي فعليًّا مجموعةٌ من البنيات الرمزية، وهي أدوات مجردة — كونها مستقلة عن أجهزة الكمبيوتر المادية — بالمعنى ذاته مثل الخوارزميات. ومن ثَم يكون لدينا وضعٌ مثير للتساؤل؛ ففي حين أن البرامج المكتوبة بهذه اللغات حدية، فإن لغات البرمجة ذاتها مجردة.

اللغة = ترميز + مفاهيم وفئات

لنراجع الفرْق بين الترميز واللغة. يزخر مجال الحوسبة بمئات اللغات الحوسبية. صُمِّمت غالبية هذه اللغات من أجل البرمجة، ولكن توجد لغات مخصَّصة لأغراض أخرى، لا سيما أغراض تصميم ووصف أجهزة الكمبيوتر المادية بمستويات التجريد المتنوعة (انظر الفصل الخامس). ويطلق عمومًا على هذه اللغات «لغات وصف عتاد الكمبيوتر» أو «لغات تصميم أجهزة الكمبيوتر ووصفها».

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

مفاهيم/فئات + ترميز = لغة

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

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

المفاهيم والفئات في لغات البرمجة

إذن ما هي تلك المفاهيم والفئات؟ تذكُر أن الحوسبة معالجةٌ للرموز؛ أو معالجةُ المعلومات بتعبيرٍ أكثر شيوعًا. «البداية هي المعلومات» — أو البيانات كما يحب أن يسميَها مصمِّمو اللغة — المراد معالجتها. ومن ثَم فإن المفهوم الأساسي المضمَّن في جميع لغات البرمجة هو ما نطلق عليه نوع البيانات. وكما ذكرنا في الفصل الأول، يحدِّد نوع البيانات طبيعةَ القيم التي يحتفظ بها عنصر البيانات (وإلا سمِّي متغيرًا)، بالإضافة إلى العمليات المسموح بأدائها على هذه القيم. أنواع البيانات إما «أولية» (أو أساسية) أو «مركَّبة» (أو مجمَّعة)، حيث إنها تتركب من أنواع بيانات أساسية أكثر.

في مثال المضروب المذكور في الفصل الثالث، لا يوجد سوى نوع البيانات الأولي «الأعداد الصحيحة غير السالبة»، وهذا يعني أن الأعداد الصحيحة الأكبر من أو تساوي صفرًا هي قيمٌ مقبولة للتعبير عن متغيرات هذا النوع، والعمليات الحسابية على الأعداد الصحيحة هي وحدها التي يمكن تنفيذها على متغيرات هذا النوع. وهذا يعني أيضًا أنه لا يمكن تعيين غير القيم الصحيحة لمتغيرات هذا النوع. على سبيل المثال، عبارة تعيين مثل الآتية:

تكون عبارة مقبولة إذا كان المتغير معرفًا بحيث يكون نوع بياناته الأعداد الصحيحة. وإذا لم يُعرف المتغير على هذا النحو، أو إذا عُرف (مثلًا) بأنه سلسلة رموز (تمثل اسمًا ما)، فسيكون التعيين غير مقبول.
وليس بالضرورة أن يكون العدد نفسه عددًا صحيحًا ما لم يُعرف بهذا النحو. إذن من المنظور الحوسبي، رقم الهاتف ليس عددًا صحيحًا؛ بل هو سلسلة رموز رقمية؛ فليس بإمكان المرء جمْع رقمَي هاتفين أو ضربهما. ومن ثَم إذا عُرف المتغير بأنه سلسلةُ رموز رقمية، فإن عبارة التعيين السابقة لن تكون صالحة.
تحتوي خوارزمية البحث الخطي المذكورة في الفصل الثالث على أنواع بيانات أولية ومركَّبة. فالمتغير من النوع الأوَّلي «الأعداد الصحيحة»، أما المتغير given فمن النوع المركَّب «سلسلة الرموز»، الذي هو ذاته مؤلَّف من النوع الأولي «الرموز». وقائمة الطلاب student أيضًا ذات نوع بيانات مركَّب، ويطلق عليها في بعض الأحيان «قائمة خطية» وفي أحيانٍ أخرى «مصفوفة». والعنصر الذي ترتيبه من القائمة student له أيضًا نوع بيانات مركَّب (والذي يُطلق عليه أسماء مختلفة في لغات البرمجة المختلفة، منها «السجل» و«الصف») ويتألف هنا من نوعَي بيانات؛ الأول (name) من نوع سلسلة الرموز، والآخر (email) أيضًا من نوع سلسلة الرموز. إذن متغير مثل student عبارة عن «بنية بيانات» مرتَّبة هرميًّا؛ أي، رموز منظَّمة في شكل سلاسل رموز، وسلاسل رموز منظمة في شكل صفوف أو سجلات، وصفوف منظمة في شكل قوائم أو مصفوفات.

لكن البيانات أو المعلومات ليست سوى بداية أي عملية حوسبة. إضافة إلى ذلك، المتغيرات نفسها سلبية. فالحوسبة تتضمن إجراءات، وتضمين هذه الإجراءات في عمليات. ومن ثَم يجب ألا تتضمنَ لغة البرمجة وسيلةً لتحديد عناصر البيانات فحسب، بل يجب أن تتضمن أيضًا «عبارات» تحدِّد الإجراءات والعمليات.

في الحقيقة، صادفنا بالفعل ولعدة مرات «أنواع» العبارات الأكثر جوهرية في الفصل السابق. أحد هذه الأنواع هو عبارة التعيين التي يستدعي تنفيذها عمليةً تتضمن كلًّا من الاتجاه والتدفق الزمني للمعلومات. على سبيل المثال، في تنفيذ عبارة التعيين:

حيث و عبارة عن متغيرين، تتدفَّق المعلومات من إلى . ولكنه ليس كتدفُّق المياه من وعاء إلى آخر. فقيمة لا تتغير ولا تقل ولا تفرُغ بعد تنفيذ هذه العبارة. بل إن قيمة «تُقرأ» و«تُنسخ» إلى بحيث تتساوى قيمة مع قيمة في النهاية. لكن في تنفيذ العبارة:
تتغير قيمة بالفعل، حيث إن قيمة الجديدة تساوي قيمة القديمة مضافًا إليها قيمة . لكن قيمة تبقى من دون تغيير.

الصيغة العامة لعبارة التعيين هي:

حيث «تعبيرٌ» (مثل التعبيرات الرياضية ، و ). وبوجه عام، تنفيذ هذه العبارة يكون بعملية مكوَّنة من خطوتين: أولًا، يجري تقدير ؛ ثم تعيَّن هذه القيمة إلى .

إذن تحدد عبارة التعيين وحدةَ الإجراء في العملية الحوسبية. إنها بمثابة العملية الأولية في العمليات الحوسبية. لكن مثلما تلتحم الذرات في العالم الطبيعي لتكوِّن الجزيئات وتلتحم الجزيئات لتكوِّن جزيئاتٍ أكبر، تحدث عملية مشابهة في عالم الحوسبة. إذ تلتحم عبارات التعيين لتكوين مقاطعَ أكبر، وتتَّحد المقاطع لتكوين مقاطع أكبر إلى أن نحصل على برامج كاملة. ثمة تسلسل هرمي موجود في العالم الحوسبي، كما هو موجود في الطبيعة.

من ثَم كانت أكبر مهمة لدى علماء الكمبيوتر هي اكتشاف «قواعد التركيب»، وابتكار أنواع عبارات تمثِّل هذه القواعد، وتصميم ترميزات لكل نوع من أنواع العبارات. وفي حين أن قواعد التركيب وأنواع العبارات يمكن أن تكون عامة إلى حد كبير، يمكن للغات البرمجة المختلفة أن تستخدم ترميزات مختلفة لتمثيلها.

من أنواع العبارات العبارة «التسلسلية»؛ وتعني تركيب عبارتين أو أكثر (أبسط) تركيبًا تسلسليًّا بحيث يتم تنفيذهما حسب ترتيب العبارات المكوَّنة. الرمز الذي استخدمته في الفصل الثالث للإشارة إلى التسلسل هو الفاصلة المنقوطة «;». ومن ثَم، نجد العبارة التسلسلية التالية في خوارزمية إقليدس:

وفيها يتقدَّم تدفُّق التحكم عبْر العبارات الثلاث حسب الترتيب الموضَّح.

لكن قد تتطلب العمليات الحوسبية أيضًا الاختيار من بين عدة بدائل. وعبارات if…then…else التي استخدمناها في الفصل الثالث في عدة خوارزميات هي أمثلة على نوع العبارات «الشرطية» في لغات البرمجة. في الصيغة العامة يتم تقييم الشرط وإذا كان صحيحًا، ينتقل التحكم إلى ، وإلا تدفَّق التحكم إلى .
ونحتاج في بعض الأحيان إلى إعادة تدفُّق التحكم إلى جزء سابق من العملية الحوسبية وتكراره. ويُعَد الترميزان while…do وrepeat…until في خوارزمية البحث الخطي وخوارزميات المضروب غير ذاتية الاستدعاء في الفصل الثالث كأمثلة على نوع عبارات «التكرار».
أنواع العبارات الثلاث هذه — التسلسلية والشرطية والتكرارية — أسسٌ لإنشاء البرامج. وتوفِّر كل لغة برمجة ترميزًا لتمثيل هذه الفئات. في الحقيقة ومن حيث المبدأ، يمكن تحديد أي عملية حوسبية ببرنامج يحتوي على مزيج من أنواع العبارات الثلاث هذه. (في عام ١٩٦٦، هذا الأمر أثبته مُنظِّرا علم الكمبيوتر الإيطاليان كورادو بوم وجوسيبي جاكوبيني.) ومن المنظور العملي، طُرح العديد من قواعد التركيب وأنواع العبارات المقابلة لتسهيل البرمجة (مثل «التفريع غير الشرطي» الذي تمثِّله عبارة goto المستخدَمة في خوارزمية إقليدس الواردة بالفصل الثالث).

البرمجة باعتبارها فنًّا

البرمجة عمليةُ تصميم، ومثل كل أنشطة التصميم، تنطوي على حسن التقدير والحَدْس والذوق الجمالي والخبرة. ولهذا السبب وضع دونالد كنوث العنوان «فن برمجة الكمبيوتر» لسلسلة أفروداته الشهيرة والمؤثِّرة (التي ظهرت فيما بين عامي ١٩٦٨ و١٩٦٩). وبعد عَقد تقريبًا، أوضح كنوث رأيه في هذا الموضوع في إحدى محاضراته. كتب أنه عندما يأتي الحديث عن فن البرمجة، فإنه يشير إلى البرمجة على أنها «ضربٌ من ضروب الفن». ينبغي أن تُشبع البرامج الذوقَ الجمالي؛ إذ ينبغي أن تكون جميلة. وتجربة كتابة برنامج ينبغي أن تشبه نَظم قصيدة أو تلحين مقطوعة موسيقية. ومن ثَم، فإن فكرة «الأسلوب» — وهي جزء وثيق الصلة بسياقات الفن والموسيقى والأدب — يجب أن تكون عنصرًا من مظاهر الجمال في البرمجة. ولنتذكر مقولةَ عالِم الكمبيوتر الهولندي إدسخر ديكسترا المذكورة في الفصل الثالث: في ابتكار الخوارزميات، «الجمال هو ما نسعى إليه». وقد عبَّر عالِم علم الكمبيوتر الروسي إيه بي يرشوف عن وجهة نظر مشابهة.

وفي إطار هذا الموضوع، اقترح كنوث في وقتٍ لاحق أنه ينبغي بالبرامج أن تندرج ضمن «الأعمال الأدبية»؛ بمعنى أن يستمتع المبرمج بكتابة البرامج وأن تمنح هذه البرامج البهجةَ لدى قراءة الآخرين لها. (أطلق كنوث على هذه الفلسفة اسم «البرمجة المتعلمة»، وإن كنتُ أعتقد أن «البرمجة الأدبية» ستكون أليقَ للتعبير عن رأيه.)

البرمجة كعلم رياضي

بالطبع يسعى علماء الكمبيوتر (بمن فيهم كنوث) إلى اكتشافِ أسسٍ صورية وموضوعية أكثر للبرمجة. فهم يبتغون علمًا للبرمجة. والنتيجة التي توصَّل إليها كلٌّ من بوم وجاكوبيني والتي سبق ذكرها هي نوع من النتائج الرياضية الصورية التي يتوق إليها علماء الكمبيوتر. وفي الحقيقة، يرى كثير من علماء الكمبيوتر أن «علم» البرمجة علمٌ «رياضي».

رؤية البرمجة باعتبارها علمًا رياضيًّا تجلَّت بشكل بارز بثلاث طرق أخرى تتعلق جميعها بالوجه المجرَّد للبرامج أو — كما أشرت مسبقًا في هذا الفصل — بوجهة النظر التي يتبناها البعض بأن البرامج كائناتٌ رياضية.

المساهمة الأولى في علم البرمجة هي اكتشاف «قواعد التركيب اللغوي» في لغات البرمجة. تلك قواعد تحدِّد السلامة النحوية في البرامج ولها تأثير عملي ضخم، حيث إن من أوائل مهام البرامج المترجِمة (التي تحوِّل البرامج العالية المستوى تلقائيًّا إلى لغة آلة) هي التأكد من سلامة النحو أو التركيب في البرامج التي تترجمها. وترجع بدايات ظهور نظرية التركيب اللغوي في لغات البرمجة إلى جهودِ عالِم اللغويات نعوم تشومسكي في نظرية التركيب اللغوي (في اللغات الطبيعية).

المساهمة الثانية في علم البرمجة هي تطوير «قواعد الدلالة»؛ وهي المبادئ التي تحدِّد معنى أنواع العبارات المختلفة. ويجب أن تكون أهميتها واضحة؛ فمن أجل استخدام لغة البرمجة لا بد أن يكون المبرمج على وعي تامٍّ بمعاني أنواع العبارات المكوِّنة لهذه اللغة. وكذلك، يجب أن يفهم كاتب البرنامج المترجِم ومن دون لبسٍ معنَى كل نوع من أنواع العبارات من أجل أن يترجم البرامج إلى لغة آلة. ولكن الدلالة، حسب معناها المستخدَم في علم اللغويات، تُعَد مشكلة شائكة حيث إنها تتضمن ربط فئات لغوية بما تشير إليه في العالم، ونظرية الدلالة في لغات البرمجة تعكس هذه الصعوبات ذاتها. ومن المناسب أن نقول إن نظرية الدلالة في البرمجة — على الرغم من صياغتها المتطورة — لم تلقَ القبول ذاته في أوساط علم الكمبيوتر ولم تُستخدم بقدْر الفاعلية ذاته مثل نظرية التركيب اللغوي.

المساهمة الثالثة في علم البرمجة ترتبط ارتباطًا وثيقًا بقضية الدلالة. قامت هذه المساهمة على قناعة علماء كمبيوتر أمثال الإنجليزي سي إيه آر هور والهولندي إدسخر ديكسترا بأن الحوسبة شبيهة بالرياضيات، وأنه يمكن تطبيق المبادئ ذاتها التي يستخدمها علماء الرياضيات — مثل المسلَّمات وقواعد المنطق الاستنتاجي والمبرهنات والبراهين — على البرمجة. وقد صاغ هور هذه الفلسفة صياغةً صريحة وجريئة؛ حيث أعلن عام ١٩٨٥ البيان التالي:
  • (أ)
    أجهزة الكمبيوتر آلات رياضية. بمعنى أنه يمكن تحديد سلوكها رياضيًّا ويمكن اشتقاق كل تفصيلة من التعريف اشتقاقًا منطقيًّا.
  • (ب)
    البرامج تعبيرات رياضية. فهي تصف بدقة وبالتفصيل سلوك الكمبيوتر الذي تنفَّذ عليه.
  • (جـ)
    لغة البرمجة نظرية رياضية. فهي نظام صوري يساعد المبرمج في كل من تطوير البرنامج، وكذلك إثبات أن البرنامج يستوفي مواصفات متطلباته.
  • (د)
    البرمجة نشاط رياضي. ممارسة البرمجة تتطلب تطبيقَ الطرق التقليدية في الفهْم والإثبات الرياضي.

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

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

البرمجة كهندسة (برمجيات)

البرمجة ضربٌ من ضروب الهندسة نظرًا لأن الكثيرين يرون أن البرامج ليست مجرد أدوات جميلة مجردة وحسب. فحتى هور في بيانه يقرُّ بأن البرامج يجب أن تصف سلوك «أجهزة الكمبيوتر» التي تنفِّذها. فأجهزة الكمبيوتر هي الوجه المادي للبرامج وهي التي تضفي عليها صفةَ الحدية. وفي نظر الكثيرين في واقع الأمر، البرامج منتجاتٌ تكنولوجية، ومن ثَم تصبح البرمجة نشاطًا هندسيًّا.

يبدو أن كلمة «برمجيات» دخلت إلى مفردات الحوسبة عام ١٩٦٠. لكن تبقى دلالاتها غيرَ محدَّدة. فالبعض يستخدمون كلمتي «برمجيات» و«برنامج» على أنهما مترادفتان. ويعتقد البعض أن البرمجيات تعني مجموعةَ البرامج الخاصة والضرورية (مثل أنظمة التشغيل والأدوات و«الأدوات المساعدة» الأخرى التي يطلق عليها مجتمعة «برامج النظام») المصمَّمة لتعمل على كمبيوتر مادي لإنشاء أجهزة افتراضية (أو أنظمة كمبيوتر) يمكن للآخرين استخدامها بمزيد من الكفاءة (ارجع إلى الشكل ٢-١ في الفصل الثاني). لكن لا يزال آخرون يعتقدون أن البرمجيات لا تعني البرامج فحسب، بل معها التوثيق ذو الصلة الذي هو ضروري من أجل تطوير البرامج الكبيرة وتشغيلها وصيانتها وتعديلها. وهناك البعض ممن يدرجون في هذا الإطار المعرفة والخبرة البشرية.

على أية حال، «البرمجيات» لها الدلالات المهمة التالية: إنها ذلك الجزء من نظام الكمبيوتر الذي لا يعتبر ماديًّا؛ وهي تتطلب وجودَ الكمبيوتر المادي لتشغيلها؛ وهناك ما يدُل على أنها منتج «صناعي» إلى حد كبير، بكلِّ ما تدل عليه الصفة.

إذن، فالبرمجيات أداةٌ حوسبية تسهِّل على العديد من المستخدمين (ربما الملايين أو المليارات) استخدامَ أنظمة الكمبيوتر. وفي أغلب الأحيان (وإن لم يكن على الدوام) تكون البرمجيات أداةً منتجة تجاريًّا تُظهر مستويات معينة من الدقة والموثوقية التي أصبحنا نتوقَّعها من الأنظمة الصناعية.

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

وقد طُرحت نماذج مختلفة لدورة حياة البرمجيات على مدار الخمسين عامًا الماضية. وبوجه عام، تقرُّ جميعها بأن تطوير نظام البرمجيات يتضمن عددًا من المراحل:
  • (أ)

    تحليل المتطلبات التي تهدُف البرمجيات إلى استيفائها.

  • (ب)

    تحديد المواصفات الدقيقة للوظائف والأداء والتكلفة لمختلف المكونات («الوحدات») التي يمكن تحديدها من تحليل المتطلبات.

  • (جـ)

    تصميم نظام البرمجيات الذي (يُرجى) أن يلبي المواصفات. وهذا النشاط قد يتكوَّن في ذاته من مراحل تصميم مفاهيمية ومفصلة.

  • (د)

    تنفيذ التصميم باعتباره نظامَ برمجيات تشغيليًّا محددًا بلغة برمجة وتجميعه للتنفيذ على نظام (أنظمة) الكمبيوتر المستهدف.

  • (هـ)

    التحقق والتثبُّت من مجموعة البرامج المنفَّذة لضمان أنها تستوفي المواصفات.

  • (و)

    بمجرد إتمام عمليتي التحقُّق والتثبُّت، تأتي صيانة النظام، وتعديله إذا لزم الأمر ووقتما يلزم.

بالطبع لا تتوالى هذه الخطوات بطريقة خطية صارمة. فدائمًا هناك احتمال الرجوع إلى مرحلة سابقة من مرحلة متقدمة إذا اكتُشفت عيوب وأخطاء. إضافة إلى ذلك، تتطلب دورة حياة البرمجيات أيضًا بنيةً أساسية — من الأدوات والمنهجيات ومعايير التوثيق والخبرة البشرية، وهذه العناصر مجتمعة تكوِّن «بيئة» هندسة البرمجيات.

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

جميع الحقوق محفوظة لمؤسسة هنداوي © ٢٠٢٤