الاثنين، 31 ديسمبر 2012
السبت، 29 ديسمبر 2012
الخميس، 27 ديسمبر 2012
الأحد، 23 ديسمبر 2012
حين تتحقق خطط المدى البعيد
حين كنت أعمل في صنع لغة كلمات سنة 2010 كانت هناك بعض القرارات التي اتخذتها في تصميم وتنفيذ اللغة. بعض هذه القرارات قد بدأت تظهر آثاره الآن!
الخميس، 20 ديسمبر 2012
الأحد، 16 ديسمبر 2012
رسم الصيغ الرياضية بلغة كلمات (الجزء الثاني)
الهدف من المشروع هو برنامج يرسم الصيغ الرياضية، مثلاً يقول له المستخدمم س^2 + 5 فيرسم البرنامج شكل الـparabola المعروف.
- في الجزء الأول تحدثنا عن الإعراب، الدالة التي تأخذ نصاً مثل 12+13 وتعود بالمصفوفة ["+"، 12، 13] التي تمثل ما يسمى بشجرة الإعراب parse tree.
لو كنت قد قرأت الجزء الأول فأنت إذاً جاهز الآن لنختتم هذه السلسلة.
حساب قيمة التعبير
حسناً. لدينا الآن شجرة إعراب مثل 100 أو ["+"، س، 12]، ماذا نفعل بها؟ نريد دالة اسمها تقييم تأخذ الشجرة وتعود بالقيمة التي تعبر عنها.
- لو كانت "الشجرة" في صورة قيمة عددية، نعود بتلك القيمة.
- لو كانت الشجرة هي المتغير س (كقيمة نصية)، فإننا لا نستطيع أن نفعل شيئاً بأنفسنا، لذلك سوف نقدم عاملاً إضافياً parameter للدالة تقييم به قيمة س المطلوبة.
- لو كانت الشجرة في صورة مصفوفة مثل ["+"، أ، ب] سوف نقوم بالآتي:
- ناد الدالة تقييم مع الفرع الأيمن أ لحساب قيمته
- ناد الدالة أيضاً مع الفرع الأيسر ب
- نفذ العملية الحسابية وارجع بالنتيجة.
كل هذا يعطينا الكود التالية، الدالة تأخذ الشجرة "ت" وقيمة "س" المحددة من البرنامج، وتحسب قيمة الصيغة الرياضية:
دالة تقييم (ت، س): إذا ت ~ ["+"، ؟أ، ؟ب]: ارجع ب: تقييم (أ، س)+ تقييم (ب، س) وإلا إذا ت ~ ["-"، ؟أ، ؟ب]: ارجع ب: تقييم (أ، س)- تقييم (ب، س) وإلا إذا ت ~ ["×"، ؟أ، ؟ب]: ارجع ب: تقييم (أ، س)× تقييم (ب، س) وإلا إذا ت ~ ["÷"، ؟أ، ؟ب]: مقام = تقييم (ب، س) إذا مقام <> 0 : ارجع ب: تقييم (أ، س)÷ مقام وإلا : اطبع "خطأ: قسمة على صفر" ارجع ب: 0 تم وإلا إذا ت ~ ["^"، ؟أ، ؟ب]: ارجع ب: أس (تقييم (أ، س)، تقييم (ب، س)) وإلا إذا ت ~ "س" : ارجع ب: س وإلا : -- لو وصلنا إلى هنا فقيمة ت هي اصلا عدد ارجع ب: ت تم نهاية
لاحظ كيف استخدمنا مرة أخرى عملية المطابقة ~ لتسهيل الموضوع. الآن نحن جاهزون للرسم. أولاً نكتب إجراءاً مساعداً يرسم المحاور س، ص
إجراء ارسم.المحاور (): ارسم.خط (400، 0)- (400، 599) ارسم.خط (0، 300)- (799، 300) نهاية
الآن سوف نكتب الدالة التي ترسم فعلاً. خطتنا كالآتي:
الدالة سوف تأخذ عاملين: من.س و إلى.س، لكي نستطيع أن نقول مثلاً ارسم س^2 من س=-4 إلى س=4
سوف تقوم الدالة بالآتي:
- كرر بحيث يبدأ المتغير أ بالقيمة من.س وينتهي بالقيمة إلى.س، وكل مرة نضيف قيمة صغيرة إلى أ:
- احسب ص عن طريق استدعاء تقييم لحساب قيمة الصيغة الرياضية، واعطها قيمة المتغير س تساوي العداد أ
- سوف نرسم خطاً صغيراً بين كل نقطتين:
- لو كان هذا أول تكرار، فلا يوجد لدينا سوى نقطة واحدة. خزن قيمة أ في المتغير أ.قديم وقيمة ص في المتغير ص.قديم
- لو لم يكن أول تكرار، فنحن لدينا النقطة (أ، ص) والنقطة (أ.قديم، ص.قديم). سنرسم خطاً بينهما
هذا يعطينا الكود :
إجراء ارسم.الدالة (التعبير، من.س، إلى.س): أ = من.س أ.قديم = لاشيء ص.قديم = لاشيء مقياس.س = 20 مقياس.ص = 15 كرر مادام أ <= إلى.س : ص = تقييم (التعبير، أ) إذا ليس أ.قديم = لاشيء : س1 = - أ × مقياس.س + 400 ص1 = - ص × مقياس.ص + 300 س2 = - أ.قديم × مقياس.س + 400 ص2 = - ص.قديم × مقياس.ص + 300 ارسم.خط (س1، ص1)- (س2، ص2)، 4 تم أ.قديم = أ ص.قديم = ص أ = أ + 0.1 انتظر (30) تابع نهاية
لاحظ أننا نضرب الإحداثيات في بعض الثوابت ليكون لدينا مقياس رسم، وننتظر 30 مليثانية بين كل رسمة لكي نرى الدالة وهي تُرسم بسلاسة على الشاشة. لاحظ أن هذه الطريقة تفترض بعض الخصائص للدالة المطلوب رسمها (مثلاً أنها متصلة continuous).
لا يبقى إلا ان نربط كل المكونات ببعضها!
اقرأ "الصيغة؟"، الصيغة اقرأ "من؟"، # أ اقرأ "إلى؟"، # ب الصيغة = تبديل (الصيغة، " "، "") الشجرة = تعبير (الصيغة) ارسم.المحاور () ارسم.الدالة (الشجرة، أ، ب)
ماذا فعلنا؟
- قرأنا الصيغة من المستخدم (وقيم س التي سنبدأ وننتهي بها)
- حذفنا المسافات من الصيغة
- أعربناها لنحصل على شجرة الإعراب بواسطة الدالة تعبير
- رسمنا المحاور
- نادينا ارسم.الدالة وأعطيناها الشجرة وقيم من.س وإلى.س
- ارسم.الدالة سوف تنادي تقييم باستمرار لكي تحسب قيمة الصيغة عند كل قيمة لـ س
- ....وترسم الخطوط المطلوبة!
كم سطراً كتبنا؟ للأسف تجاوزنا حاجز المائة قليلاً: 109. لكن لو حذفنا السطور الفارغة بين تعريفات الدوال...الخ سيكون العدد أقل من المائة.
أقل من مائة سطر، تقوم بما قد يحتاج مئات الأسطر في لغات أخرى...
يمكنك عزيزي القاريء أن تجرب عمل نسخة متقدمة من البرنامج تضيف إمكانية استخدام الدوال مثل جتا، جا، أو تضيف الثابتين ط (π) و هـ (e) أوتقدم بعض المساعدة للمستخدم. لمَ لا تجرب؟ :)
رسم الصيغ الرياضية بلغة كلمات
نريد برنامجاً يأخذ صيغة رياضية ويرسمها!
وإمعاناً في التحدي، نريد أن نكتب هذا البرنامج في مائة سطر من الكود أو أقل. هل سنقدر يا ترى؟ أعتقد أنك ستستمتع كثيراً بهذا المقال عزيزي القاري.
هذه الرسمة اسمها "شجرة الإعراب" أو parse tree، وهي تشبه الشجرة لأن لها جذراً وفروعاً. كيف نعبر عن هذه الشجرة بقيمة في لغة كلمات؟ هناك طرق كثيرة: يمكن أن نستخدم الفصائل والكائنات، أو المصفوفات، أو القواميس...فلنستخدم طريقة بسيطة: سوف تكون كل شجرة عبارة من مصفوفة من ثلاثة عناصر: العملية الحسابية نفسها، والقيمتان التي تجري عليهما العملية. مثلاً إن قمنا بإعراب التعبير "4+5" سوف نحصل على المصفوفة ["+"، 4، 5]. لو أعربنا القيمة النصية "(4+5)×2" سوف نحصل على ["×"، ["+"، 4، 5]، 2]. أي أن الشجرة هي عملية ضرب بين ["+"، 4، 5] وبين 2.
لو افترضنا أننا - بطريقة ما - لدينا دالة تأخذ نصاً من المستخدم وتعود لنا بهذه الشجرة، فإنه من السهل أن نحسب القيمة المطلوبة من الشجرة: نحسب الفرع الأيمن، ثم نحسب الفرع الأيسر، ثم نقوم بتطبيق العملية الحسابية.
لاحظ أن الإعراب لا يعود دائماً بمصفوفات..لو أعربنا مثلاً التعبير 12 فإن "الشجرة" ما هي إلا العدد 12 نفسه.
رائع. الآن علينا أن نفكر: مم تتكون الصيغ الرياضية؟ سوف نسمي الصيغة في صورتها النهائية "تعبير حسابي"، وهذا التعبير مكون من حد واحد أو أكثر. ما الذي يفصل بين الحدود في التعبير الواحد؟ علامات الجمع والطرح. أي أن التعبير يكون في صيغة حد1 + حد2 - حد3....الخ، أو مكون من حد واحد.
في السطر الأخير نجرب القواعد الجديدة. سوف يطبع مفسر كلمات لك القيمة......لاشيء :(
لماذا؟ في الواقع سوف تقوم كلمات بإعراب التعبير، لكننا لم نطلب منها أن تعطينا شجرة إعراب، لذلك سوف تعود لنا بالقيمة لاشيء. هيا نغير ذلك الموقف! فلنبدأ بشيء بسيط كالأرقام:
لاحظ شيئين:
في السطر الأول قلنا خانة:أ رقم:ب ، هذه طريقتنا في إعطاء أسماء للمكونات التي نعربها.
أننا قلنا في أخر السطر => أ + ب ، وهذه طريقتنا في أن نعود بقيم أثناء الإعراب
يمكن أن نقرأ السطر كله كالآتي: الرقم مكون من خانة هي أ، ورقم أصغر هو ب، وحين نجدهما نعود بالقيمة أ + ب.
لاحظ أن أ و ب هما نصان، فلو أعربنا الرقم "123" فسيكون أ = "1" و ب يساوي "23" (الأرقام تقرأ من اليسار) وبهذا يكون الرقم كله هو أ + ب = "123"
ماذا عن السطر الثاني الذي يقول أو خانة؟ نحن لم نخبره بأي قيمة يعود، لكن لو رأى مفسر كلمات قاعدة ما هي الا استدعاء قاعدة أخرى (نحن لم نفعل سوى استدعاء "خانة") فسيعود بنفس القيمة الآتية من القاعدة المستدعاه. كأني بالضبط قلت أو خانة:أ => أ
ماذا عن السطر خانة = من "0" إلى "9"؟ حين تكون القاعدة ما هي إلا قيمة نصية فالقيمة العائدة منها هي نفس القيمة النصية.
إذاً قد عرفنا ماذا يرجع من رقم. ماذا عن شيء مثل تعبير؟
باللغة البشرية:
التعبير هو حد اسمه أ، ثم علامة "+"، ثم تعبير أصغر اسمه ب ، وفي تلك الحالة ارجع بالمصفوفة ["+"، أ، ب]
أو هو حد اسمه أ، ثم علامة "-"، ثم تعبير أصغر اسمه ب، وهنا ارجع بالمصفوفة ["-"، أ، ب]
أو هو مجرد حد اسمه أ، وفي تلك الحالة ارجع بذلك الحد.
سهل، أليس كذلك؟ بنفس الطريقة نعدل "حد" و "أس" و"أولي" ليكون لدينا القواعد كلها:
لاحظ أننا في هذا الجزء التالي قد حولنا الرقم من قيمة نصية إلى قيمة عددية:
سوف تصنع لنا كلمات دالة اسمها "تعبير" (لأننا قد سمينا القواعد "تعبير")، وهذه الدالة إن أعطيناها نصاً فستعطينا شجرة إعراب. جرب أن تضيف هذا السطر في آخر البرنامج:
اطبع تعبير("12+13×14")
سوف يظهر المخرج التالي:
["+"، 12، ["×"، 13، 14]]
في الواقع الكود السابقة ليست دقيقة لأن العمليات الرياضية + - ÷ × بها خاصية left associativity. أي أن تعبير مثل 1-2-5 المفروض أن يكون (1-2)-5، لكن برنامجنا يعتبره 1-(2-5)، أي أنه يعود بالشجرة ["-"، 1، ["-"، 2، 5] بدلاً من الشجرة الصحيحة وهي ["-"، ["-"، 1، 2]، 5]
سبب المشكلة هو أنه كان المفروض في القواعد أن نقول:
تعبير = تعبير + حد
ولكننا قلنا
تعبير = حد + تعبير
للأسف لا يمكن استخدام الطريقة الصحيحة في هذا الإصدار من كلمات بسبب مشكلة اسمها left recursion (هناك طرق لحل تلك المشكلة لكنها لم تطبق في كلمات بعد). لذلك علينا الحذر: البرنامج سيعطي نتائجاً خاطئة في المدخلات أ-ب-ج أو أ÷ب÷ج، ولكن يمكننا استخدام الأقواس في تلك الحالات.
على العموم قد أنهينا جزء إعراب الصيغ الرياضية، ومازال لدينا 70 سطراً أيضاً!
وإمعاناً في التحدي، نريد أن نكتب هذا البرنامج في مائة سطر من الكود أو أقل. هل سنقدر يا ترى؟ أعتقد أنك ستستمتع كثيراً بهذا المقال عزيزي القاري.
الجزء الأول: كيف نفهم الصيغة الرياضية؟
يوجد في علوم الحاسب ما يسمى parsing (الإعراب). لو أعربنا التعبير الحسابي س^2+5 فسيكون لنا النتيجة التالية:
لو افترضنا أننا - بطريقة ما - لدينا دالة تأخذ نصاً من المستخدم وتعود لنا بهذه الشجرة، فإنه من السهل أن نحسب القيمة المطلوبة من الشجرة: نحسب الفرع الأيمن، ثم نحسب الفرع الأيسر، ثم نقوم بتطبيق العملية الحسابية.
لاحظ أن الإعراب لا يعود دائماً بمصفوفات..لو أعربنا مثلاً التعبير 12 فإن "الشجرة" ما هي إلا العدد 12 نفسه.
رائع. الآن علينا أن نفكر: مم تتكون الصيغ الرياضية؟ سوف نسمي الصيغة في صورتها النهائية "تعبير حسابي"، وهذا التعبير مكون من حد واحد أو أكثر. ما الذي يفصل بين الحدود في التعبير الواحد؟ علامات الجمع والطرح. أي أن التعبير يكون في صيغة حد1 + حد2 - حد3....الخ، أو مكون من حد واحد.
كيف نعبر عن هذا رياضياً؟ هناك طريقة اسمها Parse Expression Grammar أو PEG تسمح لنا أن نكتب القاعدة بهذه الطريقة:
تعبير = حد "+" تعبير (هذه قاعدة 1#)
أو حد "-" تعبير (قاعدة 2#)
أو حد (قاعدة 3#)
ما معنى هذا الوصف؟ معناه أن التعبير يمكن أن يكون حداً واحداً أو مجموعة من الحدود يفصل بينها + و -. مثلاً يمكن أن نبدأ بالحد "2×3". نحن نعرف أن هذا تعبير من قاعدة #3 من التعريف. ماذا عن 1 + 2×3؟ نعرف أن هذا أيضاً تعبير (من قاعدة #1 التي تقول أن حد + تعبير = تعبير، وبالتالي سمحت لنا بإضافة حد في المقدمة). ماذا عن 5 - 1 + 2×3؟ هذا أيضاً تعبير من جزء 2# من التعريف
لو شعرت أن الأمر صعب فلا تقلق: الموضوع ببساطة هو recursion مثلما تعلمت في البرمجة. المسألة هي أن التعبير يمكن أن يكون حداً أو يكون حد + حد + حد ....، أو حد + حد - حد - حد ....الخ.
ماذا عن الحدود نفسها؟ الحد هو "أس" واحد أو أكثر تفصل بينها علامات ×، ÷
هذه كلها حدود:
5^2 × 6
6 ÷ 3
18
6^س
كيف نكتبها بطريقة PEG؟ هكذا:
حد = أس "×" حد
أو أس "÷" حد
أو أس
وهي كما ترى نفس طريقة التعبيرات. لاحظ أن قيمة عادية مثل "18" نعتبرها أس رغم غياب علامة ^، مثلما اعتبرنا أن 12 هو تعبير رغم غياب علامة + أو -
ماذا عن الأسس؟ هي ببساطة مجموعة من واحد أو أكثر من التعبيرات الأولية يفصل بينها علامة ^. كل هذه أسس:
س^2
2^س
س^2^3
س
12
والقاعدة (كما خمنت) هي:
أس = أولي "^" أس
أو أولي
ولكن ما هو التعبير الأولي؟؟؟ إنه رقم، أو المتغير س، أو تعبير بين أقواس:
أولي = "س"
أو رقم
أو "(" تعبير ")"
لم يبق ما نعرّفه سوى الأرقام نفسها. الرقم هو خانة واحدة أو أكثر (الخانة هي الرمز 0، أو 1، أو 2...إلى 9).
رقم = خانة رقم
أو خانة
خانة = من "0" إلى "9"
الرقم هو خانات لا يفصل بينها شيء. لهذا لم نقل مثلاً رقم = خانة + رقم بل قلنا مباشرةً رقم = خانة رقم....
ولكن ما فائدة كل هذا؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟
فائدة كل هذا أن لغة كلمات بها محرك إعراب جاهز. لو قدمت له قواعد في صورة PEG سوف يقدم لك إمكانية إعراب أي نص يتماشى مع هذه القواعد. مثلما نعرّف في كلمات دالة أو إجراء أو فصيلة، يمكننا أيضاً أن نعرّف قواعداً. انظر للكود الآتية:
قواعد تعبير : تعبير = حد "+" تعبير أو حد "-" تعبير أو حد حد = أس "×" حد أو أس "÷" حد أو أس أس = أولي "^" أس أو أولي أولي = رقم أو "س" أو "(" تعبير ")" رقم = خانة رقم أو خانة خانة = من "0" إلى "9" نهاية
اطبع تعبير ("1+2+3")
في السطر الأخير نجرب القواعد الجديدة. سوف يطبع مفسر كلمات لك القيمة......لاشيء :(
لماذا؟ في الواقع سوف تقوم كلمات بإعراب التعبير، لكننا لم نطلب منها أن تعطينا شجرة إعراب، لذلك سوف تعود لنا بالقيمة لاشيء. هيا نغير ذلك الموقف! فلنبدأ بشيء بسيط كالأرقام:
رقم = خانة:أ رقم:ب => أ + ب أو خانة خانة = من "0" إلى "9"
لاحظ شيئين:
في السطر الأول قلنا خانة:أ رقم:ب ، هذه طريقتنا في إعطاء أسماء للمكونات التي نعربها.
أننا قلنا في أخر السطر => أ + ب ، وهذه طريقتنا في أن نعود بقيم أثناء الإعراب
يمكن أن نقرأ السطر كله كالآتي: الرقم مكون من خانة هي أ، ورقم أصغر هو ب، وحين نجدهما نعود بالقيمة أ + ب.
لاحظ أن أ و ب هما نصان، فلو أعربنا الرقم "123" فسيكون أ = "1" و ب يساوي "23" (الأرقام تقرأ من اليسار) وبهذا يكون الرقم كله هو أ + ب = "123"
ماذا عن السطر الثاني الذي يقول أو خانة؟ نحن لم نخبره بأي قيمة يعود، لكن لو رأى مفسر كلمات قاعدة ما هي الا استدعاء قاعدة أخرى (نحن لم نفعل سوى استدعاء "خانة") فسيعود بنفس القيمة الآتية من القاعدة المستدعاه. كأني بالضبط قلت أو خانة:أ => أ
ماذا عن السطر خانة = من "0" إلى "9"؟ حين تكون القاعدة ما هي إلا قيمة نصية فالقيمة العائدة منها هي نفس القيمة النصية.
إذاً قد عرفنا ماذا يرجع من رقم. ماذا عن شيء مثل تعبير؟
تعبير = حد:أ "+" تعبير:ب => ["+"، أ، ب] أو حد:أ "-" تعبير:ب => ["-"، أ، ب] أو حد:أ => أ
باللغة البشرية:
التعبير هو حد اسمه أ، ثم علامة "+"، ثم تعبير أصغر اسمه ب ، وفي تلك الحالة ارجع بالمصفوفة ["+"، أ، ب]
أو هو حد اسمه أ، ثم علامة "-"، ثم تعبير أصغر اسمه ب، وهنا ارجع بالمصفوفة ["-"، أ، ب]
أو هو مجرد حد اسمه أ، وفي تلك الحالة ارجع بذلك الحد.
سهل، أليس كذلك؟ بنفس الطريقة نعدل "حد" و "أس" و"أولي" ليكون لدينا القواعد كلها:
قواعد تعبير : تعبير = حد : أ "+" تعبير : ب => ["+"، أ، ب] أو حد : أ "-" تعبير : ب => ["-"، أ، ب] أو حد : أ => أ حد = أس:أ "×" حد:ب => ["×"، أ، ب] أو أس:أ "÷" حد:ب => ["÷"، أ، ب] أو أس:أ => أ أس = عامل:أ "^" أس:ب => ["^"، أ، ب] أو عامل عامل = رقم:أ => كعدد (أ) أو "س" أو "(" تعبير : أ ")" => أ رقم = خانة : أ رقم : ب => أ + ب أو خانة خانة = من "0" إلى "9" نهاية
لاحظ أننا في هذا الجزء التالي قد حولنا الرقم من قيمة نصية إلى قيمة عددية:
عامل = رقم:أ => كعدد (أ)
قد يبدو الأمر صعباً، لكنه أسهل بكثير من كتابة برنامج يأخذ أي صيغة رياضية ويفهمها بطريقة يدوية. القواعد كلها أخذت 30 سطراً لكنها وفرت عشرات أو مئات السطور المطلوبة لعمل مثل هذا البرنامج في لغات أخرى.
سوف تصنع لنا كلمات دالة اسمها "تعبير" (لأننا قد سمينا القواعد "تعبير")، وهذه الدالة إن أعطيناها نصاً فستعطينا شجرة إعراب. جرب أن تضيف هذا السطر في آخر البرنامج:
اطبع تعبير("12+13×14")
سوف يظهر المخرج التالي:
["+"، 12، ["×"، 13، 14]]
في الواقع الكود السابقة ليست دقيقة لأن العمليات الرياضية + - ÷ × بها خاصية left associativity. أي أن تعبير مثل 1-2-5 المفروض أن يكون (1-2)-5، لكن برنامجنا يعتبره 1-(2-5)، أي أنه يعود بالشجرة ["-"، 1، ["-"، 2، 5] بدلاً من الشجرة الصحيحة وهي ["-"، ["-"، 1، 2]، 5]
سبب المشكلة هو أنه كان المفروض في القواعد أن نقول:
تعبير = تعبير + حد
ولكننا قلنا
تعبير = حد + تعبير
للأسف لا يمكن استخدام الطريقة الصحيحة في هذا الإصدار من كلمات بسبب مشكلة اسمها left recursion (هناك طرق لحل تلك المشكلة لكنها لم تطبق في كلمات بعد). لذلك علينا الحذر: البرنامج سيعطي نتائجاً خاطئة في المدخلات أ-ب-ج أو أ÷ب÷ج، ولكن يمكننا استخدام الأقواس في تلك الحالات.
على العموم قد أنهينا جزء إعراب الصيغ الرياضية، ومازال لدينا 70 سطراً أيضاً!
الخميس، 6 ديسمبر 2012
تحقق الإمكان الإنساني
تعلمنا في الفيزياء أن التداخل قد يكون بناءاً أو هداماً [constructive or destructive interference]. قد يدعم بعض الموجات بعضاً وتكون بناءة، أو يصد بعضها بعضاً وتكون هدامة. وقد عشت في هذا العالم كثيراً لأرى التداخلات الهدامة. ولقد مللت.
كم من عبقري كان ليرفع مستوى العلم في البلد، بل في العالم، فقط لو وجد التعليم الكافي، أو الرعاية الصحية، أو من يدعمه، أو من يشجعه؟ لكن البلد قد حكمها اللصوص والسفاحين والطماعين.
كيف كان ليصبح شكل المجتمع لو توقف الناس عن التناحر والسرقة والاستبداد، وبدأ كل شخص يتفرغ ليجيب على سؤال: ما هو الحد الأقصى للإمكان الإنساني؟ ما أفضل شيء نستطيع أن نبنيه، وأفضل علم نستطيع أن نبحثه، وأفضل فكر نستطيع أن ننتجه؟ ما هو الإمكان الحقيقي لنا؟
كيف نحقق العدل والرخاء؟ كيف نواجه الأمراض والتلوث والتصحر؟ ماذا نفعل بشأن المخلوقات التي كادت تنقرض؟
كيف نحل المشاكل الاجتماعية؟ ماذا نفعل تجاه ارتفاع نسب الطلاق، وتمرد الأبناء على آبائهم؟ هل هناك أطفال يُضايقون أو يعتدى عليهم في المدارس؟ كيف نحل تلك المشاكل؟
هل المدن جميلة (وليس فقط نظيفة)؟ هل الناس سعداء بالمشي فيها؟ ما الذي يسبب التعاسة للناس؟ هل يحبون وظائفهم أم يعملون فيها على مضض؟
ولكن قبل أن يحدث ذلك علينا أن نفكر في أسئلة اخرى:
- كيف تتصرف مع الحاكم المستبد؟
- كيف تتصرف مع الصراعات السياسية التي نتجت بعد خلع الحاكم المستبد؟
- كيف تتصرف مع الخونة الذين يريدون العودة للسلطة بأي شكل؟
- كيف تتصرف مع كل عنيد لا يصغى للعقل، وتقدم له الحجه تلو الحجة فلا يناقشك في صحة حجتك أو خطئها، بل يستكبر ويعتبر أن المشكلة الحقيقية أنك لم تفهم قصده، ويبدأ في "شرح" كلامه لك مرة أخرى؟
وإني لم أر مثل ذلك أشياء كبيرة تعتمد على أشياء صغيرة. قبل أن نبدأ في التفكير في التقدم العلمي أو العدالة الاجتماعية عليك أولاً أن تقنع فلاناً أن ينزل من بيته وينتخب، أو أن يراجع قرار كذا، أو ألا يتحيز لكذا. ملايين المعارك الصغيرة كل يوم بين كل أفراد الوطن، وتشعر بالخسارة مع كل حوار يطول وينتهي بعناد، وبعض الناس يأتيه إغراء أن يستبد برأيه هو الآخر، وأن يحكم على الناس أنهم أغبياء ويحتاجون من يجبرهم لا من يحاورهم؛ بعضهم يستسلم للإغراء وآخر يمسك نفسه ويقول لا؛ لن أحل الاستبداد باستبداد.
لا بأس؛ هذا جزء من الرحلة. هذا جزء من البناء، هذا جزء من "تحقق الإمكان الإنساني". الأشياء الكبيرة تعتمد على الأشياء الصغيرة، حقيقة علمية.
ذات مرة نشر عالم اسمه زويكي بحثاً عما سماه "النجمة النيوترونية" Neutron star. كان يقدم تنبؤا عن وجود هذا النوع من النجوم، وكان تنبؤه استناج من خصائص الذرات والنيوترونات. لا تستطيع أن تفصل بين سلوك النجوم/الثقوب السوداء...الخ وبين سلوك الذرات والجزيئات.
وماذا عن الـDNA؟ تركيب لا يرى إلا بالميكروسكوب، ويؤثر على خصائص الكائن الحي وشكله ولونه وطوله وقصره وقوته وضعفه.
الذي يحدث هذه الأيام، من الحوارات والمظاهرات والاتفاقات والمقالات والتصريحات، هو أن الـDNA الخاص بالمجتمع يتشكل. وإني أشتاق لأن أرى المجتمع الوليد وخصائصه.
Labels:
arabic-posts,
nahda,
philosophy,
society
الاثنين، 3 ديسمبر 2012
البوست عبارة عن كود
هذا مثال ورقة بارنسلي، من فرع من الرياضيات يسمى chaos theory، من المدهش حقاً الشكل المعقد الذي يمكن أن يظهر من هذه الكود البسيطة.
لتنفذ هذا البرنامج:
لتنفذ هذا البرنامج:
- حمل لغة كلمات من http://www.kalimat-lang.com
- قم بنسخ ولصق الكود بالكامل في محرر كلمات
- قم بتنفيذ البرنامج
س مشترك ص مشترك س = 0 ص = 0 علامة البداية ارسم.نقطة (س × 30 + 50، ص × 30 + 50)، 5 الاختيار = عشوائي (100) إذا الاختيار = 0 : تحويل1 () وإلا إذا الاختيار < 86 : تحويل2 () وإلا إذا الاختيار < 93 : تحويل3 () وإلا : تحويل4 () تم اذهب إلى البداية إجراء تحويل1 (): س = 0 ص = 0.16 × ص نهاية إجراء تحويل2 (): س = 0.85 × س + 0.04 × ص ص = - 0.04 × س + 0.85 × ص + 1.6 نهاية إجراء تحويل3 (): س = 0.2 × س - 0.26 × ص ص = 0.23 × س + 0.22 × ص + 1.6 نهاية إجراء تحويل4 (): س = - 0.15 × س + 0.28 × ص ص = 0.26 × س + 0.24 × ص + 0.44 نهاية
Labels:
arabic-posts,
fun,
kalimat,
math,
programming
السبت، 1 ديسمبر 2012
الرد على ما يسمى نقداً لكلمات
قام أحد المبرمجين العرب بإنشاء لغة برمجة جديدة تسمى إبداع. إنشاء لغات برمجة عربية جديدة هو أمر مرحب به، وقد قلت ذلك كثيراً على مدونتي. مصمم اللغة يفترض أن لغته هي أفضل لغة عربية حالياً، ولكي يفعل ذلك قام بمقارنتها بباقي اللغات العربية الموجودة، ومنها بالطبع كلمات، وبالطبع كانت كلمات خاسرة في مقارنته :)
يقول المؤلف:
(وهو كما ترى كرم من المؤلف؛ إن كلمات بالنسبة له هي أفضل ما في "فترة ما قبل ظهور إبداع" التي يتحدث كأنها بداية عصرٍ جديد من البرمجة)
من حق أي إنسان أن ينتقد كلمات (أنا شخصياً أنتقدها كثيراً) لكن المشكلة أنه قد قدم نقداً عشوائياً غريباً، وقد قرأت نقده هذا سابقاً ولم أردّ، لكن الوضع صار يمكن أن يؤثر على كلمات: إن هذا المبرمج سوف يقوم بتسويق لغته في كل مكان، ومع كل مرة يروج فيها لها سوف يأتي ذكر المقارنة بكلمات (وهو يقدم لها نقداً مطولاً في التوثيق الرسمي للغة)، وإني أخشى أن يصدقه الناس في كلامه ويعرضون عن تجربة لغة كلمات بسبب الانتقادات الغريبة التي يوجهها.
وأخشى أن يظن الناس أن لغته هي ما يمثل حالة لغات البرمجة العربية حالياً (وبالتالي يظنون أنه حال سيء)، مما يؤثر على انتشار فكرة لغات البرمجة العربية عموماً.
ما علينا، هيا نرد على انتقاداته. أريد أولاً أن أنبه لشيء، هو أن كلمات ليست اللغة الوحيدة التي تم انتقادها بهذا الشكل من قبل مصمم "إبداع"، بل إنه قد قدم نفس المعاملة للغات مثل سي شارب أو بايثون أو جافا أو...أو...، وفي الواقع حظ كلمات كان أفضل من كل هؤلاء. أنظر مثلاً كيف يتكلم عن خاصية interfaces الموجودة في لغات مثل جافا أو سي شارب:
وهكذا نجده يتحدث عن إمكانيات مثل struct, union, pointer, delegate في لغات ++C ,و #C وجافا وكلها في نظره خدعة أو فقاعة أو تفاهة أو مناورة تسويقية، ويبدو أن الكاتب يخلط بين عدم معرفته لأسباب وجود الإمكانية وبين عدم ضرورة وجودها أصلاً.
مرة أخرى: ما علينا. هيا نرى نقده للغة كلمات إذاً...
يقول الكاتب:
هي من اللغات ذات التنويع المتغير ،dynamically typed و هذا النوع لا يصلح لكتابة البرامج التي تحتا ج إلي سرعات فائقة في التنفيذ، و كذلك ُيساعد في الوقوع فللي أخطاء التكويد المنطقية لأن اللغة لا تقيد المتغير بنوع بيانات معيَن.
بدايةً الكاتب يمزج بين العيوب والأذواق - هناك لغات كثيرة جداً ناجحة وفي نفس الوقت dynamically typed مثل لغة Python أو JavaScript. هذا ليس "عيباً" في كلمات إلا بقدر ما هو عيب في بايثون: أنها لا تلائم احتياجات معينة أو أنواع معينة من التطبيقات وليس عيباً مطلقاً.
عموماً أنا أنوي على المدى الطويل تقديم static type checking في لغة كلمات. لماذا لم أصنعه حالياً؟ لأن الـtype systems صعبة!
إضافة الـgenerics ليست أمراً سهلاً، وكذلك الـtype variance. وهناك أخطاء في هذه الأمور وقع فيها مصممو لغة الجافا نفسها ولابد من التعامل مع هذه الأشياء بحذر.
(طبعاً هي أمور لا تؤرق كاتب لغة إبداع لأنه قدم type system بسيطة جداً في لغته).
ثم يقول:
اللغة تحتوي علي مكونين في غاية التشابه هما: الإجراء، الدالة. و كان يجب ألا تضم اللغة مكونين متشابهين كهذين علي الإطلاق؛ حيث أن هذا لا داعي له منطقياً، بل و يسبب تشابهُّما الشديد إلي البلبلة عند المبتدئين.
يا لثقته! أنظر كيف يستخدم كلمات قوية مثل "على الإطلاق"، "لا داعي منطقياً"، بينما هو مرة أخرى لا يقدم سوى رأياً شخصياً. هل جاء بمبتدئين وعلمهم البرمجة بكلمات، ثم رأى البلبلة؟ هل أجرى هذه التجارب بمعايير علمية؟ لقد جعلتُ الإجراءات بهذه الطريقة كمحاولة مني لتسهيل تعلم اللغة بإعطاء أسماء مختلفة لمفاهيم مختلفة؛ لكني لم أدّع "هكذا" أن هذا هو المنطقي، بل قلت أنها تجربة وأن تدريب الأطفال وملاحظتهم هو الذي سيخبرنا بالنتيجة.
ثم يقول:
اللغة تحتوي علي مكوني: المصفوفات arrays، القواميس dicts. و كان بالإمكان ضم هذين المكونين في مكونٍ واحد، و هذا سيسهل علي المبتدئين كثيراً لأنه يضم المكونات المتشابهة التكوين و الوظيفة في مكونٍ واحدٍ أشمل
هل من عيوب اللغة أنها لم تفعل ما "كان بالإمكان"؟ هناك أشياء كثيرة ممكنة، ومصمم اللغة يختار ما ينفذه منها. عموماً معظم اللغات تفصل بين الإمكانيتين ماعدا بعض اللغات مثل Lua توحّد بينهما كما يريد. ولو نظرت للأمر من ناحية algorithmic complexity أو من ناحية الـperformance بشكل عام لوجدت مميزات للفصل بينهما.
ثم يقول (قمت بتجميع بعض العيوب لتسريع الأمر):
الدوال و الإجراءات في كلمات ضعيفة البنية؛ فهي تعيد خرجاً واحداً فقط، ولا يمكن إعطاء قيمٍ ابتدائيةٍ لمدخلات الدالة أو الإجراء.
..الفصائل في كلمات ثرثارة؛ فلكي تُعَّرِّف محتويات فصيلةٍ ما فيجب عليك كتابة كلامٍ كثير.
كلمات مصنوعة لتعليم الأطفال البرمجة، لذلك قمت بتبسيط الsemantics والsyntax، وتكرار بعض التركيبات لتذكير المبرمج بفائدتها. مرة أخرى مسألة آراء شخصية، ومسألة ملاءمة الأداة للهدف.
تحتوي كلمات علي أوامر "علامة" و "اذهب إلى"، و اللذين يكافئان "Goto"
وما المشكلة؟ لو تحدثت عن الناحية التعليمية فمصمم لغة SmallBasic من مايكروسوفت يدافع عن goto (المصدر هنا)، ومن الناحية الاحترافية فهذا الأمر مستخدم أحياناً في Linux Kernel.
تعبير الحلقات التكرارية ضعيفٌ للغاية، حيث لا يتيح تغيير مقدار الخطوة في العملية إلا بقيمة زيادةٍ مقدارها 1 (و قد نبه م. محمد سامي إلي أنه ينوي تدارك هذه الجزئية في الإصدارات القادمة بإذن الله عز و جل)
أتمنى أن يحدث الكاتب معلوماته، لأن هذه الإمكانية قد تم تداركها بالفعل منذ أشهر.
المكتبة حتي الآن مبنيةٌ داخل المفسر نفسه، و ليست قائمةً بذاتها و ليست مكتوبةً بلغة كلمات نفسها بل بلغة الـ++C مع مكتبة الـQT. لا يوجد مترجمٌ قويٌ للغة حتي الآن، و كل ما يوجد هو مفسرٌ يتيح لنا استخدام بعض مكونات مكتبة الـQT،
ما المشكلة في كون اللغة مفسرة لا مترجمة؟ هناك لغات من أنجح اللغات في العالم ومفسرة. أما فكرة أنه لا يمكن سوى استخدام مكونات Qt فهو أيضاً غير صحيح (ربما تكون معلومات الكاتب قديمة). كلمات يوجد بها إمكانية FFI التي تتيح استدعاء إجراءات مكتوبة بالسي من مكتبات DLL. وهنا نراها تنادي دوالاً من مكتبات لينكس ومن مكتبات Win32 API.
الشيء الوحيد الذي ينقص هو إمكانية تنفيذ برامج كلمات بدون الحاجة إلى بيئة تطوير كلمات، وهو أيضاً شيء قد أضفته لكنه لا يعمل حالياً بسبب بعض الأخطاء، وأتمنى أن يأتي الدور لإكماله. [تحديث: ثم إعادة تشغيل خاصية عمل الملفات التنفيذية في كلمات منذ إصدارة يناير 2013]
لا يمكن كتابة أوامرٍ بلغة التجميع assembly في برنامج كلمات
إني أتعجب من بعض الأشياء التي يراها صاحب النقد عيوباً. بحسب علمي لا توجد لغات بها هذه الإمكانية إلا لغات قليلة جداً مثل Delphi, C ولغة التجميع نفسها. ولكن انتظر! إن صاحب المقال يذكر سبب افتراضه أن هذا عيباً:
...و هذا يجعلها غير قادرةٍ علي: إنتاج مكتبتها باستخدامها هي نفسها.
كلام خطأ؛ راجع إمكانية FFI
....إنتاج برامجٍ تعمل علي المتحكمات الميكروئية microcontrollers
في تلك الحالة استخدم سي أو لغة التجميع
...كتابة البرمجيات الأخري التي نحتاج فيها إلي التعامل مع الذاكرة مباشرةً، مثل، أنظمة التشغيل، المترجمات compilers، المفسرات interpreters.
عجيب أن يأتي هذا من مبرمج يرفض فكرة الـpointers. عموماً يمكن كتابة مترجمات، مفسرات، بلغات خالية من إمكانية لغة التجميع، مثلاً مترجم لغة سي شارب هو نفسه مكتوب بالسي شارب، ومترجم الجافا مكتوب بالجافا، وهناك مترجمات ومفسرات كثيرة مكتوبة بالبايثون.
أيضاً هناك نظم تشغيل مكتوبة بالجافا والسي شارب. كيف تصرف كاتبوها؟ غالباً ينظرون إلى ما يحتاج للكتابة بلغة التجميع ويضعونه في مكتبة خارجة ثم يقومون باستدعائه من البرنامج الأصلي.
اللغة لم تستقر في تصميمها بعد، و لم توضع لها خطةٌ توضح حجمها النهائي المتوقع حتي الآن، ونحن نري بالفعل أن اللغة يزيد حجمها يوماً بعد يوم.
هناك نوع من "خارطة الطريق" قد كتبته لكلمات (وهو هنا لمن يريد الاطلاع عليه)، لكني أشعر أن الكاتب لديه حساسية من موضوع ازدياد حجم اللغات. حتى أنه يعيب على لغة سي شارب أن حجمها يزداد في كل إصدارة.
هناك بالفعل من يريد أن يحافظ على لغته صغيرة وminimalist وأنا أتفهم مزايا هذا الموضوع (مثلا لغة Google Go تفعل هذا)، لكن يبدو أن الكاتب يرى النمو والتطور عيباً شاملاً في أي لغة.
اللغات مثل سي شارب تتطور لأن عالم البرمجة يتغير: سي شارب صار فيها إمكانيات functional programming حين بدأ نجم البرمجة المتوازية يعلو، وإمكانية Linq ظهرت لتسهيل التعامل مع البيانات المتنوعة في البرامج الكبيرة (ولأسباب أخرى)، وإمكانية generators ظهرت لتبسط أشياءً كانت من قبل معقدة، وإمكانية async/await ظهرت مرة أخرى من أجل البرمجة المتوازية.
سي شارب لغة معقدة لأنها مصنوعة لحل مشاكل معقدة.هل كان يمكن أن تكون أبسط؟ ربما. لكن لا نستطيع أن نقول أن تطورها المستمر هو عيب خطير فيها لابد أن يتوقف.
الوحدات في كلمات تتيح لنا إنشاء إجراءاتٍ و دوالٍ حرة (أي لا يلزم أن تكون مكتوبةً في فصيلةٍ ما)، و هو ما يجعلنا نعاني من مساوئ نموذج البرمجة الإجرائية في المشاريع الكبيرة، و هذه الصفة تناقض مبدأ الأمن الذي نريده في لغة البرمجة القوية.
يبدو أن الكاتب قد غير رأيه في هذا الموضوع لأن هذه الإمكانية (بحسب ما فهمت) موجوده في لغته أيضاً، لكنه لم يحذف هذا الجزء من نقد كلمات وأرجو أن يحدّث ما كتب.
الوصول إلي مكونات الفصيلة غير مُوَحَّد الشكل، فنحن نصل إلي المتغير الداخلي للكائن عن طريق كتابة اسمه ثم كتابة اسم الكائن بعده، أما الإجراءات و الدوال فيجب أن يكتب اسم الكائن أولاً، ثم نتبعه بعلامة : ثم اسم الإجراء أو الدالة.
الكاتب يتحدث عن إمكانية أن أقول
س = سيارة جديد
لون سقف س = "أزرق"
ويريد بدلاً من ذلك أن تكون:
س_سقف_لون = "أزرق"
...وذلك لكي يكون هناك توافق بين field access و method call.
أنا اخترت أن تكون الكود طبيعية أكثر وأشبه باللغة العادية.
ليس فيها تعبيرٌ لمعالجة الاستثناءات exception handling.
هذه الإمكانية مؤجلة حتى أجد طريقة لصنعها بشكل أفضل (وليس مجرد محاكاه لما يحدث في لغات موجودة)، لأني أرى شكلها الحالي معقداً.
لا تحتوي علي مكونٍ هامٍ للغاية هو التعدادات enumerations
ماشي. ولا لغات كثيرة أخرى.
لا تحتوي علي فكرة ال ) delegatingالموجود في لغات مثل الل#.(C
ممم...كلمات حالياً (في أحدث إصداراتها) بها فكرة first class functions وهي مشابهة في الأهداف لما صنعت من أجله فكرة delegates. ربما يمكن الآن في كلمات إضافة الـdelegates في مكتبة.
نلاحظ أن الكاتب قد رفض فكرة الـdelegates كما هي في سي شارب ولم يضفها إلى لغته، لكنه قال أن لديه إمكانية أخرى في لغته هي ما يسميه "الإجراء الحر" تعوض النقص.
لست متأكداً أنني قد فهمت مقصده، لكن الإجراءات الحرة لا تقوم بدور الdelegates!
الكاتب يركز على جزء أن الـdelegate تسمح باستدعاء أكثر من إجراء مرة واحدة؛ لكن ليس هذا الاستخدام الأساسي لها: الاستخدام الأساسي هو فكرة تخزين إجراء في متغير أو تمريره لإجراء آخر. هل يمكن صنع هذا في لغة إبداع؟ لا أعتقد.
كما قلت، توجد في لغة إبداع بعض الأفكار الجيدة، وربما تتطور مع الوقت وتصير لغة قوية، لأ أريد أن يكون مقالي هذا دافعاً للكاتب (أو لأي مبرمج عربي آخر) أن يترك المحاولة لعمل لغات برمجة عربية.
لكني لا أحب أسلوبه في تحطيم اللغات الأخرى بدون خلفية علمية وايضاً بدون معرفة لأسباب القرارات المتخذة في كل لغة. ولا أحب الثقة الغريبة في أسلوبه حيث كل كلامه "منطقي" أو "بالتأكيد" بينما الأمر لا يخرج عن الآراء الشخصية.
وقد ابتعدت شخصياً عن الهجوم على أية لغة برمجة عربية أخرى مفضلاً أن أجعل كلمات تتحدث عن نفسها، ولكن هذا المقال هو حالة خاصة. هذا نقد غير منصف للغة كلمات يوزع رسمياً مع لغة برمجة عربية أخرى!
وعموما اشعر بالضيق من كتابة هذا المقال..ومازلت أفكر هل أبقي عليه أم أخفيه من المدونة..
يقول المؤلف:
بداية: ُتعد لغة كلمات أرقي لغات البرمجة العربية في فترة ما قبل ظهور إبداع علي الطلق، فلها الميزات التالية...
(وهو كما ترى كرم من المؤلف؛ إن كلمات بالنسبة له هي أفضل ما في "فترة ما قبل ظهور إبداع" التي يتحدث كأنها بداية عصرٍ جديد من البرمجة)
من حق أي إنسان أن ينتقد كلمات (أنا شخصياً أنتقدها كثيراً) لكن المشكلة أنه قد قدم نقداً عشوائياً غريباً، وقد قرأت نقده هذا سابقاً ولم أردّ، لكن الوضع صار يمكن أن يؤثر على كلمات: إن هذا المبرمج سوف يقوم بتسويق لغته في كل مكان، ومع كل مرة يروج فيها لها سوف يأتي ذكر المقارنة بكلمات (وهو يقدم لها نقداً مطولاً في التوثيق الرسمي للغة)، وإني أخشى أن يصدقه الناس في كلامه ويعرضون عن تجربة لغة كلمات بسبب الانتقادات الغريبة التي يوجهها.
وأخشى أن يظن الناس أن لغته هي ما يمثل حالة لغات البرمجة العربية حالياً (وبالتالي يظنون أنه حال سيء)، مما يؤثر على انتشار فكرة لغات البرمجة العربية عموماً.
ما علينا، هيا نرد على انتقاداته. أريد أولاً أن أنبه لشيء، هو أن كلمات ليست اللغة الوحيدة التي تم انتقادها بهذا الشكل من قبل مصمم "إبداع"، بل إنه قد قدم نفس المعاملة للغات مثل سي شارب أو بايثون أو جافا أو...أو...، وفي الواقع حظ كلمات كان أفضل من كل هؤلاء. أنظر مثلاً كيف يتكلم عن خاصية interfaces الموجودة في لغات مثل جافا أو سي شارب:
...إذاً يتَضح لنا أن هذه الميزة ما هى إلا فقاعة فارغة ُتقال و لا حقيقة لها، و السبب الوحيد لقولها هو دعم السبب الحقيقى لاستخدام الواجهات، و جعل الأسباب كثيرة تملأ ناظرى القارئ لتقِنعه بيسر بأهميتها، فى حين أنه ليس هناك سبب حقيقى َيستحق النظر إلا واحداً أو اثنين على الأكثر...
وهكذا نجده يتحدث عن إمكانيات مثل struct, union, pointer, delegate في لغات ++C ,و #C وجافا وكلها في نظره خدعة أو فقاعة أو تفاهة أو مناورة تسويقية، ويبدو أن الكاتب يخلط بين عدم معرفته لأسباب وجود الإمكانية وبين عدم ضرورة وجودها أصلاً.
مرة أخرى: ما علينا. هيا نرى نقده للغة كلمات إذاً...
يقول الكاتب:
هي من اللغات ذات التنويع المتغير ،dynamically typed و هذا النوع لا يصلح لكتابة البرامج التي تحتا ج إلي سرعات فائقة في التنفيذ، و كذلك ُيساعد في الوقوع فللي أخطاء التكويد المنطقية لأن اللغة لا تقيد المتغير بنوع بيانات معيَن.
بدايةً الكاتب يمزج بين العيوب والأذواق - هناك لغات كثيرة جداً ناجحة وفي نفس الوقت dynamically typed مثل لغة Python أو JavaScript. هذا ليس "عيباً" في كلمات إلا بقدر ما هو عيب في بايثون: أنها لا تلائم احتياجات معينة أو أنواع معينة من التطبيقات وليس عيباً مطلقاً.
عموماً أنا أنوي على المدى الطويل تقديم static type checking في لغة كلمات. لماذا لم أصنعه حالياً؟ لأن الـtype systems صعبة!
إضافة الـgenerics ليست أمراً سهلاً، وكذلك الـtype variance. وهناك أخطاء في هذه الأمور وقع فيها مصممو لغة الجافا نفسها ولابد من التعامل مع هذه الأشياء بحذر.
(طبعاً هي أمور لا تؤرق كاتب لغة إبداع لأنه قدم type system بسيطة جداً في لغته).
ثم يقول:
اللغة تحتوي علي مكونين في غاية التشابه هما: الإجراء، الدالة. و كان يجب ألا تضم اللغة مكونين متشابهين كهذين علي الإطلاق؛ حيث أن هذا لا داعي له منطقياً، بل و يسبب تشابهُّما الشديد إلي البلبلة عند المبتدئين.
يا لثقته! أنظر كيف يستخدم كلمات قوية مثل "على الإطلاق"، "لا داعي منطقياً"، بينما هو مرة أخرى لا يقدم سوى رأياً شخصياً. هل جاء بمبتدئين وعلمهم البرمجة بكلمات، ثم رأى البلبلة؟ هل أجرى هذه التجارب بمعايير علمية؟ لقد جعلتُ الإجراءات بهذه الطريقة كمحاولة مني لتسهيل تعلم اللغة بإعطاء أسماء مختلفة لمفاهيم مختلفة؛ لكني لم أدّع "هكذا" أن هذا هو المنطقي، بل قلت أنها تجربة وأن تدريب الأطفال وملاحظتهم هو الذي سيخبرنا بالنتيجة.
ثم يقول:
اللغة تحتوي علي مكوني: المصفوفات arrays، القواميس dicts. و كان بالإمكان ضم هذين المكونين في مكونٍ واحد، و هذا سيسهل علي المبتدئين كثيراً لأنه يضم المكونات المتشابهة التكوين و الوظيفة في مكونٍ واحدٍ أشمل
هل من عيوب اللغة أنها لم تفعل ما "كان بالإمكان"؟ هناك أشياء كثيرة ممكنة، ومصمم اللغة يختار ما ينفذه منها. عموماً معظم اللغات تفصل بين الإمكانيتين ماعدا بعض اللغات مثل Lua توحّد بينهما كما يريد. ولو نظرت للأمر من ناحية algorithmic complexity أو من ناحية الـperformance بشكل عام لوجدت مميزات للفصل بينهما.
ثم يقول (قمت بتجميع بعض العيوب لتسريع الأمر):
الدوال و الإجراءات في كلمات ضعيفة البنية؛ فهي تعيد خرجاً واحداً فقط، ولا يمكن إعطاء قيمٍ ابتدائيةٍ لمدخلات الدالة أو الإجراء.
..الفصائل في كلمات ثرثارة؛ فلكي تُعَّرِّف محتويات فصيلةٍ ما فيجب عليك كتابة كلامٍ كثير.
كلمات مصنوعة لتعليم الأطفال البرمجة، لذلك قمت بتبسيط الsemantics والsyntax، وتكرار بعض التركيبات لتذكير المبرمج بفائدتها. مرة أخرى مسألة آراء شخصية، ومسألة ملاءمة الأداة للهدف.
تحتوي كلمات علي أوامر "علامة" و "اذهب إلى"، و اللذين يكافئان "Goto"
وما المشكلة؟ لو تحدثت عن الناحية التعليمية فمصمم لغة SmallBasic من مايكروسوفت يدافع عن goto (المصدر هنا)، ومن الناحية الاحترافية فهذا الأمر مستخدم أحياناً في Linux Kernel.
تعبير الحلقات التكرارية ضعيفٌ للغاية، حيث لا يتيح تغيير مقدار الخطوة في العملية إلا بقيمة زيادةٍ مقدارها 1 (و قد نبه م. محمد سامي إلي أنه ينوي تدارك هذه الجزئية في الإصدارات القادمة بإذن الله عز و جل)
أتمنى أن يحدث الكاتب معلوماته، لأن هذه الإمكانية قد تم تداركها بالفعل منذ أشهر.
المكتبة حتي الآن مبنيةٌ داخل المفسر نفسه، و ليست قائمةً بذاتها و ليست مكتوبةً بلغة كلمات نفسها بل بلغة الـ++C مع مكتبة الـQT. لا يوجد مترجمٌ قويٌ للغة حتي الآن، و كل ما يوجد هو مفسرٌ يتيح لنا استخدام بعض مكونات مكتبة الـQT،
ما المشكلة في كون اللغة مفسرة لا مترجمة؟ هناك لغات من أنجح اللغات في العالم ومفسرة. أما فكرة أنه لا يمكن سوى استخدام مكونات Qt فهو أيضاً غير صحيح (ربما تكون معلومات الكاتب قديمة). كلمات يوجد بها إمكانية FFI التي تتيح استدعاء إجراءات مكتوبة بالسي من مكتبات DLL. وهنا نراها تنادي دوالاً من مكتبات لينكس ومن مكتبات Win32 API.
الشيء الوحيد الذي ينقص هو إمكانية تنفيذ برامج كلمات بدون الحاجة إلى بيئة تطوير كلمات، وهو أيضاً شيء قد أضفته لكنه لا يعمل حالياً بسبب بعض الأخطاء، وأتمنى أن يأتي الدور لإكماله. [تحديث: ثم إعادة تشغيل خاصية عمل الملفات التنفيذية في كلمات منذ إصدارة يناير 2013]
لا يمكن كتابة أوامرٍ بلغة التجميع assembly في برنامج كلمات
إني أتعجب من بعض الأشياء التي يراها صاحب النقد عيوباً. بحسب علمي لا توجد لغات بها هذه الإمكانية إلا لغات قليلة جداً مثل Delphi, C ولغة التجميع نفسها. ولكن انتظر! إن صاحب المقال يذكر سبب افتراضه أن هذا عيباً:
...و هذا يجعلها غير قادرةٍ علي: إنتاج مكتبتها باستخدامها هي نفسها.
كلام خطأ؛ راجع إمكانية FFI
....إنتاج برامجٍ تعمل علي المتحكمات الميكروئية microcontrollers
في تلك الحالة استخدم سي أو لغة التجميع
...كتابة البرمجيات الأخري التي نحتاج فيها إلي التعامل مع الذاكرة مباشرةً، مثل، أنظمة التشغيل، المترجمات compilers، المفسرات interpreters.
عجيب أن يأتي هذا من مبرمج يرفض فكرة الـpointers. عموماً يمكن كتابة مترجمات، مفسرات، بلغات خالية من إمكانية لغة التجميع، مثلاً مترجم لغة سي شارب هو نفسه مكتوب بالسي شارب، ومترجم الجافا مكتوب بالجافا، وهناك مترجمات ومفسرات كثيرة مكتوبة بالبايثون.
أيضاً هناك نظم تشغيل مكتوبة بالجافا والسي شارب. كيف تصرف كاتبوها؟ غالباً ينظرون إلى ما يحتاج للكتابة بلغة التجميع ويضعونه في مكتبة خارجة ثم يقومون باستدعائه من البرنامج الأصلي.
اللغة لم تستقر في تصميمها بعد، و لم توضع لها خطةٌ توضح حجمها النهائي المتوقع حتي الآن، ونحن نري بالفعل أن اللغة يزيد حجمها يوماً بعد يوم.
هناك نوع من "خارطة الطريق" قد كتبته لكلمات (وهو هنا لمن يريد الاطلاع عليه)، لكني أشعر أن الكاتب لديه حساسية من موضوع ازدياد حجم اللغات. حتى أنه يعيب على لغة سي شارب أن حجمها يزداد في كل إصدارة.
هناك بالفعل من يريد أن يحافظ على لغته صغيرة وminimalist وأنا أتفهم مزايا هذا الموضوع (مثلا لغة Google Go تفعل هذا)، لكن يبدو أن الكاتب يرى النمو والتطور عيباً شاملاً في أي لغة.
اللغات مثل سي شارب تتطور لأن عالم البرمجة يتغير: سي شارب صار فيها إمكانيات functional programming حين بدأ نجم البرمجة المتوازية يعلو، وإمكانية Linq ظهرت لتسهيل التعامل مع البيانات المتنوعة في البرامج الكبيرة (ولأسباب أخرى)، وإمكانية generators ظهرت لتبسط أشياءً كانت من قبل معقدة، وإمكانية async/await ظهرت مرة أخرى من أجل البرمجة المتوازية.
سي شارب لغة معقدة لأنها مصنوعة لحل مشاكل معقدة.هل كان يمكن أن تكون أبسط؟ ربما. لكن لا نستطيع أن نقول أن تطورها المستمر هو عيب خطير فيها لابد أن يتوقف.
الوحدات في كلمات تتيح لنا إنشاء إجراءاتٍ و دوالٍ حرة (أي لا يلزم أن تكون مكتوبةً في فصيلةٍ ما)، و هو ما يجعلنا نعاني من مساوئ نموذج البرمجة الإجرائية في المشاريع الكبيرة، و هذه الصفة تناقض مبدأ الأمن الذي نريده في لغة البرمجة القوية.
يبدو أن الكاتب قد غير رأيه في هذا الموضوع لأن هذه الإمكانية (بحسب ما فهمت) موجوده في لغته أيضاً، لكنه لم يحذف هذا الجزء من نقد كلمات وأرجو أن يحدّث ما كتب.
الوصول إلي مكونات الفصيلة غير مُوَحَّد الشكل، فنحن نصل إلي المتغير الداخلي للكائن عن طريق كتابة اسمه ثم كتابة اسم الكائن بعده، أما الإجراءات و الدوال فيجب أن يكتب اسم الكائن أولاً، ثم نتبعه بعلامة : ثم اسم الإجراء أو الدالة.
الكاتب يتحدث عن إمكانية أن أقول
س = سيارة جديد
لون سقف س = "أزرق"
ويريد بدلاً من ذلك أن تكون:
س_سقف_لون = "أزرق"
...وذلك لكي يكون هناك توافق بين field access و method call.
أنا اخترت أن تكون الكود طبيعية أكثر وأشبه باللغة العادية.
ليس فيها تعبيرٌ لمعالجة الاستثناءات exception handling.
هذه الإمكانية مؤجلة حتى أجد طريقة لصنعها بشكل أفضل (وليس مجرد محاكاه لما يحدث في لغات موجودة)، لأني أرى شكلها الحالي معقداً.
لا تحتوي علي مكونٍ هامٍ للغاية هو التعدادات enumerations
ماشي. ولا لغات كثيرة أخرى.
لا تحتوي علي فكرة ال ) delegatingالموجود في لغات مثل الل#.(C
ممم...كلمات حالياً (في أحدث إصداراتها) بها فكرة first class functions وهي مشابهة في الأهداف لما صنعت من أجله فكرة delegates. ربما يمكن الآن في كلمات إضافة الـdelegates في مكتبة.
نلاحظ أن الكاتب قد رفض فكرة الـdelegates كما هي في سي شارب ولم يضفها إلى لغته، لكنه قال أن لديه إمكانية أخرى في لغته هي ما يسميه "الإجراء الحر" تعوض النقص.
لست متأكداً أنني قد فهمت مقصده، لكن الإجراءات الحرة لا تقوم بدور الdelegates!
الكاتب يركز على جزء أن الـdelegate تسمح باستدعاء أكثر من إجراء مرة واحدة؛ لكن ليس هذا الاستخدام الأساسي لها: الاستخدام الأساسي هو فكرة تخزين إجراء في متغير أو تمريره لإجراء آخر. هل يمكن صنع هذا في لغة إبداع؟ لا أعتقد.
وأخيراً
كما قلت، توجد في لغة إبداع بعض الأفكار الجيدة، وربما تتطور مع الوقت وتصير لغة قوية، لأ أريد أن يكون مقالي هذا دافعاً للكاتب (أو لأي مبرمج عربي آخر) أن يترك المحاولة لعمل لغات برمجة عربية.
لكني لا أحب أسلوبه في تحطيم اللغات الأخرى بدون خلفية علمية وايضاً بدون معرفة لأسباب القرارات المتخذة في كل لغة. ولا أحب الثقة الغريبة في أسلوبه حيث كل كلامه "منطقي" أو "بالتأكيد" بينما الأمر لا يخرج عن الآراء الشخصية.
وقد ابتعدت شخصياً عن الهجوم على أية لغة برمجة عربية أخرى مفضلاً أن أجعل كلمات تتحدث عن نفسها، ولكن هذا المقال هو حالة خاصة. هذا نقد غير منصف للغة كلمات يوزع رسمياً مع لغة برمجة عربية أخرى!
وعموما اشعر بالضيق من كتابة هذا المقال..ومازلت أفكر هل أبقي عليه أم أخفيه من المدونة..
الاشتراك في:
الرسائل (Atom)