الخميس، 29 نوفمبر 2012

هيا نستخدم تعبيرات لامدا(1): الترتيب والمقارنة



 هب أن لدينا هذا الإجراء الذي يرتب مصفوفة من الأعداد (الإجراء بطيء لكنه بسيط بما يكفي للأهداف التعليمية):


إجراء رتب (م):
    لكل أ من 1 إلى عدد (م):
        لكل ب من أ + 1 إلى عدد (م):
            إذا م [أ] > م [ب]:
                مؤقت = م [أ]
                م [أ]= م [ب]
                م [ب]= مؤقت 
            تم 
        تابع 
    تابع 
نهاية 

م = [5، 12، 8، 4، 3، 9]
رتب (م)
اطبع م

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

الإجراء يأخذ عاملاً parameter هو المصفوفة 'م'، ماذا لو كان يأخذ عاملاً آخر هو الدالة التي يستخدمها في سطر المقارنة؟
إجراء رتب (م، دالة.المقارنة):
    لكل أ من 1 إلى عدد (م):
        لكل ب من أ + 1 إلى عدد (م):
            إذا دالة.المقارنة : تنفيذها (م [أ]، م [ب]):
                مؤقت = م [أ]
                م [أ]= م [ب]
                م [ب]= مؤقت 
            تم 
        تابع 
    تابع 
نهاية 

م = [5، 12، 8، 4، 3، 9]
رتب (م، λ س، ص : س > ص)
اطبع م

لقد قمنا بثلاث تغييرات صغيرة:
  1. أضفنا عاملاً هو دالة.المقارنة
  2. بدلاً من الاختبار م[أ] > م[ب]، جعلناه دالة.المقارنة: تنفيذها(م[أ]، م[ب])
  3. عند استدعاء الإجراء رتب، أعطيناه دالة مقارنة هي λ س، ص : س > ص، أي الدالة التي لو أخذت س و ص تعود بالقيمة س>ص (القيمة 'صحيح' أو 'خطأ' حسب نتيجة المقارنة).
 هذا البرنامج سيتصرف بالضبط مثل البرنامج السابق، لكن يمكننا أن نغيره كما نشاء باستخدام العامل الجديد! مثلاً من أجل الترتيب التنازلي، نقدم دالة مقارنة بالعلامة معكوسة λ س، ص : س < ص  .
ماذا لو أردنا ترتيب مصفوفة من الأشخاص حسب السن مثلاً؟ (اعتبر لدينا فصيلة اسمها "شخص" بها بيان اسمه "سن"). وقتها يكفي أن نقول هذا:

رتب (الأشخاص، λ أ، ب : سن أ > سن ب)


ماذا لو أردنا ترتيب الأشخاص حسب السن تنازلياً؟ يكفي تغيير العلامة في تعبير لامدا.

السبت، 24 نوفمبر 2012

تعبيرات لامدا في كلمات

تم إطلاق نسخة نوفمبر 2012 من لغة كلمات، وفيها أنواع جديدة من التعبيرات: الإجراء كذا، الدالة كذا. مثلاً لو قلت:

إجراء ترحيب( ):
    اطبع "مرحباً بك" 
نهاية 

دالة مجموع (أ ، ب):
    ارجع ب: أ + ب 
نهاية 

س = الإجراء ترحيب 
ص = الدالة مجموع

سوف تجد في المتغير س كائناً object يسمح لي باستدعاء الإجراء 'ترحيب' متى أردت. وكذلك ص يحمل وسيلة لاستدعاء الدالة 'مجموع' استدعيهما هكذا:
س : تنفيذها ( ) 
ب = ص : تنفيذها (5، 10)

السطر الأول يطبع الترحيب على الشاشة، والسطر الثاني يضع القيمة 15 في المتغير ب.

لماذا قلنا "س: تنفيذها( ) " في أول سطر بينما قلنا "ب = ص: تنفيذها(...)" في الثاني؟ لأن س تعبر عن إجراء بينما ص تعبر عن دالة.

الآن ما فائدة هذا الاسلوب في إيجاد قيم تعبر عن الإجراءات والدوال؟ هيا نضرب مثلاً ظريفاً:

دالة كلهم (المصفوفة ، الاختبار) :
    لكل أ من 1 إلى عدد (المصفوفة) :
        إذا ليس الاختبار : تنفيذها (المصفوفة [أ]) :
            ارجع ب: خطأ 
        تم 
    تابع 
    ارجع ب: صحيح 
نهاية 

دالة زوجي (ر) :
    ارجع ب: باقي.قسمة (ر، 2) = 0 
نهاية 

م = [2 ، 8 ، 6 ، 12] 

اطبع كلهم (م، الدالة زوجي)

ماذا فعلنا؟ الدالة كلهم تأخذ مصفوفة ودالة اخرى اختبارية (تعود بالقيمة صحيح أو خطأ)، وتقوم بتطبيق الدالة على كل قيمة في المصفوفة، بحيث لو عادت تلك الدالة بـصحيح لكل القيم، تعود الدالة الأم أيضاً بـصحيح، وإلا عادت بـخطأ.

والآن لم تعد تحتاج كتابة هذا الـ loop مرة أخرى للتأكد أن شرطاً ما ينطبق على كل القيم في مصفوفة!

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

لحظة...سطر واحد؟ ألم أضطر لكتابة الدالة زوجي في المثال السابق؟ هذا يجعل الموضوع يأخذ أكثر من سطر واحد للأسف :(

حسناً، في الواقع لم أكن أحتاج لذلك، لأن كلمات بها أيضاً تعبيرات لامدا (lambda expressions)، وهي طريقة لكي أعرف دالة بلا اسم في المكان الذي أريد فيه قيمة تعبر عن دالة.

أي أنه بدلا من "اطبع كلهم(م، الدالة زوجي)" كان يمكن أن أقول:

اطبع كلهم (م، λ أ : باقي.قسمة (أ، 2) = 0)

هذه هي صيغة الـ Lambda expression :

λ متغيرات:  تعبير ينتج منه قيمة

ومعناها "الدالة التي تأخذ هذه المتغيرات كعوامل وترجع بقيمة هذا التعبير". مثلاً λ س: س+1 هي الدالة التي لو أخذت س تعود بـ س+1.

(لكي تكتب علامة لامدا في محرر كلمات اضغط زر Ctrl + L، لو كنت تستخدم محرراً آخر يمكنك إدخال رمز ^ بدلاً من لامدا)

في مثال "كلهم" قد مررت للدالة "كلهم" دالة أخرى، هي "الدالة التي لو أخذت أ تعود بالقيمة باقي.قسمة(أ،2)=0"، وهو نفس الدور الذي تقوم به الدالة زوجي -- التي لم نعد نحتاج إليها.

هل تريد أن تتأكد أن المصفوفة م لا تحتوي صفراً؟ بسيطة:

اطبع كلهم.ليسوا ( م ، λ أ : أ = 0 )

نحن هكذا نحاول أن ندخل بكلمات إلى عصر جديد: عصر الـfunctional programming.

أليس هذا صعباً على الأطفال؟ من يدري؟ نحن لم نجرب بعد. وعلى كل حال إن ظهر أن تلك الإمكانية صعبة فلا بأس: يمكننا أن نتركها في اللغة لكن لا نلزم الأطفال بتعلمها، وباقي اللغة متاحة لهم كما هي. ومن أراد من الكبار (أو الأطفال القادرين) أن يتعلمها فهي موجودة.

الدوال التي تأخذ دوالاً أخرى كعوامل تسمى higher order functions. مثال آخر لمثل هذه الدوال هو الدالة تناظر:

م = [ 1 ، 2 ، 3 ، 4 ] 
اطبع تناظر ( م ، λ أ : أ × 2 )

هذه الكود سوف تطبع على الشاشة [2، 4، 6، 8] لأن تناظر تأخذ مصفوفة ودالة، وتعود بمصفوفة أخرى مليئة بقيم المصفوفة الأولى بعد تطبيق الدالة على كل منها. أي أن كل قيمة في المصفوفة القديمة لها قيمة مناظرة لها في المصفوفة الجديدة.

مثال آخر هو الدالة اختزال :
م = [ 1 ، 2 ، 3 ، 4 ] 
اطبع اختزال ( م ، λ أ ، ب : أ + ب )

الكود السابقة سوف تطبع على الشاشة القيمة 10، لأن اختزال تأخذ مصفوفة ودالة، ثم تقوم بطبيق الدالة "بين العناصر" كأني في المثال السابق حسبت 1+2+3+4. طبعاً كان يمكنني أن أقدم دالة ضرب بدلاً من الجمع لأحسب حاصل ضرب الأعداد في المصفوفة) أو دالة max لأحسب أكبر قيمة في المصفوفة..أو...أو...

الأسم "تناظر" هو ما أطلقته - في محاولة للتعريب - على الدالة المعروفة بإسم map، والدالة "اختزال" هي reduce.

ربما تكون قد سمعت عن MapReduce. إنها تكنولوجياً مبني عليها كثير من التطبيقات في شركات مثل:
  • Google
  •  Yahoo
  • Microsoft
  • Facebook
    ...وغيرهم. الـfunctional programming ليس كلاماً رياضياً نظرياً. إنه مهم للتكنولوجيا والتطوير.

    هل تريد أن نبني جوجل خاصة بنا في مجتمعنا؟ لغة كلمات بها البذور العلمية لذلك لغرسها في الأطفال.

    الأحد، 18 نوفمبر 2012

    عن كون كلمات لغة للأطفال، ولماذا لا تكون لغة احترافية

    هناك أكثر من شخص تحدث معي عن سبب إصراري أن تكون لغة كلمات لغة تعليمية وليست لغة لعمل برامج احترافية مثلها مثل Java, Python, ...الخ.

    هذا المقال سأقسمه إلى ثلاثة أجزاء:
    • الأسباب اللي تدعو لـ"حرفنة" كلمات.
    • ردي على بعض هذه الأسباب
    • متطلبات تحويل كلمات إلى لغة احترافية، لكي يكون الحوار واقعياً ويفهم القاريء الموضوع بالضبط.
    الرأي الآخر: لماذا لا تجعلها احترافية؟

    من الأسباب التي تدعو لجعل كلمات لغة احترافية:

    1. قد يكون هناك عائقاً نفسياً يمنع البعض من استخدام لغة للأطفال أو المبتدئين.
    2. ماذا سيفعل الأطفال (أو الكبار المبتدئين) بعد تعلم كلمات إن أرادوا عمل برامج احترافية؟
    3. ماذا عن حلم البرمجة باللغة العربية في كل مكان؟

    1- لن يحب أحد أن يستخدم لغة للمبتدئين: هذا جانب اجتماعي/تسويقي. هناك فئة من المبرمجين لا تحب إلا ما هو "قوي" و"احترافي". وهذا قد يدفع البعض لعدم استخدام كلمات لأنها "لعبة". هناك جانب آخر أجتماعي هو أن بعض العرب للأسف لا يرى أنه هناك منتج جيد يمكن أن يخرج من عقل مبرمج عربي، وبعض من هؤلاء سيظنون أنني جعلت كلمات للأطفال لأخفي عيوبها أو ليكون لدي عذر جاهز لأي ثغرة في اللغة: أنها للاطفال.

    2- ماذا سيفعل الأطفال (أو الكبار المبتدئين) بعد تعلمها؟ هذا سؤال معقول. هب أن شخصاً تعلم كلمات ثم أراد أن يصنع برامجاً كبيرة أو تجارية، هل سيجب عليه أن يتعلم لغة برمجة أجنبية؟ إن كنت أقول أنني صنعت كلمات لرفع حاجز اللغة الذي يعوق تعلم البرمجة، فلماذا لا أرفع أيضاً (أو بتعبير أدق: أساعد في رفع) حاجز اللغة الذي يعوق البرمجة الاحترافية؟

    3- ماذا عن تحقيق حلم البرمجة باللغة العربية؟ هذا جانب اجتماعي أيضاً: لو ظهرت لغة برمجة عربية احترافية، ألن يؤدي هذا لشعور بالفخر في سائر أنحاء الوطن العربي، وأن يزداد العرب ثقة في قدرتهم على النهوض بأمتهم، وأن يكون شيئاً جميلاً على العموم؟

    الرأي الخاص بي: لماذا لم أجعلها كذلك

    بالنسبة لجانب أن البعض سيراها لعبة: لقد تعلمت البرمجة على كمبيوتر صخر وأنا طفل، وكنت أبرمج لأستمتع بوقتي قبل أن أعرف بوجود كلية اسمها "حاسبات" أو وظيفة اسمها "مطور برامج". كلمات بدأت لأقدم نفس الفرصة لأطفال اليوم، ولم تصنع لتكون لغة احترافية.

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

    وهذا ما لا أستطيع أن أقوم به حالياً. ما أستطيع أن أقوم به هو تطوير اللغة نفسها، وهو ليس أمراً سهلاً حتى للغة مبتدئين.

    ربما هذا حلم يحتاج لمساهمة من المجتمع كله. فليصنع الناس لغات برمجة عربية أخرى، تعليمية واحترافية وتجريبية. كلمات - لمن لا يعرف - مفتوحة المصدر: يمكن لأي مبرمج أن يدرس الكود ويعرف كيف كتبت. يمكن للمجتمع إن أراد أن يتعلم منها ويصنع مثلها أو أفضل.

    الجزء الأخير: الخطوات المطلوبة لتكون كلمات احترافية

    (الحديث هنا تكنولوجي وليس اجتماعي، لن أتحدث عن التسويق أو الدعم الفني...الخ ولكن عن تطوير اللغة نفسها).

    أولاً: كلمات في صورتها الحالية لغة قوية جداً. فيها مثلاً هذه الإمكانيات:
    • tail call elimination
    • destructuring
    • lambda expressions - في الإصدارة القادمة
    •  green threads
    • CSP channels
    وهي إمكانيات معظمها لا يوجد في ++C، ولا بايثون، ولا جافا. (في حالات معينة مثل CSP  يمكن تطعيم تلك اللغات بمكتبات خارجية لتقديم هذه الإمكانيات، لكن في حالات مثل tail calls لا يمكن).

    لكن على الجانب الآخر، اللغات الأخرى تقدم تنفيذا سريعاً للبرامج، تقدم garbage collection متقدم عن كلمات (ماعدا ++C التي لا تحب مثل هذه الرفاهيات)، تقدم مكتبات لأي شيء تريده، تقدم ضماناً معقولاً لخلو المترجم والآلة الافتراضية من الأخطاء، وتقدم خاصية استدعاء دوال خارجية [بايثون تقدم ctypes لاستدعاء إجراءات مكتوبة بالسي، جافا تقدم JNI لنفس السبب، سي شارب تقدم P/Invoke، وهكذا).

    كلمات تحتاج إذاً، لكي تكون أقرب للاحترافية:
    • تطوير الآلة الافتراضية الخاصة بها (وهي من تصميمي واسمها SmallVM) لتكون أسرع وبجامع مهملات أفضل. أو كتابة نسخة من كلمات تعمل على ألة افتراضية موجودة.
    • ضبط إمكانية FFI الخاصة بها (وهي الخاصية التي تكافيء JNI/ctypes المذكورة بأعلاه). الخاصية موجودة بالفعل في كلمات لكنها تحتاج لاستكمالها.
    • إصلاح الكثير من الثغرات والنواقص الموجودة
    • صنع خاصية multiplexing over threads، ولو تم صنع هذه الخاصية فستكون ميزة نادرة لكلمات، لا توجد إلا في لغات مثل Google Go أو Erlang
    • صنع بعض المكتبات الأساسية مثل web, database, networking
    • عمل كل هذا بدون التأثير على سهولة تعلم اللغة، أو ملاءمتها للأطفال، أو جمالها [ربما يتطلب هذا فصل اللغة إلى لغتين واحدة للاطفال والأخرى احترافية، لكن بنفس الـsyntax تقريباً ونفس المكتبات].
    بعض هذه الإمكانيات يجري العمل فيه فعلاً (مثلاً أعمل حالياً في خاصية multiplexing)، والبعض مؤجل للمدى الطويل، والبعض لا أدري إن كنت سأقوم به فعلاً أم لا. من يعلم؟ هؤلاء الذين يطلبون لغة احترافية، ربما يحصلون عليها ذات يوم.

    الجمعة، 16 نوفمبر 2012

    Solving an ACM problem with Kalimat (part 2)

    • هذا المقال تكملة للجزء الأول الذي تجده هنا، لكن في الواقع الجزء الثاني يتضمن كل المعلومات المطلوبة ولا تحتاج لقراءة الجزء الأول لتفهمه.
    • مسألة الـACM نفسها هنا
     ما المطلوب من المسألة؟ كتابة برنامج به وصف لمجموعة من المبان، وحذف الخطوط المتقاطعة بحيث يظهر فقط المحيط العام لتلك المبان، كما توضح الصورة:


    كيف نحل هذه المسألة؟ من حسن الحظ أن شرح السؤال نفسه يلمح لنا بالحل!
    The skyline vector should represent the "path" taken, for example, by a bug starting at the minimum x-coordinate and traveling horizontally and vertically over all the lines that define the skyline.

    يقول لنا البرنامج أن الحل يصف تحركات حشرة تتحرك عبر صف المبان. تعال نتخيل أن هذه الحشرة هي نملة (بدلاً من البقة المذكورة في المسألة). الحركة في الصور التالية من اليسار لليمين:

    في البداية ستسير النملة أفقياً حتى تصطدم بجدار بمبنى:
    فإن وجدت المبنى ستبدأ في التحرك رأسياً لتتسلقه


    إن وجدت نفسها عند سفح مبنى من جديد، فستبدأ في تسلقه، وإن وجدت نفسها عند هضبة فستنزل

    في هذه الظروف، تكون النملة دائماً في حالة من أربع: واقفة على الأرض وأمامها مبنى (تحتاج أن تسير إليه)، أو واقفة على سطح مبنى (بدايته أو وسطه) تسير عليه، أو عند سفح مبنى (فتصعده)، أو عند نهاية سطح مبنى، سنسمي هذه الحالة هضبة، (فتهبط).

    وكيف تنتقل بين الحالات؟

    إن كانت واقفة على الأرض:
    • تسير إلى سفح أول مبنى أمامها

    إن كانت واقفة على سطح مبنى:

    • يمكن أن يكون هناك مبنى يعوق سيرها، في تلك الحالة تسير إلى وجه المبنى العائق ثم تصبح حالتها "عند سفح".
    • أو تكون حرة أن تسير لآخر المبنى الذي تقف عليه، وفي تلك الحالة تفعل ذلك وتكون حالتها "على هضبة"


    إن كانت عند سفح:
    • تصعد لأعلى المبنى، ثم تكون حالتها "على سطح مبنى"
    إن كانت عند هضبة:
    • إن كان هناك سطح مبنى يعوق هبوطها، تنزل إلى سطح ذلك المبنى ثم تصبح حالتها "على سطح مبنى"
    • إن لم يكن هناك عائق تنزل إلى الأرض (ص = 0) وتصبح حالتها "على الأرض"



    الملخص:

    لم يبق سوى كتابة الكود التي تمثل هذا الرسم، ثم نستطيع جميعنا أن نعود إلى البيت ونأكل الساندوتشات التي أعدتها أمهاتنا :)


    شيء نلاحظه: نحن نعلم ان المباني المدخلة مرتبة ترتيبا تصاعدياً حسب الحافة اليسرى للمبنى، لذلك حين نبحث عن عوائق افقية لا يوجد معنى لأن نبدأ البحث من أول مبنى، بل نريد البحث من "أول مبنى على يمين النملة"، لذلك سيكون لدينا متغير اسمه "بداية.البحث.الأفقي" يدل على رقم المبنى الذي سنبدأ منه البحث. هذا المتغير سيأخذ أولاً القيمة 1، ثم نحدثه كلما تحركت النملة لليمين.

    الآن إلى الكوووود!!


    كما نعلم، مجموعة البيانات المدخلة هي مصفوفة من ثلاثيات، مثل [[12، 10، 20]، [15، 8، 22]، [20، 12، 30]]، وكل ثلاثية تعبر عن مبنى [الحافة اليسرى، الارتفاع، الحافة اليمنى]. فلنبدأ بشيء بسيط: دوال قصيرة لاستخراج بيانات كل مبنى مما يجعل البرنامج أسهل في القراءة:
    دالة يسار ( مبنى ) :
        ارجع ب: مبنى [ 1 ] 
    نهاية 
    
    دالة سطح ( مبنى ) :
        ارجع ب: مبنى [ 2 ] 
    نهاية 
    
    دالة يمين ( مبنى ) :
        ارجع ب: مبنى [ 3 ] 
    نهاية

    الآن نرى الإجراء الأساسي لحل المسألة:
    بداية.البحث مشترك 
    
    إجراء إجابة ( صف.المباني ) :
        بداية.البحث = 1 
        على.الأرض ( 0 ، 0 ، صف.المباني ) 
    نهاية 

    ببساطة: بداية البحث (الذي يدل على رقم أول مبنى على يمين النملة) نحددها بواحد، ثم ننادي إجراءاً يعبر عن الحالة المبدئية للنمية (أنها على الأرض). سوف نصنع إجراءاً يعبر عن كل حالة وننتقل بين الحالات عن طريق استدعاء تلك الإجراءات.

    ماذا أخذ الإجراء على.الأرض؟ أخذ قيم س، ص، ومصفوفة المباني.

    جميل جداً. الآن ننظر للإجراء نفسه:

    إجراء على.الأرض(س ، ص ، المباني) :
     
     لكل أ من بداية.البحث إلى عدد(المباني) :
            إذا يسار(المباني [أ]) > س :
                س = يسار(المباني[أ]) 
                اطبع س 
                حدث.بداية.البحث(س، المباني) 
                وكل إلى عند.سفح(س، ص، المباني[أ] ، المباني) 
            تم 
        تابع 
             -- إن وصل التنفيذ هنا فمعنى ذلك
             -- أن النملة على الأرض ولا يوجد
             -- مبان على يمينها: أي أن الرحلة
             -- قد انتهت
     نهاية

    الإجراء مكون من جزئين: الجزء الأول (بين لكل...تابع) يبحث عن أول مبنى على يمين النملة، فإن وجده:
    - يغير قيمة "س" ليحرك النملة عند سفح المبنى، ويطبع القيمة الجديدة كما هو مطلوب في المخرجات
    - ينادي حدث.بداية.البحث(س، المباني) لكي يبحث عن أول مبنى على يمين س الجديدة ويجعل رقم هذا المبنى هو بداية.البحث
    - ينفذ السطر وكل إلى عند.سفح (____ ) ويعطيه بعض القيم، مما يجعل البرنامج الآن في حالة جديدة.

    ما معنى وكل إلى؟ انها تجعل السطر من "استدعاء إجراء" إلى "توكيل لإجراء". ما الفرق بينهما؟ في حالة التوكيل فإنه قبل استدعاء عند.سفح(...) سوف يتم أولاً حذف الstack frame الخاصة بـ على.الأرض( ) من الذاكرة، وهذا  طبيعي لأن هذا الجزء من البرنامج لا نحتاج أن نرجع إليه.

    الآن نرى عند.سفح:
    إجراء عند.سفح ( س ، ص ، مبنى ، المباني ) :
    
        ص = سطح ( مبنى ) 
        اطبع ص 
        وكل إلى عند.سطح ( س ، ص ، مبنى ، المباني ) 
    نهاية 

    إذا كانت النملة عند سفح مبنى، فإنها تتسلقه (بتغيير قيمة ص وطباعتها)، ثم توكل سائر العمل إلى الحالة الجديدة: عند.سطح

    سهلة دي مش كدة؟

    إجراء عند.سطح(س، ص، مبنى، المباني) :
    
     لكل أ من بداية.البحث إلى عدد(المباني) :
            م = المباني [أ] 
             -- لو وجدنا مبنى خارجاً تماماً عن حدود المبنى الحالي،
             -- فكل المباني التي تليه هي الأخرى خارجة عن الحدود
             -- وبالتالي لا داع للاستمرار في البحث
            إذا يسار(م) > يمين(مبنى) : اذهب إلى نهاية.البحث 
     
             -- هل م أعلى من المبنى الذي تقف عليه النملة؟
             إذا سطح(م) > سطح(مبنى) :
                -- في هذه الحالة فهو عقبة. هيا نتحرك إلى سفحه
                 س = يسار (م) 
                اطبع س 
                حدث.بداية.البحث(س ، المباني) 
                وكل إلى عند.سفح(س، ص، م، المباني)           
            تم 
        تابع 
        علامة نهاية.البحث 
        -- إن وصلنا هنا ولم نجد شيئاً، نسير إلى نهاية المبنى الحالي
         س = يمين(مبنى) 
        اطبع س 
        حدث.بداية.البحث(س، المباني) 
        وكل إلى عند.هضبة( س ، ص ، مبنى ، المباني) 
    نهاية

    لا تنزعج! الكود أبسط مما يبدو عليها. هي ببساطة تقوم بالآتي:
    1- نفذ لكل مبنى م في المباني التي على يمين النملة:
    • لو كان يسار م أكبر من يمين المبنى الذي نقف عليه، إذا فكل المباني بعيدة ولا توجد عقبات. سوف نذهب للخطوة 2
    • لو كان الأمر غير هذا، فقد وجدنا مبنى يقطع مبنانا! لو كان أعلى من مبنانا أيضاً فيجب أن نصل إلى سفحه. حرك س إلى سفح المبنى، واطبعها، وانتقل لحالة عند.سفح
    2- لو انتهت الحلقة ولم نجد عقبة، إذاً فنحن على سطح مبنى بلا عقبات. هيا نسير إلى نهاية السطح (نغير س ونطبعها)، ثم ننتقل إلى حالة عند.هضبة

    لو كنت لاتزال تجد صعوبة، انظر إلى الصور مرة أخرى.

    الآن نصل إلى عند.هضبة:
    إجراء عند.هضبة(س، ص، مبنى، المباني) :
    
     أعلى.عقبة = لاشيء 
        لكل أ من 1 إلى عدد(المباني) :
            م = المباني[أ] 
            إذا م <> مبنى وأيضا يمين(م) > س وأيضا يسار(م) < س :
                 -- لقد وجدنا مبنى يقطع مبنانا
                 -- وهو بالتأكيد ليس أعلى منه لأنه لو كان أعلى
                 -- لكنا عليه بدلا من المبنى الحالي
     
                 -- لو كنا مازلنا في بداية البحث، نعطي
                 -- قيمة مبدئية للمتغير أعلى.عقبة
                إذا أعلى.عقبة = لاشيء :
                    أعلى.عقبة = م 
                تم 
                 
                 -- سوف نختار أعلى مبنى فيهم لنهبط إليه
                إذا سطح(م) > سطح(أعلى.عقبة):
                    أعلى.عقبة = م
                تم 
            تم 
        تابع 
        إذا أعلى.عقبة = لاشيء :
            ص = 0 
            اطبع ص 
            وكل إلى على.الأرض(س، ص، المباني) 
        وإلا :
            ص = سطح(أعلى.عقبة) 
            اطبع ص 
            وكل إلى عند.سطح(س، ص، أعلى.عقبة، المباني) 
        تم 
    نهاية

    مرة أخرى: الأمر أبسط مما يبدو عليه. الدالة جزءان:

    الجزء الأول بين "لكل...تابع" يبحث عن أعلى مبنى يحتوي النقطة س التي تقف فيها النملة (يمينه أكبر من س ويساره اقل منها). لأن هذا الشرط ينطبق على المبني الحالي الذي تقف النملة عليه؛ لابد أن نضع جزءاً من الشرط يتأكد أن م هو مبنى مختلف عن المبنى الحالي.

    الجزء الأول بين "لكل...تابع" له دور آخر: من بين كل المباني التي تحتوي س، فإنه يختار أعلاها. هذا يتم عن طريق ثلاثة أجزاء:
    • خارج الـloop، يجعل قيمة المتغير أعلى.عقبة تساوي لاشيء.
    • داخل الـloop، يعطي هذا المتغير قيمة أولية هي أول مبنى يصلح يجده، وذلك عن طريق الشرط إذا أعلى.عقبة = لاشيء :... هذا الجزء يتم تنفيذه مرة واحدة فقط.
    • داخل الـloop أيضاً، يتم كل مرة مقارنة م بأعلى عقبة، لحساب قيمة max في المتغير أعلى.عقبة بالطريقة المعروفة.
    الجزء الثاني: لو كانت قيمة المتغير أعلى.عقبة تساوي لاشيء، فمعنى هذا أنه لا توجد عقبات، فتنزل النملة على الأرض (تغير ص وتغير حالتها).

    لو كان هناك قيمة للمتغير أعلى.عقبة، فهناك إذاً عقبة أمام نزولنا. بدلاً من النزول للأرض ننزل إلى سطح تلك العقبة (المبنى) ونغير الحالة.

    أخيراً هذا هو الإجراء حدث.بداية.البحث
    إجراء حدث.بداية.البحث (س، المباني) :
        
        لكل أ من بداية.البحث إلى عدد( المباني ) :
            إذا يسار (المباني [أ]) > س :
                بداية.البحث = أ 
                اذهب إلى النهاية 
            تم 
        تابع 
        علامة النهاية 
    نهاية

    الإجراء يستخدم القيمة القديمة لـ بداية.البحث، حتى يجد أول مبنى على يمين النملة (يمينه أكبر من س)، وهنا يسجل رقم ذلك المبنى في بداية.البحث ويخرج.

    هل يعمل البرنامج؟ القيم المطبوعة هي نفس النتيجة المكتوبة في موقع المسألة (ولكني لم أختبره على مدخلات أخرى)
    يمكنك أن تختبره أنت إن أردت! الكود كاملةً تجدها هنا:
    -- هذا البرنامج حل لمسألة Skyline problem من مسائل الـACM
     -- تجد المسألة هنا: http://uva.onlinejudge.org/external/1/105.html
     
    -- اختبارات()
     حل.المسألة ( ) 
    
    إجراء حل.المسألة ( ) :
        صف.المباني = [ ] 
        ملف.المدخلات = افتح.ملف ( "input.txt" ) 
        كرر مادام ليس ملف.المدخلات : منته ( ) :
            س = ملف.المدخلات : اقرأ.سطر ( ) 
            الثلاثية = تفصيص ( س ، " " ) 
            الثلاثية [ 1 ] = كعدد ( الثلاثية [ 1 ] ) 
            الثلاثية [ 2 ] = كعدد ( الثلاثية [ 2 ] ) 
            الثلاثية [ 3 ] = كعدد ( الثلاثية [ 3 ] ) 
            صف.المباني = صف.المباني + [ الثلاثية ] 
        تابع 
        اغلق.ملف ( ملف.المدخلات ) 
        إجابة ( صف.المباني ) 
    نهاية 
    
    
    بداية.البحث مشترك 
    
    إجراء إجابة ( صف.المباني ) :
        بداية.البحث = 1 
        على.الأرض ( 0 ، 0 ، صف.المباني ) 
    نهاية 
    
    
    بداية.البحث مشترك 
    إجراء على.الأرض ( س ، ص ، المباني ) :
    
     لكل أ من بداية.البحث إلى عدد ( المباني ) :
            إذا يسار ( المباني [ أ ] ) > س :
                س = يسار ( المباني [ أ ] ) 
                اطبع س 
                حدث.بداية.البحث ( س ، المباني ) 
                وكل إلى عند.سفح ( س ، ص ، المباني [ أ ] ، المباني ) 
            تم 
        تابع 
             -- إن وصل التنفيذ هنا فمعنى ذلك
             -- أن النملة على الأرض ولا يوجد
             -- مبان على يمينها: أي أن الرحلة
             -- قد انتهت
     
    نهاية 
    إجراء عند.سفح ( س ، ص ، مبنى ، المباني ) :
    
     ص = سطح ( مبنى ) 
        اطبع ص 
        وكل إلى عند.سطح ( س ، ص ، مبنى ، المباني ) 
    نهاية 
    
    إجراء عند.سطح ( س ، ص ، مبنى ، المباني ) :
          --  اطبع "سطح"
     لكل أ من بداية.البحث إلى عدد ( المباني ) :
            م = المباني [ أ ] 
             -- لو وجدنا مبنى خارجاً تماماً عن حدود المبنى الحالي،
             -- فكل المباني التي تليه هي الأخرى خارجة عن الحدود
             -- لاحظ أن الأمر التالي غير مختوم بكلمة "تم" بل
             -- الأمر كله سطر واحد
             إذا يسار ( م ) > يمين ( مبنى ) : اذهب إلى نهاية.البحث 
            
             -- هل م أعلى من المبنى الذي تقف عليه النملة؟
             إذا سطح ( م ) > سطح ( مبنى ) :
                 -- في هذه الحالة فهو عقبة. هيا نتحرك إلى سفحه
                 س = يسار ( م ) 
                 اطبع س 
                 حدث.بداية.البحث ( س ، المباني ) 
                وكل إلى عند.سفح ( س ، ص ، م ، المباني )        
             تم 
        تابع 
        علامة نهاية.البحث 
         -- إن وصلنا هنا ولم نجد شيئاً، نسير إلى نهاية المبنى الحالي
          س = يمين ( مبنى ) 
        اطبع س 
        حدث.بداية.البحث ( س ، المباني ) 
        وكل إلى عند.هضبة ( س ، ص ، مبنى ، المباني ) 
    نهاية 
    
    إجراء عند.هضبة ( س ، ص ، مبنى ، المباني ) :
    
        أعلى.عقبة = لاشيء 
        لكل أ من 1 إلى عدد ( المباني ) :
            م = المباني [ أ ] 
            إذا م <> مبنى وأيضا يمين ( م ) > س وأيضا يسار ( م ) < س :
                 -- لقد وجدنا مبنى مختلف يقطع مبنانا
                 -- وهو بالتأكيد ليس أعلى منه لأنه لو كان أعلى
                 -- لكنا عليه بدلا من المبنى الحالي
     
                 -- لو كنا مازلنا في بداية البحث، نعطي
                 -- قيمة مبدئية للمتغير أعلى.عقبة
                 إذا أعلى.عقبة = لاشيء :
                    أعلى.عقبة = م 
                تم 
                عقبة2 = م 
                 -- سوف نختار أعلى مبنى فيهم لنهبط إليه
                إذا سطح ( عقبة2 ) > سطح ( أعلى.عقبة ) :
                    أعلى.عقبة = عقبة2 
                تم 
            تم 
        تابع 
        إذا أعلى.عقبة = لاشيء :
            ص = 0 
            اطبع ص 
            وكل إلى على.الأرض ( س ، ص ، المباني ) 
        وإلا :
            ص = سطح ( أعلى.عقبة ) 
            اطبع ص 
            وكل إلى عند.سطح ( س ، ص ، أعلى.عقبة ، المباني ) 
        تم 
    نهاية 
    
    إجراء حدث.بداية.البحث ( س ، المباني ) :
        
        لكل أ من بداية.البحث إلى عدد ( المباني ) :
            إذا يسار ( المباني [ أ ] ) > س :
                بداية.البحث = أ 
                اذهب إلى النهاية 
            تم 
        تابع 
        علامة النهاية 
    نهاية 
    
    
    دالة يسار ( مبنى ) :
        ارجع ب: مبنى [ 1 ] 
    نهاية 
    
    دالة سطح ( مبنى ) :
        ارجع ب: مبنى [ 2 ] 
    نهاية 
    
    دالة يمين ( مبنى ) :
        ارجع ب: مبنى [ 3 ] 
    نهاية

    الخميس، 15 نوفمبر 2012

    Solving an ACM problem with Kalimat

    هذه هي المسألة التي يتحدث عنها المقال، اقرأها جيداً ثم تعال وأكمل القراءة :)

    شكل مبدئي للحل
     
    البرنامج يقرأ ملفاً به عدد من السطور، كل سطر هو مجموعة من الأرقام تفصل بينها مسافات، وكل ثلاثة أرقام متتالية تعبر عن مبنى في المدن التي تتعامل معها المسألة. إذاً فلنبدأ بقراءة ملف المدخلات وتقسيم كل سطر إلى ثلاثيات
    إجراء حل.المسألة() :
        صف.المباني = [ ] 
        ملف.المدخلات = افتح.ملف("input.txt") 
        كرر مادام ليس ملف.المدخلات : منته() :
            س = ملف.المدخلات : اقرأ.سطر() 
            الثلاثية = تفصيص(س ، " ") 
            صف.المباني = صف.المباني + [الثلاثية] 
        تابع 
        اغلق.ملف(ملف.المدخلات) 
        اطبع إجابة(صف.المباني) 
    نهاية

    يعتمد هذا البرنامج على مكون لم نكتبه بعد: الدالة إجابة  التي تحسب لنا الحل المطلوب. لكن قبل هذا نريد أن نختبر البرنامج ونتأكد أن الخطة العامة تسير كما ينبغي. من أجل ذلك سوف نكتب دالة "إجابة" قصيرة جداً:

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

    عظيم! يمكننا الآن تشغيل البرنامج (بعد التأكد من وجود ملف input.txt به مثال للمدخلات الصحيحة كما في صفحة المسألة).

    في الواقع حين جربت تشغيل البرنامج وجدت خطأ...ليس في البرنامج بل في كلمات نفسها! وجدت المفسر يقول لي "استدعاء الإجراء أو الدالة بعدد غير مناسب من القيم المرسلة" وقصده على التعبير ملف.المدخلات: منته( )  ، يبدو أنه كان يتوقع عدداً أكبر من العوامل.

    هل ينفع هذا؟ يبدو أن كلام المشككين صحيح: العرب لا يستطيعون عمل لغات برمجة. لماذا لا يرسل أحدكم رسالة بريدية غاضبة لمصمم اللغة يؤنبه على إهماله؟ :(

    القصد، قمت بتصحيح الخطأ وإعادة تنفيذ البرنامج:




    حسناً! نحن نقرأ المدخلات بصورة صحيحة، ويبقى أن نحل المسألة. هل سنقدر على هذا؟ وسؤال آخر: هل سيعمل الحل بسرعة؟ لاحظ أن كلمات أبطأ بكثير من لغة مثل سي++. هذه لغة مصممة للتعليم والرسم بالكمبيوتر والألعاب، وليس لـ"طحن الأرقام". أنا لم أحل المسألة بعد، لذلك فأنا لا أعرف فعلاً إجابة السؤال. سأبدأ الآن في حلها..

    اضغط هنا لتقرأ الجزء الثاني

    الجمعة، 9 نوفمبر 2012

    التاريخ والأشياء الصغيرة

    أهوى علم لغات البرمجة (علم مختلف عن الـcompilers). وأفكر دائماً في لغة البرمجة "النموذجية" التي يمكن التعبير بها عما تريد بدون فجوة بين الفكرة في دماغك والكود التي تكتبها. يتفرع من هذا فكرة لغة البرمجة التعليمية التي يمكن لأي شخص أن يدخل منها عالم البرمجة، ولغة البرمجة "الديموقراطية" التي تمكّن أي شخص (صحفي، محامي) أن يكتب برنامجاً في مجال تخصصه، وهكذا.

    وأقوى سلاح في هذه الرحلة هو التاريخ. وهكذا تجدني أقضي الساعات في القراءة عن لغات البرمجة القديمة منذ الستينات وما بعدها.

    Algol - Icon -  CLU - Simula - Self - Forth - Logo - CleanSheet - ObjectVision

    ..بحثاً عن فكرة عبقرية لكن مفقودة.



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

    وفي أيام معركة الجمال في الثورة، ابتكر الثوار - وحدهم - طرقاً حربية مشابهة لما كان يفعله الرومان. حائط بشري يمسك دروع طويلة ويزحف بها... Testudo formation

    وحين فكرت في تعريب العلوم كنت آخذ "غطسات" في كتب العلوم الرياضية والطبية أيام الحضارة الإسلامية القديمة، لأرى كيف كان يبدو "العلم باللغة العربية"، وإن كان يمكن أن يكون العلم العربي الجديد امتداداً لما سبق وليس علماً مختلفاً تماماً.

    تلك المخطوطات منذ أيام الحضارة الإسلامة فيها أسلوب معين لكتابة الكتب: العنوان الطويل لكل فقرة الذي يصلح ملخصاً للفقرة. هناك كاتب أجنبي استخدم هذا الاسلوب في كتابه للذكاء الاصطناعي (الكاتب Patrick Henry Winston)، واستخدمته أحياناً في مقالات على المدونة. في الواقع الكتب الإسلامية القديمة كان بها ميزة ظريفة جداً هي أن الكاتب كان يصنع الكتاب خليطاً من الكتابة والرسم ينسابان مع بعضهما في حرية. كان الكتاب عملاً فنياً وليس مجرد وسيلة تقديم معلومات، وربما نحتاج أن تكون المزيد من الكتب بهذه الطريقة.

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

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

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

    الخميس، 8 نوفمبر 2012

    A notation for a sketch-based programming language

    This is my design for a language called "SketchCode". The language tries to enable sketch-based programming, both on a traditional paper pad or on a tablet-like device, and strives to maintain simplicity and clarity of the sketches by reusing whatever notations people already use when sketching and by introducing as few new notations as possible.

    Instead of making the code itself graphical, the system keeps the code mostly text based while using graphical notation for data structures. Blocks of simple shapes indicate objects, arrows indicate object references, tables indicate records or arrays.

    As you see, this simple scheme already allows us to represent many kinds of data. In SketchCode our program should be mostly graphs, state machines, ...etc, I like the idea that a program's data stands out more than its code.  As Fred Brooks said: Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious

    The graphical nature of the data allows us to program by pattern matching as seen in a lot of functional languages. An important set of new notations would be the language of pattern matching: how to indicate matching a variable? How to match a part of an array or structure?



    The first example shows how to calculate the sum the elements in a (sketched) linked list, the second shows how to extract data from a record, and the third shows the notation for 'if' statements.

    Tentatively, I chose to underline an identifier in a pattern to indicate being a variable, and the "piece of a table" to indicate partial record matching. It would be interesting to see how to indicate other notations like a part of a graph or a slice of an array.

    I have also borrowed some notations from math, and an implemented system could add traditional notations for things like roots, fractions, summation,...etc

    A lot can be done with just those basic components: we could have unit tests with sketches of test input, or a "console" where we sketch function application to evaluate it, and more. From there, there is so much that could be added.

    Of course, such a system needs to be implemented in order to find out whether this design is really sufficient to express interesting programs, and whether such expressions are actually natural to draw/understand, and how to e.g naturally modify an existing program.

    السبت، 3 نوفمبر 2012

    عطش للأفكار الأصيلة

    حين أقول "فكرة أصيلة" فقولي محاولة لترجمة original idea، والمقصود هو فكرة ليست مجرد تكرار للأفكار المعروفة. وأنا أعيش في حالة عطش دائم للأفكار الأصيلة، ويمكن تلخيص حياتي في أنها رحلة بحث عن الجديد، والنادر، والمبتكر. ولذلك أتحدث عن البرمجة، والرسم، والتأليف. كل من هذه هو ببساطة رحلة بحث عن فكرة جديدة [وتنفيذها].

    والمشكلة هي أنني شخص يحب الأفكار الأصيلة يعيش في عالم يحب المكرر والمألوف...

    - الشباب الجامعي الذي "يمزح" عن طريق تكرار القفشات من الأفلام الكوميدية.
     - السياسيون الذين يكررون الشعارات كل يوم حتى صارت تصريحاتهم هي clip show من لصق الشعارات ببعضها (والجمهور يحب هذا وينتخبهم).
     - حتى البرمجة؛ يكاد يصير تلخيصها الآن في تطبيقات "خزن البيانات ثم اعرضها"، والـUML ، والـ design patterns.

    هل تريد أكبر دليل على كلامي؟ انظر إلى لغة مثل الـ Prolog، إنها "فكرة أصيلة" بمعنى الكلمة، وتغير من تفكيرك في البرمجة تماماً، لكن الجميع يسخر منها لأنها أكاديمية، أو لأنه لم يفهم الcut، أو لأنها لن تأتي له بوظيفة. حتى الذين يحبونها، يحبونها بطريقة "لغة كويسة" وليس بطريقة "أريد أن أعرف المزيد!!".

    وفي عالم الشركات الجديدة وريادة الأعمال، توجد هذه الأيام مقولة منتشرة هي "الأفكار ليست مهمة، المهم التنفيذ"، وهذا تحوير ساذج لمقولة أقرب للدقة هي "مهما كانت الفكرة جيدة لن تنجح إن كان التنفيذ سيئاً".

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

    وحين بدأت في الكتابة على هذه المدونة، قررت شيئاً: لن أكتب في شيء إلا لو كان الموضوع نفسه جديداً، أو إن كان الموضوع معروفاً فلن أكتب إلا لو كان لديّ نظرة جديدة أو زاوية جديدة له. لن تجد على هذه المدونة مقالاً عن التنمية البشرية مثلاً، أو مقالاً يشرح الـquicksort. بشكل عام إن كان البحث بجوجل عن الموضوع يعطي مئات النتائج فلن أكتب عنه.

    ولن يكون للمدونة قراء كثيرون جداً :)

    الأربعاء، 31 أكتوبر 2012

    أفكار سياسية لحزب مصر القوية

    هذه بعض المقترحات مني للحزب في الفترة القادمة [ملاحظة: أنا شخص من خارج الحزب] تنقسم إلى ثلاث أقسام: قبل انتخابات مجلس الشعب، أثناء الانتخابات، والمرحلة الأهم: بعد الانتخابات.

    قبل الانتخابات

    من المشاكل التي تواجه الحزب - وهي من أكبر المشاكل في رأيي - مشكلة الpositioning، وهو مصطلح تسويقي بمعنى "الفكرة المرتبطة بك أو بمنتجك، بحيث يمكن أن يقال لو كنت تريد _______ فلدينا المطلوب".

    الـposition الخاص بحزب الحرية والعدالة مثلاً هو "دولة اسلامية معتدلة". حزب الدستور يحاول الحصول على position في عقول الناس هو "حزب يبحث عن الديموقراطية والحريات". حزب الأمة المصرية (الذي يؤسسه حازم صلاح أبو إسماعيل) ربما يكون الـposition الذي يسعى له هو "دولة اسلامية 'حازمة' بلا تنازلات"، وهكذا. فما هو الـposition الخاص بمصر القوية؟ بدون الإجابة على هذا السؤال أخشى أن يأتي الكثير من الناس فيقولوا "ده حزب كويس" ويسكتوا، بدون حماسة حقيقية أو تقدير للأهمية الحقيقية للدور الذي يقوم به الحزب.

    أنا لا أقول أن الحزب بلا موقع محدد، أنا فقط أقول أن هذا الموقع قد يشعر به مؤسسو الحزب لكن لا يوجد تعبير قوي عنه بين الناس..

    ما هي اتجاهات الحزب إذاً؟ ربما تكون هذه (في رأيي الشخصي):
    • إسلامي
    • يرى دوراً كبيراً لمسؤولية الدولة [مقابل القطاع الخاص]، في النهضة، رعاية الفقراء، العدالة الاجتماعية...الخ
    • يتسامى عن الصراعات الآيديولوجية أو الصراعات بشكل عام، ويحاول بدلاً من ذلك التركيز على صنع الدولة الحديثة المتطورة، وهذا يتضح من تسميته "مصر القوية"، ويأخذ هذا الموضوع كمشروع بحثي وليس مجرد تقليد لتجارب سابقة.
    المشكلة هنا أن هذه الصورة تبدو أعقد من اللزوم أحياناً عند توصيلها للمواطن العادي. الأمر يحتاج قصة موحدة تربط هذه الجوانب. وحين أقول قصة أقصد هذا بالفعل: شيء مجسد يتخيله الناس ويتنفسونه، وليس مجرد مجموعة من الآيديولوجيات.

    (أعتقد أن لديّ قصة مناسبة، لكني لا أريد الحديث عنها بعد لأني لم أنته بعد من مراجعة جوانبها المختلفة)

    عموماً كما قلت: لابد من تحديد الـposition، وإيصال هذا الـposition لكل أعضاء الحزب وكل من يتعامل معه، ثم انعكاس هذه الفكرة في اللقاءات الصحفية والحملات الدعائية...الخ. لابد أن يوجد فكرة تجعل الناس يقولون "مصر القوية" حين يأتي ذكرها.

    أثناء الانتخابات

    سوف يكون هناك بعض العوائق لانتخاب الحزب: البعض سيقول أنه بلا خبرة سياسية، البعض سيقول أنه ليس إسلامياً حقاً، والبعض سيقول أنه ليس متجهاً لبناء الدولة الحديثة حقاً، والبعض سيقول "كلام كويس بس احنا عاوزين أفعال".

    هناك شيء ربما يساعد في هذا الموضوع (وربما الحزب يقوم به بالفعل وأنا لا أعلم): حزمة من الأفعال.

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

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

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

    لكن لماذا نستخدم هذه النقطة فقط في إقرار عدد من القوانين؟ لماذا لا نستخدمها في تغيير شكل الحوار السياسي في مصر؟ :)

    في الواقع الحوار السياسي في مصر لا يعجبني كثيراً..إنه لا يخرج في أكثره عن شيء من:
    • التخوين والشائعات.
    • الوصول لحلول وسط بين الأطراف المتنازعة.
    • تبادل الآراء ومحاولة الإقناع بواسطة أساليب إقناعية جدلية مختلفة.
    النوع الأول مرفوض، والنوع الثاني ينبغي أن يكون الحل الأخير وليس الوسيلة الأساسية، والنوع الثالث هو الأقرب لما يقوم به المعتدلون/المخلصون، لكنه في الواقع لا يغير الآراء كثيراً. كم مرة تجادل طرفان عن العدالة الاجتماعية مثلاً ثم خرج طرف منهم وقد غير رأيه؟ في الغالب كل من الطرفين لديه حججه التي أقنعته لكنها لن تقنع الطرف الآخر (الذي لديه حجج بدوره).

    هناك طريقة رابعة، والذي يقدّم هذه الطريقة إلى سائر أطراف الحوار السياسي المصري سيكون في أعيني بطلاً قومياً. هذه الطريقة هي القرار المبني على البيانات.

    هب أننا مختلفون على موضوع مجانية التعليم (في كل المراحل) هل تؤثر على جودة التعليم أم لا. يمكننا أن نقوم بتجربة: خذ أفضل عشرين أو ثلاثين دولة في المجال التعليمي، وانظر لموقف كل دولة فيه من مجانية التعليم. أو خذ إحصائيات عن الدول التي كان تعليمها خاصاً وأُدخلت فيه المجانية، أو العكس، هل حدث تغير ما؟ وهل المجانية كانت هي العامل فعلاً أم كان هناك عوامل أخرى؟ (هنا يفيد النظر للدراسات عالية الجودة التي تتبع المنهج العلمي).

    في هذه الحالة قد يجد المواطن نفسه في حوار سياسي مختلف، ويجد أعضاءً يكون ردهم لمن يخالفهم: هذه هي البيانات التي تدعم قراري، فأتني ببيانات أفضل منها.

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

    وهذا قد يكون ما يأتي بمصر قوية حقاً.

    الجمعة، 12 أكتوبر 2012

    طيب ليه المجتمع ما بقاش فجأة مليان بطلبة العلم؟

    نحن الآن في عصر الوفرة المعلوماتية. من أراد أن يتعلم سيجد مئات الكتب والدروس والفيديوهات والأوراق البحثية والبرامج والـsource code. لكن ليس الكثير يستغلون هذه الموارد. لماذا؟

    هذا سؤال جاد يستحق إجابة جادة. وهذا المقال رسالة إلى كل من يريد النهضة: النهضة لن تأتي بتوزيع الأجهزة اللوحية في المدارس (وإن كنا نرحب بكل خطوة نافعة)، بل من فهم سلوك الناس ودوافعهم. إن لدينا بالفعل ما يكافيء مدرسة وجامعة ومكتبة في كل بيت متصل بالإنترنت؛ ولن تضيف الأجهزة اللوحية كثيراً إلى هذا. فكر لماذا لم يستفد أحد من الموارد الموجودة قبل أن تسارع لعمل صفقة للاستحواذ على موارد جديدة.

    هل هو الوقت والمال؟

    أحياناً هذه أسباب حقيقية: هناك بيوت ليس لديها أموال لشراء الكتب، أو الاشتراك بالإنترنت. هناك أشخاص وظيفتهم هي كل حياتهم، وبالكاد لديهم وقت لأسرتهم ناهيك عن العلم. إذاً جزء من النهضة هو السير في طريق العدالة الاجتماعية حتى يطمئن الناس على قوتهم وقوت أطفالهم، ويكون لديهم disposable time, disposable income يقضونه في نشاطات أخرى.

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

    لا أقصد أنهم تافهون: ربما بعضهم كذلك لكن كثير منهم تراه يتمنى فعلاً النهضة ويتحدث عن قيمة العلم ويقارن حالنا بحال الدول الغربية...الخ. فما السبب إذاً؟

    القصور الذاتي

    Every object in a state of uniform motion tends to remain in that state of motion unless an external force is applied to it.
    Newton's first law of motion

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

    هناك جهود كثيرة مبذولة في ما يسمى التنمية البشرية، لكن لا يوجد جهد مكافيء في العلم الحقيقي. في أحسن الأحوال هناك مبادرات على غرار "مصر تقرأ" لكن لا تؤخذ هذه الأمور بجدية مثلما تؤخذ "صناع الحياة" أو غيرها. هذا يفتح الباب لنسأل: ما الأسباب التي أدت لذلك؟ ربما يحتاج هذا السؤال مقالاً آخر.

    ومعظم الناس ببساطة لم يفكروا في الموارد الموجودة أو لم يسمعوا بها. كيف نخبرهم؟

    وكثير من المؤسسات الفكرية النهضوية (وليس كلها) تبحث عن التوعية أكثر منها العلم. وحتى من يبحث عن العلم فيها نجده يتحدث عن العلم أكثر منها في العلم. أي أن رسالته هي "ندوة عن أهمية العلم" أكثر منها "ندوة عن الـcontext free grammars".

    ولابد من البحث عن الأسباب.

    "ولكن كيف سيؤثر في حياتي؟"

    برامج التنمية البشرية لا تستحي من التهويل في أثرها: ان شعار كثير منها حرفياً هو "ايقظ المارد الموجود بداخلك". هم يقدمون لك فكرة أنك ستكون إنساناً أكثر نجاحاً وأقرب للسعادة وأكبر تأثيراً لو نميت نفسك على طريقتهم. أما العلم فماذا سيغير في حياتك؟

    فلنفترض أنك قد قرأت وقرأت وقرأت، وتعلمت البرمجة، أو قرأت في الفيزياء، أو في التاريخ، أو في علم الفلك، أو في الاقتصاد، فماذا بعد؟

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

    "ولكن العلم ممل"

    الحرارة النوعية هي كمية الحرارة اللازمة لرفع درجه حرارة 1 كيلوجرام من المادة بمقدار درجه واحدة. ويرمز لها بالرمز (c) ووحداتها في النظام الدولي هي (جول/كيلوجرام/كلفن).
    من ويكيبديا

    لماذا أراك تحب الكتب هكذا؟ أنا لا أحب الكتب! هل رأيت كتب المدرسة؟
    من حديث مع أقاربي


    مشكلتنا لها نواح متعددة: بدايةً معظمنا، في أول خبرة له بالعلم، يرى العلم في الكتب المدرسية، والكتب المدرسية المصرية (وربما هذه مشكلة عالمية) تبدو بلا اتجاه ولا هدف، بل هي مجموعة من الحقائق المرصوصة بعضها بجوار بعض.

    المشكلة الثانية أن العلم فعلاً - ولو خارج الكتب المدرسية - يقدم بطريقة جافة مجردة. ومعظم الذين يسعون لحل المشكلة يركزون على جزء "جافة" بأن يضيفوا الرسومات والألوان والحركة ولا يقتربون من جزء "مجردة". ما معنى الحرارة النوعية؟ لا أقصد المعنى المذكور في التعريف، ولكن المعنى مثلما نقول "حياتي لها معنى"...ما السبب الذي جعلنا نعرّف الحرارة النوعية ونضعها في الكتب؟ ما دور هذه المعادلة في سير الطبيعة وفي الاستفادة من العلم؟ ما هو الـraison d'etre لهذا القانون؟

    وكيف "أشعر" بهذا القانون وليس فقط "اعرفه"؟ هذه نقطة لا ينتبه لها البعض: أن القوانين لا توجد في الورق ولكنها تتمثل في الطبيعة المحسوسة. لماذا نسلق اللحم في الماء لكن نقليه في الزيت؟ ما علاقة هذا بالحرارة النوعية؟ حتى القواعد التي تبدو مجردة مثل قواعد النحو أو البلاغة، لماذا هي كما نراها وليس بصورة أخرى؟ مثلاً لماذا نضع بعض الطلبات في صورة سؤال مثل "could you pass the salt؟"، وما الأثر النفسي لهذه الصياغة على السامع، وما سبب ذلك الأثر؟

    "ولكن العلم صعب"

    وحتى من يبحث عن العلم فيها نجده يتحدث عن العلم أكثر منها في العلم. أي أن رسالته هي "ندوة عن أهمية العلم" أكثر منها "ندوة عن الـcontext free grammars".
     — أنا، من جزء سابق في هذا المقال

    هؤلاء يقضون الساعات على الفيسبوك، أو الفيديو جيمز، أو في الخروج، أو في الكوفي شوبس.
      — أنا برضه

     الحديث عن العلم أسهل من الدخول في التفاصيل العلمية. مشاهدة المسلسل أسهل من تعلم البرمجة. إن كنا نبحث عن الأسباب فهذا سبب.

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

    وفي هذه الأيام هناك نشاطات كثيرة يمارسها الأطفال والشباب تظنها صعبة حين تفكر فيها. هناك أشخاص كانت أول خبرة برمجية لهم في تصميم مستويات جديدة في الألعاب التي يلعبونها game modding. هناك من يخرجون من الحيز الإلكتروني إلى الحيز المادي ويقومون بتعديل سياراتهم بتصميمات جديدة car modding، (هناك بالمناسبة مجتمعات لتعديل السيارات ضمن الشباب المصري).

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

     ولن تكون النهضة العلمية بتوزيع الأجهزة اللوحية في المدارس (وإن كنا نرحب بكل خطوة نافعة)، بل من فهم سلوك الناس ودوافعهم.