‏إظهار الرسائل ذات التسميات teaching-children-programming. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات teaching-children-programming. إظهار كافة الرسائل

الجمعة، 6 يوليو 2012

مشاريع للأطفال، لكن قد تغير العالم

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

لغة Python

كان هناك مشروع في مركز الرياضيات وعلوم الحاسب في هولندا، عبارة عن لغة برمجة اسمها ABC. كانت لغة مصنوعة لتعليم البرمجة ولتحل محل لغة Basic (التي تعلم بها البرمجة كثير من أطفال الثمانينات، وإن لم تكن ABC مصممة للأطفال بالضرورة، لكن للمبتدئين بشكل عام).

أثرت هذه اللغة كثيراً على Guido Van Rossum مصمم لغة Python، وكانت سببا من أسباب كون بايثون سهلة التعلم وسهلة القراءة. هذه السهولة ساهمت في جعل اللغة مستخدمة في مجالات كثيرة جداً: التعامل مع الصور، تطبيقات الإنترنت، برامج البحث العلمي الحوسبي Scientific computing. التحكم في الروبوت...

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

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

البرمجة بالأشياء، واجهات GUI، والأجهزة اللوحية.

في السبعينات من القرن العشرين كان هناك مشروع طموح يجري اسمه Dynabook. كانت محاولة للجمع بين التكنولوجيا ونظريات Piaget التربوية: ماذا لو كان للطفل جهاز كمبيوتر متنقل، وشبكة معلومات يحمل منها الكتب، ولغة برمجة سهلة لكي يتعلم الرياضيات والفيزياء والهندسة...الخ بطريقة "حوسبية" أو "خوارزمية"؟

من أجل هذا المشروع تم تطوير فكرة GUI لكي لا يحتاج الطفل لحفظ اوامر command line ولكي يجد تشبيهات سهلة الفهم وصور يضغط عليها.

وتم تقنين وضبط مباديء البرمجة بالأشياء (التي كانت ظهرت في لغة Simula في اوروبا) وتم اختراع لغة Smalltalk، التي أثرت في كل لغات البرمجة الشيئية التي تلتها. Java؟ ++C؟ Python؟ JavaScript؟ كلها متأثرة بطريقة أو أخرى بهذه اللغة.

وأكثر من ذلك: كان Bill Gates و Steve Jobs على علم بهذا المشروع في شبابهما وانبهرا به، وهذا سبب كبير لسعي الأول لمشروع Tablet PC في 2001، وسعي الثاني لإنتاج iPad في الفترة الحالية.

الكمبيوتر المنزلي

على هذه المدونة تجدني أحكي كثيراً عن كمبيوتر صخر وامثاله (Commodore, BBC Micro, Texas..). في نهاية الثمانينات كانت إحدى هذه الشركات - شركة Acorn التي صممت جهاز BBC Micro - تصمم الجيل التالي من أجهزتها. اتخذوا وقتها قرار أن يصمموا معالجاً دقيقاً خاصاً بهم بدلاً من استخدام المكونات الموجودة، وبنوا هذا المعالج على تقنية RISC، وبهذا كان اسمه:
Acorn RISC Machine

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

نظريات Piaget في التعليم

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

It is with children that we have the best chance of studying the development of logical knowledge, mathematical knowledge, physical knowledge, and so forth.

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

ماذا يعني هذا تحديداً؟ وكيف يمكن الاستفادة منه؟ لا أعرف. أنا جديد في هذا الموضوع. لكنه موضوع بدأ بملاحظة الأطفال وكيف يتعلمون.

البرمجة والتعليم والنهضة

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

لن أقول أنني عبقري أو مبتكر: حين كنت أفكر في كلمات لم يخطر ببالي التمكين الحوسبي وهذه الأشياء؛ كنت فقط أفكر في شيء مثل QBasic باللغة العربية ليبرمج به الأطفال.

حين كنت أحلم بـ "اوراق" كانت يدي تؤلمني من لوحة المفاتيح فتمنيت جهاز كمبيوتر بقلم، ثم رأيت مشاريع مثل MIT Design Rationale الذين يعملون منذ سنين (من ضمن ما يبحثون) في التعبير عن الأفكار والتصميمات بالرسم sketching. هؤلاء قوم يبحثون فعلاً، ويعملون فعلاً، ولا يكتفون بالأحلام.

أعتقد أن مجتمعنا على أبواب نهضة كبيرة، فمن لها؟

الأربعاء، 27 يونيو 2012

كلمات والأطفال: بعض النتائج التجريبية (5)

في صورة ملاحظات سريعة، لكن مفيدة:

علمته اليوم control flow باستخدام goto. كانت ظريفة وسلسة. أحد القرارات الصحيحة مني: قدمت مثالاً به أكثر من "علامة" في نفس البرنامج، وقدمت امثلة على goto للأمام (skipping code) وgoto للخلف (repetition). اول مثال كان infinite loop لكي لا احتاج لشرح goto مع if من المرة الأولى.

حين كنت أشرح goto وسألته كيف يتصرف البرنامج هنا، قال "لو شغلنا المراقب العجيب حيحصل كذا.." وقصده "لو عملنا trace للبرنامج حيحصل كذا". شيء مثير للاهتمام جداً!

دع الطفل يجرب التفاصيل غير البرمجية ويستمتع بيها...مثلاً يختار نصوص ظريفة في الرسائل التي يعرضها على الشاشة.

قال لي "امر اقرأ بيجي دايماً قبل اطبع صح؟"، هذا لأن كل البرامج التي اخذها من قبل فيها هذا النمط. حرصت ان اظهر ان البرمجة بها حرية ان تقول أي اوامر بأي ترتيب، وان المهم في النهاية هو ان تحقق هذه الأوامر الهدف المطلوب. وجربت مثالاً امامه يأتي فيه "اطبع" قبل "اقرأ".

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

بدأت أعلمه استخدام الـfunctions (وليس تعريفها) لأسباب عملية: كان البرنامج اكثر من مرة لا يعطي النتيجة الصحيحة بسبب وجود مسافات في أول أو آخر المدخلات، فعلمته دالة تقليم(س).

حاولت اشرح له boolean values، بس حاسس انها abstract أكثر من اللازم. مش متعودين كأشخاص ان "صح" و"خطأ" تكون قيم منفصلة عما تصف.

Nested ifs are a problem too, the concept of "an if statement, like any other statement, can be inside an if'" is not directly understood.

حاولت برضه اعلمه القواميس (وهي مثل الـhashtables)، فهم القواميس نفسها كان سهلاً، لكن كانت هناك مشكلتان: (1) مشاكل في شرح عملية lookup نظراً لتعقيدها وعدم وجود تشبيه مشهور يمثلها (2) لم أجد طريقة لقراءة التعبير س[أ]، فكنت كل مرة اقول "س القوسين أ" أو ما شابه :(

بالمرة اخذته في جولة سريعة في موضوع الـgraphics، إمكانية "اظهار الإحداثيات" في كلمات نفعت جداً. أنا سعيد اني اضفتها. رسمنا مثلثاً بأمر ارسم.خط.

من التجربة أدركت أيضاً أهمية لغة مثل "كلمات"، هناك أشياء كثيرة صممت فيها لأهداف تعليمية، ولا توجد في كثير من اللغات الأخرى،...ونفعت!

الاثنين، 11 يونيو 2012

كيف تكتب كود تبدو عربية؟

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

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

العوامل parameters تكون معرفة لا نكرة
مثلا في هذا الإجراء:
إجراء ارسم(الشكل):
اعرض(الشكل)
لون(الشكل)
حرك(الشكل)
نهاية
أعتقد ان السبب الآن واضح لماذا نفعل ذلك!

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


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


ب = "الشجرة الخضراء في الحديقة الغناء"
اطبع تفصيص(ب)

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


اقرأ.البيانات()
احسب.الحسبة()
اطبع.النتائج()
ماذا لو كانت الدالة معرفة داخل فصيلة class وتعود بقيمة؟ في تلك الحالة استخدم صيغة بدل الاشتمال
❌ أ = الموظف : هات.المرتب()
✅ أ = الموظف: مرتبه()

❌ ص = الصورة: تدوير()
✅ ص = الصورة: تدويرها()
مذكر ام مؤنث؟ حسب اسم الفصيلة، لأنه لو كانت الفصيلة مثلاً "سيارة" فغالباً سوف نتحدث عن الكائنات منها بصورة س، سيارة1، السيارة...الخ، فسنسمي الدوال مثلاً "سرعتها"، "لونها".

عند تعريف بيانات داخل فصيلة fields، تذكر انها ستستخدم بصيغة الإضافة
فصيلة موظف:
له الاسم، المرتب
له المدير، المساعد
تم
م = اقرأ.موظف( )
الاسم المساعد المدير م = "ميشو"

✅ 
فصيلة موظف:
له اسم، مرتب
له مدير، مساعد
تم
م = اقرأ.موظف( )
اسم مساعد مدير م = "ميشو"

بالمناسبة، لا ارى مشكلة في تعبير مثل "س النقطة، ص النقطة"، قياساً على "عين الفعل، لام الفعل" في علم الصرف.

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

ماذا عن اسماء البيانات المكونة من اكثر من كلمة؟

لو كان اسم البيان اصلا في صورة اضافة، مثل "رقم جلوس"، فاستخدمه كما هو:
أ = رقم.جلوس م
لكن لو كان اسماً وصفة، مثل "السرعة النسبية"؟ ليس لدي اجابة محددة. يمكنك ان تستخدمه كما هو:
أ = السرعة.النسبية م
وتقرأها "السرعة النسبية الخاصة بـ م"

أو يمكنك أن تسميه سرعة.نسبية وحين تقرأ السطر التالي:
أ = سرعة.نسبية م
تقرأه "سرعة م النسبية".

القاعدة المختصرة

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

هل لاحظت ان هذا المقال يبدو كمقال عن النحو لا فقط البرمجة؟ هذا لأن كلمات لغة البرمجة العربية الجميلة

الجمعة، 8 يونيو 2012

البيئة المحيطة

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

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

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

كان الشرح الآن عن struct في لغة ++C. عن ان الstruct لا ينشيء بيانات في الذاكرة، لكن عمل variable منها ينشيء فعلاً البيانات. همممم، كنت اشرح الفصائل في توثيق كلمات اليوم السابق، ربما ينبغي ان ابسّط الشرح قليلاً.

دخل الشرح في الheap. هذا مهم... في كلمات، على عكس ++C، كل كائن عبارة عن reference. كيف اشرح الـreference؟

رسم الheap سهل. لكن الreference؟ دائما نرسمها اسهم تشير إلى اماكن في الذاكرة، لكن السهم ليس قيمة! حين أقول أ = ب، فإن قيمة الreference يتم نسخها. كيف اعبر عن هذا في رسمة تعبر عن البرنامج؟ أرقام؟ لا هذا معقد. أريد شيئاً مرئياً.

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

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

الخميس، 24 مايو 2012

كلمات والاطفال: بعض النتائج التجريبية (جزء 4)

(الطفل في هذه التجربة هو نفسه من الجزء 1، الذي ضربت معه مثال عمود النور). قطعت معه هذه المرة شوطاً كبيراً.

- مراجعة على المتغيرات وامر اقرأ -
- امر التخصيص assignment -
- العمليات الحسابية -
- العمليات الحسابية على متغيرات -
- امر إذا -
- امر إذا/وإلا -

مراجعة على المتغيرات وامر اقرأ

عند تعليم الاطفال وجدت دائماً ان امر اقرأ صعب. (هل هذه حقيقة ام انها رواسب استخدامي لاساليب سيئة سابقاً مع نفس هؤلاء الاطفال؟) لذلك فانا دائماً لا افترض انهم تعلموه تماماً من المرة السابقة.

لزيادة التأكيد، عرضت عليه صورة المتغيرات وقلت ان المتغير شيء له اسم وقيمة، وان امر "اقرأ" يصنع متغيراً بطريقة كذا وكذا.

ثم قلت له: اكتب لي برنامجاً يقرأ كلاماً من المستخدم، ثم يطبعه مرتين.

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

القصد، كتب

اقرأ فوزي

(تم تغيير الاسم)

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

قلت له ان يكتبها وفعل. قلت: الآن يجب ان تطبعها مرتين. ماذا ستفعل؟ قال: حاجة مش فاكرها...فيها كاف...

(يبدو انني قد اخبرته من قبل بأمر لكل/تابع). قلت له: لا لا، تخيل انك تريد من شخص ان يفتح الثلاجة مرتين..ماذا تفعل؟ قال: اخبره ان يفتح الثلاجة مرتين! - لكن ماذا لو لم يعرف كلمة "مرتين"، ولم يعرف الاعداد اصلاً؟ بعد قليل من المناقشة عرف ان قصدي ان الاجابة التي قصدتها هي "افتح الثلاجة، افتح الثلاجة".

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

أيضا اخذت معه وقفة عن لوحة المفاتيح والمحرر: زر home يذهب لأول السطر، زر end لنهايته، النسخ ctrl+c، اللصق ctrl+v

قام بنسخ السطر، وتنفيذ البرنامج. فرح جداً بفكرة تكرار السطر = تكرار التنفيذ، وقام بتكراره ثلاث، واربع، وخمس مرات ورؤية النتائج. التفكير البرمجي كما قلت لكم :)

امر التخصيص

الطريقة الثانية لصنع متغير هي امر التخصيص أ = 12. انه يصنع متغيراً ويضع فيه قيمة. قمنا نفس المثال من الجزء السابق:
أ = "اسمي الكامل"
اطبع "أنا "، أ
اطبع "سن "، أ ، " هو 10"

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

ذكرت له الفرق بين الذكر والاستخدام. حين اقول ان كلمة "يا حمار" استخدمت لأول مرة سنة 1885 فأنا لا اشتم احداً، انا اتحدث عن الكلمة نفسها، بينما لو قلتها في سياق آخر قد اكون اشتم احد (ليس مثالا طيباً)، المرة الأولى ذكر والثانية استخدام. كيف نفرق بين الذكر والاستخدام، حتى في الكلام العادي؟ بعلامات التنصيص.

(نعم، انا اتكلم مع الاطفال في الفلسفة، لماذا تسأل؟).

العمليات الحسابية

مثال بسيط جداً:
س = 12
ص = 13
ع = س + ص

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

العمليات الحسابية والمتغيرات

ثم قلت له هذا المثال:

س = 9
س = س + 1

اخبرني إذاً ما سيحدث هنا؟
قال: سوف يصنع متغيراً اسمه س يساوي 9 (لسبب ما الاطفال لا يحبون كلمة "قيمته كذا").
ثم يحسب س + 1
- ثم ماذا؟
ثم يصنع متغير س ويضع فيه النتيجة.

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

كنت اظن التعبير في صورة س = [شيء يحتوي س] سيكون اصعب من هذا، لكنه عرف وحده كيف يقيس "س=س+1" على المثال السابق "ع = س + ص". او ربما تعلم هذا من جلسة سابقة. في الحالتين شيء جيد جداً.

هل احد اسباب هذا التعلم السلس هو انه لم يأخذ جبر بعد، وبالتالي ليس لديه معنى سابق للتعبير "س=س+1"؟

ثم صنعنا هذا المثال:

اقرأ #متغيرطويل
اقرأ # أ
اطبع أ+متغيرطويل
اطبع أ-متغيرطويل
اطبع أ×متغيرطويل
اطبع أ÷متغيرطويل

(يتضح للقاريء المقق انه كان هناك مناقشات جانبية هنا)

بدأ المثال ببرنامج يجمع رقمين ثم طورناه، لأننا مطورون برامج كما تعلمون (أو فنني حاسب آلي كما يذاع هذه الايام). كانت فرصة جيدة ليعرف علامات ×، ÷ على لوحة المفاتيح العربية، كما قلت له ان لغات البرمجة التقليدية فيها علامة الضرب * وعلامة القسمة /، وان الطريقة التقليدية */ والجديدة ×÷ كلتاهما مدعوم في لغة كلمات

امر إذا


وهنا قد حان وقت تعلم شيئاً جديداً (هيييه!). لو عدنا للمثال السابق سوف نجد انه يطبع دائماً ناتج العمليات الحسابية الاربعة. انا اريده ان يسأل المستخدم عن نوع العملية التي يريدها، يعني لو ادخلت له
12
3
÷

فسوف يقول لي 4. قلت له ان الامر إذا يأخذ الصورة الآتية:

إذا [شرط] :
_____
_____
تم

والشرط هو الشيء الذي ينبغي ان يكون صحيحاً لكي يتحقق الاوامر. لو اخبرتك "اذهب للسوق، وإذا كان هناك دجاجاً اشتر منه قفصاً" فالشرط هو "كان هناك دجاج".

الآن هيا نعدل البرنامج. اضفنا (بعد شيء من النقاش) امر اقرأ ثالث للعلامة. ثم كان مطلوب منه وضع الجزء الخاص بالجمع فقط لو كان العلامة المطلوبة هي +.

بعد تفكير منه، وشيء من المساعدة مني، كانت الكود كالآتي:

اقرأ #متغيرطويل
اقرأ # أ
اقرأ ش

إذا ش = "+":
اطبع أ+متغيرطويل
تم

اطبع أ-متغيرطويل
اطبع أ×متغيرطويل
اطبع أ÷متغيرطويل

كان هناك حيرة في "هل نضع علامة زائد بين علامتي تنصيص ام لا" اعادتنا لنقاش الذكر او الاستخدام، كما كان هناك مشاكل في الشرط نفسه (لم يكن يعلم، ولم اكن اخبرته، بالمقارنات فكان الامر في البداية هو إذا ش+ من المتوقع لمن لا يعرف الـsyntax ان يحاول اختراع syntax خاص به...)

قمنا بتنفيذ البرنامج لنجرب هذا الجزء، فأدخل 5+5 في اول سطر. قلت له ان امر اقرأ دائماً يقرأ شيئاً واحداً في السطر ويجب ان يكون المدخل في صورة
5
5
+

....لو اردنا يمكننا ان نغير ترتيب الاوامر ليكون المدخل
5
+
5

لكن لا يمكننا ان ندخلها كلها على نفس السطر.

بدا عليه الاحباط، إنه كان يتوقع ان يكون المدخل في صورة "طبيعية". سأل: وماذا لو اردنا إدخال 5+5؟

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

أليس هذا، أي تلميذي، هو ما يحدث في لغة كلمات نفسها؟ انها تقرأ شيء مثل ش=5+6 فتفصل ش وحدها، وكل رقم وحده، والعلامات وحدها، ثم تقوم بتنفيذ الامر.

كم كنت اود وقتها لو كانت لغة كلمات فيها مشروع Glass compiler الذي كنت اخطط له!! هذا المشروع يقوم باظهار برنامج كلمات في صورة كود، ثم parse tree ، ثم assembly، ثم يظهر تنفيذه.

ما علينا. قمنا، بتجربة البرنامج وشرحت له (او طلبت منه ان يشرح - لا اذكر) كيف يسير جزء "إذا"، ثم بعد مزيد من النقاش، بتعميم البرنامج:

اقرأ #متغيرطويل
اقرأ # أ
اقرأ ش

إذا ش = "+":
اطبع أ+متغيرطويل
تم

إذا ش = "-":
اطبع أ-متغيرطويل
تم

إذا ش = "×":
اطبع أ×متغيرطويل
تم

إذا ش = "÷":
اطبع أ÷متغيرطويل
تم

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

شغلت المراقب وبدأ تتبع كل خطوة من البرنامج. ادخلت له 12، 6، ÷...دخل في اول امر. هل ÷ = +؟ لا، فلم يدخل في الامر. نفس الشيء مع امر "إذا" الثاني"، ثم جرب الثالث ونجح وعرض نتيجة القسمة. ثم جرب الرابع ولم يفعل شيئاً.

جربنا اكثر من عملية حسابية. حرصت ان اقول له انك لو ادخل 5،5،* بينما امر إذا يستخدم × فلن يتحقق الشرط.
برنامج دسم :)

امر إذا/وإلا


كانت الملفات المفتوحة الآن في كلمات كثيرة، وحين قمت بعمل برنامج جديد كان الاسم المخصص له من قبل الـIDE هو new program 9. قلت له هل تعرف كيف تقوم كلمات بهذا؟ هناك متغير يخزن عدد البرامج التي تم انشاؤها، ثم كلما اختار احد امر "جديد" ينفذ سطر كذا = كذا + 1

القصد...

نريد برنامجاً يقرأ رقم يعبر عن السن، ثم لو السن عشر سنوات او اكثر يقول "انت كبير"، ولو اقل يقول "انت صغير".

اقرأ
إذا س >= 10:
اطبع "انت كبير"
تم

إذا س <10:
اطبع "انت صغير"
تم

(جاء البرنامج من مناقشة، وعرفته بـ >=)

أراد ان يلعب قليلاً فغير الكود لتصبح كالآتي:

اقرأ
إذا س >= 10:
اطبع "انت اكبر من الهرم"
تم

إذا س <10:
اطبع "انت صغير جداااا"
تم

قلت له: لكن الهرم عمره - ماذا - خمسة آلاف سنة؟ هيا نفرق بين حالة "اكبر من الهرم" وحالة "كبير" العادية. بالمرة نفرق بين الصغير والصغير جداً.


اقرأ
إذا س >= 5000:
اطبع "انت اكبر من الهرم"
تم

إذا س >= 10:
اطبع "انت كبير"
تم

إذا س <10:
اطبع "انت صغير"
تم

إذا س <2:
اطبع "انت صغير جداااا"
تم

لكنك تعلم عزيزي القاريء ان هذا البرنامج - بالتجربة معه - لم يعط نتائج صحيحة: لو ادخلت ان سنك 12,000 سنة فسوف يقول "انت اكبر من الهرم" و "انت كبير" معاً! نفس الشيء لو قلت ان سنك سنة واحدة، سوف يعطي نتيجتين.

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

لاحظ اننا لو اردنا تطبيق ذلك في الكود الموجودة

إذا س >= 5000:
اطبع "انت اكبر من الهرم"
تم

إذا س >= 10:
اطبع "انت كبير"
تم

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

إذا س >= 5000:
اطبع "انت اكبر من الهرم"
إذا س >= 10:
اطبع "انت كبير"
تم

ثم "إذا" في المنتصف نجعلها "وإلا إذا":

إذا س >= 5000:
اطبع "انت اكبر من الهرم"
وإلا إذا س >= 10:
اطبع "انت كبير"
تم

نفس الشيء مع السن الصغير:

إذا س <10:
اطبع "انت صغير"
وإلا إذا س <2:
اطبع "انت صغير جداااا"
تم

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

لماذا ندخل في المنطق إن كان الكود نفسها تظهر الامر؟ يقال ان الطفل في هذه المرحلة يكون تفكيره operational - لكي يحدث كذا افعل كذا - وليس منطقياً رمزياً. إن كانت الكود، وهي تشبه الـoperational، تقوم بالغرض فسأسكت، على الاقل هذه المرة :)

غيرنا ترتيب الشروط، وجربنا البرنامج.

الخميس، 17 مايو 2012

كلمات والاطفال: بعض النتائج التجريبية (جزء 3)

نتابع مع نفس الطفل المذكور في الجزء الثاني.

كتبت هذه الكود:
اقرأ أ
اقرأ ب

ثم قلت: فلنفترض ان أ يمثل اسم الشخص (مثلاً محمد) و ب يمثل اسم الاب (مثلاً سامي)، فكيف اكتب الاسم الكامل؟

كان الرد الأول: اطبع أ=محمد...

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

لكني الآن افكر في شيء...هناك سبيلين لتفسير الرد: اما اننا مازلنا في الحاجز بين التجريد والتصوير، وهناك لبس متبقي بين فكرة "متغير يعبر عن أي قيمة - مثلا محمد" وبين فكرة "محمد".

التفسير الآخر انها كانت ستجيب إجابة صحيحة، لكنها لم توفق في التعبير -- أي كانت تقصد "اطبع أ، الذي يساوي 'محمد' في هذه الحالة..."

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

القصد، قالت ان السطر الثالث المطلوب هو "اطبع أ ب"..

هذا جيد -- لكن يتبقى الsyntax. اكتبيه إذاً؟

قالت:

اطبع أ ب

صححت لها موضوع الفاصلة:

اطبع أ، ب

ثم جربنا تنفيذ البرنامج، ادخلت له اسمي واسم أبي فقال البرنامج:
محمدسامي

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

نريد ان نطبع الاسم، ثم مسافة فارغة، ثم اسم الاب، كم شيئا نريد ان نطبعه؟
- ثلاثة!
- تمام! وكم فاصلة بينهم؟
- اثنان

حسناً...اكتبي إذا الفاصلة الزائدة، والآن لدينا فراغ نكتب فيه المسافة:

اطبع أ، ، ب

ينبغي الآن ان نكتب مسافة فارغة بين الفاصلتين..ضعيها بين علامتي تنصيص

اطبع أ، " "، ب

وهيا ننفذ البرنامج. ما الاسم الذي تريدين؟
- سلمى
- حسناً، سوف اكتب سلمى
- لكن اكتبها بالياء!
- لماذا؟ هكذا ستكون الكلمة خطأ! سلمي بدلا من سلمى!
- لكننا نريد حرفاً يشبك مع الذي بعده!

اووووه :)

وهكذا تم تجربة أول برنامج.

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

اطبع أ، " "، ب

إن هذا السطر مليء بالتعقيدات التي لا اشعر بها لأني برمجت قبل ذلك بالسي++، جافا...الخ
  • أ و ب هم عناصر خاصة بالكود syntactic elements، لكن عند تنفيذ البرنامج فهي تدل على عناوين لقيم مخزنة في الذاكرة..
  • المسافات في الكود لا تصنع فارقاً، لأن لغة البرمجة بها Lexical analyzer يقوم بعمل skip whitespace، لكن لو كانت المسافة بين علامتي تنصيص، فإنه يكون لها معنى كقيمة، قيمة اثناء تنفيذ البرنامج.
  • امر اطبع يأخذ القيم المطلوب طبعها بينها فواصل وحول النصوص علامات تنصيص، لكن القيم تطبع على الشاشة بدون هذه النقشات.
إن المبرمج دائماً يضطر أن يحوّل انتباهه بين عالمين: عالم الكود في المحرر وعالم القيم اثناء تنفيذ البرنامج، وعليه ان يعلم - بصورة مباشرة او غير مباشرة - انه هناك مفسر للغة يقوم بنقل الكود من احد هؤلاء العالمين إلى العالم المجاور.

هل هذا شيء جيد؟ ام الافضل ان تكون الكود تشبه المخرجات إلى اقصى حد؟ مثلاً في لغة روبي يمكن عمل شيء مثل هذا (لو كانت روبي بالعربية):
اطبع "{أ} {ب}"

أو هنا مثال اوضح للفرق بين طريقة كلمات وطريقة روبي:
اطبع "الاسم هو "، س، " والسن هو "، ص، " يا فتى"
اطبع "الاسم هو {س} والسن هو {ص} يا فتى"

هنا انا لا افصل بين المخرجات بفاصلة، بل اكتبها في صورة نص كبير، لكن حين اريد ان اطبع قيمة متغير (شيء يشبه الكود ولا يشبه النص المعروض كما هو) احيطه بأقواس { }

نعم، طريقة روبي افضل كطريقة برمجية، لكن كطريقة تعليمية؟ ربما وربما لا. كالعادة: يحتاج الامر لتجربة :)

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

ربما بعد ذلك احتاج لعمل نسخة من كلمات يمكن تغيير الـsyntax بها تغييرات طفيفة بدون مجهود كبير - بدون حتى عمل recompile للغة - لتسهيل هذا النوع من التجارب.

الأحد، 13 مايو 2012

كلمات والاطفال: بعض النتائج التجريبية (جزء 2)

هذه المرة جربت مع شخص مختلف عن المقال السابق. هذه لم تكن اول session مع هذا الشخص. مشكلتي قبل ذلك مع معظم الاطفال - كما تذكرون - كانت في المتغيرات، وكيف ان الطفل لا يسمع الكلمة اصلاً وانا اقولها. لو قلت "أمر اقرأ يضع قيمة في متغير" فالطفل سيسمعها "أمر اقرأ يضع قيمة".

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

فقررت الاستعانة بهم. ما هو تعريف المتغير؟ إنه واحد من هؤلاء الكائنات. وما هي صفاته؟ له اسم، ويحمل في داخله قيمة. لم اذكر قابليته للتغير او مثل ذلك: المتغير اسم وقيمة. هكذا صار لدينا شيء نتكلم عنه.

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

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

ماذا يفعل امر '=' ؟ لو قلت س = 12 فإنه يصنع متغير اسمه س والقيمه بداخله 12.

وهل هناك طريقة اخرى لصنع متغير؟ أمر اقرأ! انه يأتي في صورة كلمة اقرأ يليها اسم متغير، ولو اردت قراءة ارقام لابد من علامة # قبل اسم المتغير.

ولكن ماذا يقرأ؟ انه ينتظر أن يكتب المستخدم له شيئاً، وحين اضغط enter يعلم انني قد انتهيت من الكتابة، فيقرأ ما كتبته له.

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

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

الآن ماذا نفعل بالمتغيرات؟؟ سوف نكتب برنامجاً يأخذ رقماً ويعرضه على الشاشة مجموعاً عليه 10. لكني اكتشفت انني لم اشرح فكرة المتغير، بل قد شرحت نصفها! إن نصف المتغير هو التخزين، بينما النصف الآخر هو الاسترجاع.

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

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

...وهكذا يا تلميذتي، لو قلت س + 10، وكان المتغير س يحتوي بداخله القيمة 8، فكأني قلت بالضبط 8 + 10

والآن هل مفهوم هذا البرنامج؟

اقرأ # س
اطبع س + 10

هيا ننفذه!
هل يمكن ان تشرحي لي كل خطوة، ماذا يحدث بالضبط؟

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

الآن لو علمنا ان امر اطبع يمكنه ان يطبع اكثر من شيء لو فصلنا بينهم بفاصلة، اطبع _______ ، ________

...فهل يمكن ان تكتبي برنامج يكتب "عندك كم سنة"؟
ثم ينتظر حتى ادخل له سني
ثم يقول: العام القادم سيكون لديك <السن الصحيح>

كتبت امر اطبع، ثم حين بدأت تكتب امر اقرأ سألت "أنا اقدر اسميه اي اسم صح؟".

بعد تصحيح بعض اخطاء الsyntax، تم تنفيذ البرنامج، ثم طلبت ان تشرحه لي (صرت مصرّاً على هذا حين اعلم احد).

البرنامج الثالث كان يشبه الأول: اقرأ رقم واطبعه مضروباً في 2، وكان بلا اخطاء.

اشعر ان هذه المرة كانت مثمرة.

الخميس، 26 أبريل 2012

An educational tower of programming features

I've been working on an educational programming language for children called Kalimat. One of the ideas about its design is "different concepts for different levels".

Some languages are quite easy to learn, like 80s Basic, while others try to still be easy but add structure or discipline. There's this famous Dijkstra quote (probably made in jest) about Basic ruining children's minds beyond all repair.

Well, Kalimat goes the other way by assuming "all repair" is possible, even a good thing: it starts with a language very similar to QBasic; a child can write interesting programs using only global variables, If conditions, and goto. They can learn with flowcharts if it benefits them, and they can use graphics routines.

We can call this "Level 1". Gradually, these primitive features are shed in favor of more advanced, more abstract features.

Kalimat is Arabic-based, but I'll use a hypothetical English version for the example. This is the typical 'guess the number' game:

n = random(20)
label begin
read "Guess the number:", #g
if g > n :
    print "too high!"
    goto begin
else if g < n :
    print "too low!"
    goto begin
else
    print "good job!"
done

The benefit of this model is that almost everything is visible. The child doesn't need to know the abstractions of procedure calls, or keep in their head the semantics of such calls when thinking about what to do. Commands are executed, sometimes execution jumps. Variables store numbers and sentences, and that's more or less it. Now let's move stuff on the screen or write short quiz programs.

If the child outgrows the kind of programs this model allows, they can learn looping with for and while, and further learn procedure calls. Procedures are separate from functions: this allows the teacher to talks about procedures as "taking some lines of code and giving them a name", and then enter the realm of local variables and parameter passing, and finally talk about "defining our own functions" similar to built-in functions like sin, cos, or random. Let's call that level 2.

Level 3 is OOP. While OOP is now all about abstraction, there's some bit of "concreteness" left: There is no implicit "this" or "self" reference, and like, say, Python this reference is explicit. We also borrow the "send a message" metaphor from Smalltalk. An object can respond to a message or reply to it. Mirroring procedures and functions (I admit this part looks clumsy, needs experimentation to see if it turns to actually make the teaching easier).


class Point:
    has x, y
    responds to draw( )
end

responseOf Point p to draw( ):
    drawPixel (x of p, y of p)
end 

You've probably noticed the usage of cues from natural language to make reading programs flow more naturally. We are not trying to emulate COBOL or SQL; but we believe such cues in the right dosage could help with teaching and conversations about the code. I intend for Kalimat to have something of a canonical reading form, that is when reading code aloud, there is a known way to voice expressions, definitions, ...etc

Anyway, I like the result in the code snippet:  "the response of a point P to 'draw!' is to invoke drawPixel at the x and y of P".

How about other levels? Now that the child's programming knowledge has matured, they can learn more: like for example concurrency. Kalimat uses the CSP model. First we have the launch command that takes a procedure invocation and runs it separately. It's easy to take a program that draws an animated ball and transform it into 50 concurrently moving balls, with the simple addition of a loop and a launch statement.

To coordinate between processes, we have channels and their usual operations: send, receive, and select. Those same channels are also used for the GUI library; in my opinion this simplifies GUI programming in many situations. For example to create a program where the user draws lines you could do:

while true:
    receive p1 from mouseClickChannel( )
    receive p2 from mouseClickChannel( )
    drawLine (x of p1, y of p1)-(x of p2, y of p2)
loop

The flow of execution matches the flow of user actions, no need to separate program state, and in larger programs the need for some design patterns is minimized.

Other than concurrency, Kalimat has (explicit) tail-call elimination for any ambitious teacher who wants to go into functional directions, and currently I'm working an a language-hosted PEG parsing, for people who want the children to create e.g NLP user interfaces, text-adventure games, or whatever they fancy. Kalimat is all about teaching thinking, computer science, and the fun of programming.

I did the design of Kalimat on intuition and from memories from my childhood days of programming, but I've recently found out about Piaget's well-know theory of child intellectual development stages. I'm not so sure about this, since I'm far from being a development psychologist, but there might be some fit between Kalimat's primary, abstraction-free, levels and the operational model of early childhood learning. This might be able to explain the exploding success of 80s Basic among children and allow us to take advantage of some of its characteristics.

Kalimat is open source, hosted on http://code.google.com/p/kalimat

It is Arabic-based, but I hope to have an English version for better discussion and experimentation with the global programming education community, if anyone turns to be interested.

I once made a buggy, half complete English release (here's a screenshot of it). I don't want to publicly release it at this stage, but I'd be happy to give it to anyone who requests. My email ID is samy2004 on Gmail.

الثلاثاء، 17 أبريل 2012

قالوا البرمجة صعبة

احيانا اتحدث عن تعليم الاطفال البرمجة فيقولون: اطفال؟؟ برمجة؟؟

ماذا عن الكبار؟ انظر لطلبة الفرقة الاولى من حاسبات (مش قصدي الدفعة الحالية بالذات) وكيف يتكلمون عن كارثة اسمها البرمجة.

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


ملخص الطريقة:
  • ارسم الشكل في ورقة مربعات 8×8
  • حول كل صف في الرسمة إلى binary
  • حول الارقام إلى hexadecimal باستخدام الجدول المرفق
  • اصنع string مكون من ثمان حروف، كل حرف له ASCII code يمثلها الرقم الhex
  • حول هذا الstring إلى sprite عن طريق الدالة (..)$sprite
نعم يا سيدي، كان الاطفال في سن 12 سنة - ومنهم كاتب هذه السطور - يرسمون على الشاشة بالاكواد الستعشرية.

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

لا احد يقدرني ابداً :]

لم اكن فلتة. كان هناك الاف الاطفال المبرمجين في الوطن العربي وخارجه. اشتريت مرة مجلة برمجة للاطفال اسمها ميكرو، وكانوا يتحدثون عن ماوس من ماركة معينة في product review..كانت معها بعض البرامج منها...محرر للاشباح..

تقول المجلة: "لقد انتهى عصر رسم الاشكال الشبحية بواسطة الاكواد الستعشرية؛ الآن يمكنك فتح البرنامج والتكتكة بالفارة في النقطة التي تريد الرسم فيها."

إنه التقدم يا سادة! إنه التقدم!

ويقول لك البرمجة صعبة..ركزوا يا جماعة البرمجة مش صعبة ولا حاجة :)

الثلاثاء، 3 أبريل 2012

تجربة: لغة برمجة غير مألوفة سهلة التعلم

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

لكن ماذا لو لم يهمني ذلك؟ لو اردت عمل لغة جديدة للاطفال، بالعربية، ويمكنني ان اضحي بمشابهة اللغات الاخرى مقابل سهولة الاستخدام؟

حسناً..اولا سيكون امر التخصيص في صورة ->، بدلا من علامة =، لتحديد اتجاه ذهاب البيانات. أيضاً سيتم تبديل الاتجاهات

س -> ص معناها "ضع س في ص".

ايضاً لن يكون هناك امر اقرأ ولا اطبع، لكن سيكون هناك كائنات Objects تعبر عن الشاشة، لوحة المفاتيح،...الخ

"مرحبا" -> الشاشة
المفاتيح -> س
الماوس ->(س1، ص1)
الماوس ->(س2، ص2)
ارسم.خط (س1،ص1)-(س2،ص2)

هل لاحظت (س1،ص1)؟ هذا لأن اللغة ستدعم تجميعات من القيم tuples. بالمناسبة هكذا تكون عملية التبديل مثلاً سهلة جداً:
(أ، ب) -> (ب، أ)

"خلي أ تبقى ب، وب تبقى أ"

لو أردت ان تكون اللغة object oriented جداً فيمكنني اصلا ان ارسل قيماً كما اريد للشاشة وما شابه..

خ = خط(100، 100، 200، 200)
د = دائرة(100، 100، 75)
خ -> الشاشة
د -> الشاشة

هذه الطريقة تجعل امور معينة سهلة جداً..ماذا لو اردت برنامج يرسم خطوطا باستمرار؟

كرر:
خط(الماوس، الماوس) -> الشاشة
تابع

حسناً....كفانا لعباً بالمعامل ->، ماذا نفعل أيضا؟؟

تعال نصنع طريقة بسيطة لعمل الدوال:

مجموع(أ، ب) = أ + ب.

وطريقة لتعريف الاجراءات:

حرك(أ، بداية، نهاية) =
ارسم(أ، بداية)
انتظر(30)
ارسم(أ، نهاية).

تبدو اللغة نوعاً ما مثل لغة prolog..أليس كذلك؟

مادمنا قد بدأنا في هذا المشوار، تعال نكمل بأن نضيف طريقة مبسطة لتعريف البيانات.

نوع شخص(اسم، سن، عنوان).

شخص(اسم: "حمدي"، سن: 12، عنوان: "الجيزة") -> ح
اسم ح -> الشاشة

ماذا عن الOOP؟ سوف نعرف كل الmethods كأنها رسائل للانواع المختلفة بكلمة في اللغة اسمها معنى

معنى شخص(أ، ب، ج) -> الشاشة =
("هذا شخص اسمه "، أ، "وسنه "، ب) -> الشاشة.

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

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

يحتاج الامر لتجربة. ما رأيك أن تنفذ انت هذه اللغة وتجرب على اطفال؟

نسيت شيئاً...ماذا اسميها؟ من الصعب عليّ أن أفكر في مشروع بدون اسم جيد له..ماذا عن "سهم"؟ بديهي اكثر مما ينبغي؟ سأبقيها هكذا حتى العثور على اسم افضل. أو سمّه انت لو ستنفذه :)

السبت، 31 مارس 2012

كلمات والاطفال: بعض النتائج التجريبية

هناك تجربة تكررت مع طفلين في نفس السن تقريباً (9، 10). حدثتا في ظروف متشابهة، ولعل من المفيد أن احكيهما للإفادة. حفاظاً على الخصوصية لن اذكر مع من جربت، لكن ظروف التجربة كانت كالآتي:
  • لم تكون دروساً منتظمة بل على فترات متباعدة (ولعل هذا هو السبب الاساسي في المشاكل التي حدثت).
  • كنت اعلمهم شفاهة بلا مرجع مكتوب.
  • لكن كل منهما كان لديه نسخة مطبوعة من كتاب تحقيق الذات في كتابة البرمجيات.
لم تكن التجارب بمنهج علمي (many free variables, no control group, insufficient sampling) لكني ارى المعلومات مفيدة جداً.
كان المثال الذي احاول شرحه دائماً هو برنامج "التحية"، الذي يسأل المستخدم عن اسمه ثم يرد بقول "مرحباً يا فلان". وفي الحالتين كانت نفس المشاكل تكرر نفسها.

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

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

موضوع الconcepts عن طريق الحكايات اقوى مما ظننت، ويستحق المزيد من البحث. افكر في عمل video game بها مروة والروبوت، وعليك التحكم فيه بالاوامر ليقوم بأعمال المنزل. ربما يكون هذا اكثر تصويراً من اوامر "اطبع" و"اقرأ".

2- في التجربتين الطفل لم يكن مدركاً جيداً للsyntax الخاص بكلمات، اعتقد انه كان من الافضل بكثير عمل reference من ورقة واحدة للsyntax الخاص بالاوامر الخاصة بكل درس.

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

ينبغي إجراء تجارب اخرى من دروس مبنية على تمارين مكثفة على الاوامر قبل التفكير في البرامج، مع تسجيل الملاحظات.

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

لا احب كلمة متغير كثيراً...إنها تركز على صفة جانبية (انه يمكن أن يتغير) بينما الاهمية الكبرى للمتغير انه اسم يدل على قيمة.

في الfunctional programming، يطلقون على هذا النوع من المتغيرات name bound to a cell..أي ان الاسم - الثابت - يشير إلى موضع تخزين، لكن من الممكن ان اغير ما اخزنه في ذلك الموضع. يعني من الآخر اخذوا تشبيه "اسم على صندوق" وجعلوه مصطلحاً علمياً رسمياً. هذا افضل؛ سأحاول تجنب موضوع "المتغير" بعد ذلك.

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

أيضاً في هذه الكود فإن القطعة البرمجية "أ" لها معنيان:
اقرأ أ
اطبع "مرحبا يا "، أ

المعنى الأول أن "أ" هو مكان التخزين الذي يجب ان تضع فيه ما قرأته من المستخدم. المعنى الثاني هو القيمة المخزنة في مكان التخزين هذا. بصورة رسمية اكثر، المعنى الأول memory address والثاني memory content. هناك لغات مثل لغة لوجو تميز نحوياً بين المعنيين:

... معناها المتغير نفسه

... معناها القيمة المخزنة فيه.

المشكلة اني لا اريد عمل هذا في كلمات لأنها مصممة لتكون سهلة للاطفال لكن قوية بما يكفي ليمكن عمل برامج قوية/تجارية بها، فلابد ان تشبه إلى حد ما اللغات التقليدية. ربما يمكنني عمل لغة "Kalimat mini" للاطفال فقط وتكون اسهل في التعلم. سأفكر.

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

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

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

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

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

ضربت هذا المثل لأوضّح لماذا كان ينبغي استخدام نفس المتغير في السطرين في برنامج "اقرأ كذا/اطبع مرحبا يا كذا"، وصار الامر هكذا واضحاً جداً!

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

في بداية طرحي للمثال كانت العلامة هي عمود النور نفسه، لكن الطفل الذي كنت اعلمه اقترح أن تكون علامة × على احد العواميد لتمييز اي عمود هو. هذا تشبيه ادق لفكرة "اسم المتغير"، أليس كذلك؟ :)

الثلاثاء، 13 مارس 2012

سنوات قطر 3 - انا مبرمج يوجه نفسه بنفسه

(هذا المقال هو الجزء الثاني من جزئين)

انتهى الجزء الأول بأنني قد تعلمت البرمجة. ولكن كيف مارستها وطورت نفسي فيها؟

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

كما كانت الكتب متقدمة تكنولوجياً. هناك كتب تعلمك تركيب sensor ضوءي بالكمبيوتر وصنع برنامج إنذار لو مر شخص او شيء أمام الsensor. هناك كتاب في السلسلة عن البرمجة بالـmachine language...

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

وهناك من يشك حتى هذه اللحظة في موضوع تعليم الأطفال البرمجة. هأ!

المصدر الآخر كان الكتب التي نشرتها شركة العالمية (المسؤولة عن كمبيوتر صخر)..كنت اخذ امي لمحل الكمبيوتر كل فترة لتشتري لي نسخة. هذه صور الاغلفة من مقال سابق كتبته..

كنت قد قرأت وقتها قصة في مجلة ماجد عن لغات الكمبيوتر (بطولة ذكية الذكية إن أردت أن تسأل) وذكروا اسماء بعض اللغات الشهيرة وقتها مثل Fortran, Cobol وذكرت أيضا لغة لوغو. تقول زكية "وهي عبارة عن سلحفاة صغيرة اوجهها بأوامري".

سلحفاة؟ لغة برمجة؟ ما الأمر؟ كان قد جاء مع كمبيوتر صخر كتالوج بكل البرامج التي صممتها "العالمية" له (وكانت كثيرة) منها صخر لوغو. وكانوا يرسمون في الكتالوج سلحفاة.

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

- ولكني أريده!

قالت أمي: هل أنت متأكد أنه سيفيدك؟

- نعم!

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

لم يكن برنامجا عادياً، كان دليل الاستخدام كثيفاً وليس بضع صفحات كالبرامج السابقة. وبدأت أقرأ. إن لغة Logo لها قصة فهي صممت اصلا للتعليم ومبنية على مباديء علمية حديثة اسمها constructionist learning وصممها خبير تعليمي اسمه Seymour Papert، وكانت لغة متطورة بها اشياء لم اكن احلم بها في الbasic:
- subroutine calls
- list data structures
- tail-call elimination
- سلحفاة

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

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



لكن مازالت "الوراثة" ظاهرة :)

جربت أيضا برمجة بعض الاجهزة الغريبة مثل Casio PB 1000، وهو يعتبر جد، جد، جد الPDAs أو الSmartphones الحديثة. كانت الشاشة اربع سطور..أربعة!! هذه صورته الأنيقة جداً. هلم وشاهدها قبل ان تحذفها الويكيبديا :]

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

strlen(s)
char *s;
{
int n=0;
while(*s++) n++;
return n;
}

ما هذا؟؟ هل هي رسالة بالشفرة؟ أين هذا من PRINT, FOR, NEXT؟ أين هذا حتى من اوامر صخر لوغو عالية المستوى مثل اقرأ.حرف أو كرر؟ لا تظنني جاهل في السي او غير معترف بأهميتها، لغة كلمات مكتوبة بالسي++، لكن الآن أعتقد أنك قد عرفت لماذا اللغة اسمها 'كلمات' وليس 'رموز'.

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

سنوات قطر 2 - انا مبرمج :)

هناك ثلاث مراحل للتطور الفكري في حياتي:
  • مرحلة الاهتمام بالنهضة والتاريخ وعلم الاجتماع...الخ، في 2008
  • مرحلة التعرف على الفرق بين البرمجة والcomputer science وانا طالب بالجامعة، وشغفي بالـ discrete math, logic...الخ
  • واهم مرحلة على الإطلاق: تعلمي البرمجة في الصغر والإعجاب بفكرة "المخترع". سنة 1987-1991 في سنوات قطر.

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


ولو اخترت البيسك فكان هذا ما سأراه:


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

المدرسة

كنت في مدرسة بريطانية اسمها Qatar international school، مازالت باقية حتى الآن بل ولها الآن موقع على الإنترنت (ربما عرفوا انني سأدون عنهم). كان المعلمون فيها اجانب إلا قليل من العرب، منهم معلمة الكمبيوتر المصرية. وكانت تعلمنا برمجة أو على الاقل تحاول.

كان الترم كله تقريبا كالآتي:
  1. تكتب هي البرنامج على السبورة.
  2. نكتبه نحن على الكمبيوتر.
  3. غير مسموح لنا ان نعلن اننا انتهينا إلا حين يعمل البرنامج ويعرض النتيجة الصحيحة.
  4. حين تظهر النتيجة الصحيحة، نقضي باقي الحصة في الالعاب على الاجهزة.
ما هي نوعية البرامج؟ كانت نوعان: برامج تعلمك قواعد لغة البيسك بالامثلة، مثل يبرنامج يستخدم امر PRINT بصيغه المتعددة، والنوع الثاني برامج ظريفة أو نافعة مثل برنامج جدول الضرب أو حوار قصير مع المستخدم.

بعد ذلك، ربما الترم الذي يليه - لا اذكر - بدأت المعلمة تقول: يا شباب، الم تلاحظوا في البرامج التي كتبتموها ازواج من الكلمات دائما تأتي مع بعضها؟ إن FOR دائما معها NEXT، بينما IF معها THEN...الم تلاحظوا؟

اعتقد ان هذه الطريقة جيدة جداً على عكس المتوقع. لماذا؟
  • لقد تدربنا تدريبا كاملا على استخدام لوحة المفاتيح حتى حفظت ايدينا PRINT, FOR,...الخ. عدم الكتابة الجيدة كانت عائقا امام الاطفال الذين جربت تعليمهم بكلمات.
  • كان العرض بالامثلة قبل الشرح، وقد رأينا ان البرمجة تعطي نتائج ظريفة مثل جدول الضرب.
  • كان لا يسمح بالالعاب قبل تشغيل البرنامج بصورة صحيحة، فتعلمنا اهمية كتابة كل حرف، رقم، فاصلة بشكل صحيح.
  • كان هناك العاب في الموضوع فلن يكتئب الاطفال كثيراً.
ما الذي جعل المعلمة تستخدم هذه الطريقة التي لا يوجد فيها شرح لمدة ترم كامل؟ لا اظن انها كانت مهملة مثلاً أو غير مهتمة - كانت تصرفاتها ليست تصرفات شخص هكذا..هناك احتمال:
- انها ترى هذه الطريقة هي الصحيحة من مصادر علمية أو تربوية.
- انها تراها الطريقة الصحيحة كاجتهاد شخصي منها.
- انها فعلت ذلك لأنها خافت ان ينفر الاطفال من البرمجة، فقررت ان تمشي بالتدريج جداً.

المهم..كنت في ذلك الوقت اكتب البرنامج واشغله بطريقة ميكانيكية - مثل اغلب الاطفال - حتى العب باقي الحصة. لكن حدث شيئ ما في يوم من الأيام..اكتشفت فكرة جديدة: انا لست مضطراً أن اكتب هذه البرامج بالذات. يمكنني في الواقع ان اغير فيها لإعطاء نتائج مختلفة أو ان استخدم FOR, IF..وما شابه لكي اصنع شيئا من تصميمي. ماذا عن آلة حاسبة مثلاً؟

وهكذا بعد ان صنعنا البرنامج المطلوب في الحصة يقول لي صديقي البانجلادشي الذي يشاركني الكمبيوتر: لقد انتهينا..أي لعبة تريد الآن؟

فأردّ: الا يمكن ان تلعب على جهاز آخر؟ أنا أريد أن أجرب شيئاً...

(لا تنس قراءة الجزء الثاني)

الثلاثاء، 31 يناير 2012

لغة كلمات والمجتمع: لماذا وكيف؟

قديماً كانت البرمجة وسيلة للتعبير عن النفس

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


ووسيلة للتعبير عن النفس للكبار أيضاً

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

لكن الأمور قد تغيرت

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

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

لقد نسينا متعة البرمجة، وقد آن لنا أن نتذكرها.

هيا نغير الأمور للأفضل

أريد إعادة روح الإبداع والتنافس للعالم البرمجي في الوطن العربي. من أجل هذا صنعنا لغة كلمات وهي سلاح أراه قوياً في هذا الأمر. لماذا؟
  • لأنها سهلة الاستخدام وسهلة التعلم، مما يتيح لعدد أكبر بكثير ان يدخلوا مجال البرمجة، وأن يدخلوها في سن مبكر حيث الاهتمام بالاستمتاع والتعبير عن النفس وليس البرمجة لأسباب وظيفية.
  • تتيح البرمجة باللغة العربية، مما يسمح لشريحة أوسع من المجتمع أن تدخل في هذا العالم، وتزيح عائقاً أمام كثير من الاطفال الاذكياء لكن لم يتعلموا الانجليزية.
  • الإبداع بالرسوم والألعاب سهل في كلمات: لا تحتاج إلى تركيب مكتبة مثل SDL أو DirectX أو PyGame كي تبدأ: كل شيء موجود بالفعل كجزء من الأوامر الاساسية للغة.
  • اللغة نفسها قوية وتنمو بنمو قدرات المبرمج، فيمكن استخدام اوامر صغيرة اولا لتكون لغة شبيهة بلغة البيسك القديمة، ثم الانتقال بعد ذلك للإجراءات، البرمجة الكائنية OOP، وحتى البرمجة المتوازية!
  • بيئة التطوير الخاصة باللغة مصممة من أجل التعليم، ونفخر أن يكون بها إمكانات خصيصاً لذلك:
  1. يمكنك أن تنسخ الكود بصيغة HTML مع ضبط المحاذاة وتلوين الكلمات، لتضع الكود بسهولة على مدونتك أو على منتدى تعليمي.
  2. يمكن كذلك نسخها بصيغة Wiki لكي يتعاون الناس على تصميم كتب لها عبر الإنترنت.
  3. بها إمكانية تتبع سير البرنامج أثناء تنفيذه (المراقب العجيب).
  4. بها debugger.
...وهناك إمكانات اخرى يخطط لها.

لم ننس الجانب الاجتماعي أيضاً

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

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

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

الاثنين، 23 يناير 2012

الطريق المعلوم لشرح مثال مثلث النجوم

هب انك معيد في كلية الحاسبات تعلم البرمجة لطلبة مبتدئين، وتريدهم أن يكتبوا برنامجاً رسم مثلثاً مقلوباً من النجوم ارتفاعه 5:

*****
****
***
**
*

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

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

عملاً بمبدأ اظهر ولا تخبر تعالوا الآن نقدم طريقة مختلفة لشرح هذا المثال.

اولا سوف نصف المشكلة:
  • نريد كتابة برنامج يكتب مثلث نجوم ارتفاعه 5 سطور.
  • أدوات حل المشكلة لدينا هي (أ) امر cout الذي يعرض اشياء على الشاشة. (ب) امكانية الانتقال لسطر جديد بإضافة endl في امر cout وأخيراُ (ج)ادوات التحكم البرمجية التقليدية من loops، conditions، variables

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

الآن نفكر في الحل:

(من اجل التبسيط لن اكتب "طقوس" برامج السي من #include وما شابه)

من الواضح أنه مهما كان شكل الحل فإنه لابد أن يكتب سطوراً على الشاشة. ولابد أن يكون عدد هذه السطور خمسة:

main() {

for(int i=0; i<5; i++) {

draw_line();

}}

مهلاً! لا يوجد في السي++ أمر اسمه draw_line! انا تخيلت ان هذا الأمر موجود لسبب بسيط جداً هو أنني أريد ان احل المشكلة على أجزاء. سوف نفكر الآن فقط في عدد السطور المطلوبة ثم لاحقاً نفكر في شكل كل سطر.

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

الآن نكتب الأمر المطلوب:

void draw_line() {

// ???????

}

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

ما هو عدد النجوم المطلوب؟ اوه ألا تعرف؟ إنه n بالطبع!

void draw_line() {

for(int j=0; j<n; j++) {

cout << "*";

}

cout << endl;

}

هل تذكر الabstraction؟ لقد افترضت في الجزء السابق ان البرنامج "يعرف" كيف يرسم السطر. الآن أنا افترض انه "يعرف" كم نجمة ترسم في كل سطر. الآن نفكر: من أين سنأتي بهذه القيمة؟ نعود مرة اخرى ونتأمل الشكل:

*****
****
***
**
*

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

main() {

int n = 5;

for(int i=0; i<5;i++) {

draw_line();

n--;

}

}

الكود تبدو طبيعية جدا: طول السطر يبدأ بخمسة، ثم نرسم السطر، ثم ننقص الطول بمقدار واحد، وهكذا. لكن الدالة draw_line هي التي تحتاج لطول السطر، وليس main!

لا بأس، من أجل هذا هناك إمكانية تمرير الparameters. أولا نعدل main:

main() {

int n = 5;

for(int i=0; i<5;i++) {

draw_line(n);

n--;

}

}

وثانيا نعدل draw_line:

void draw_line(int n) {

for(int j=0; j< n; j++) {

cout << "*";

}

cout << endl;

}

وانتهى البرنامج! ماذا لو لم يكن الطالب قد اخذ الfunctions من قبل؟ مشكلة قابلة للحل: يمكن تقديم الfunctions قليلاً أو استخدام comments هكذا:

main() {

for(int i=0; i<5;i++) {

// draw line

}}

ثم التساؤل "ماذا نكتب مكان التعليق" بدلاً من "كيف نكتب الدالة المطلوبة".

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

ارجو أن يفيد هذا المثال من هو في موقف تعليمي.