خمسة أسئلة حول تصميم اللغة

مايو 2001

(هذه بعض الملاحظات التي دونتها لحلقة نقاش حول تصميم لغات البرمجة في معهد ماساتشوستس للتكنولوجيا في 10 مايو 2001.)

1. لغات البرمجة للبشر.

لغات البرمجة هي وسيلة تواصل البشر مع أجهزة الكمبيوتر. سيكون الكمبيوتر سعيدًا بالتواصل بأي لغة غير غامضة. السبب في وجود لغات عالية المستوى هو أن البشر لا يمكنهم التعامل مع لغة الآلة. الهدف من لغات البرمجة هو منع عقولنا البشرية الضعيفة والهشة من الإرهاق بكم هائل من التفاصيل.

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

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

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

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

2. صمم لنفسك ولأصدقائك.

إذا نظرت إلى تاريخ لغات البرمجة، فإن العديد من أفضلها كانت لغات مصممة لمؤلفيها لاستخدامها، والعديد من أسوأها صممت ليستخدمها الآخرون.

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

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

الحجة لتصميم لغات للمبرمجين السيئين هي أن هناك عددًا أكبر من المبرمجين السيئين أكثر من المبرمجين الجيدين. قد يكون هذا صحيحًا. لكن هؤلاء المبرمجين الجيدين القلائل يكتبون نسبة كبيرة بشكل غير متناسب من البرمجيات.

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

3. امنح المبرمج أكبر قدر ممكن من التحكم.

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

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

4. استهدف الإيجاز.

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

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

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

5. اعترف بماهية القرصنة.

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

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

1. كيف ننظم المكتبات الكبيرة؟

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

2. هل يخاف الناس حقًا من بناء الجملة البادئ؟

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

3. ما الذي تحتاجه للبرامج المستندة إلى الخادم؟

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

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

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

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

4. ما هي التجريدات الجديدة المتبقية للاكتشاف؟

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

1. يمكنك استخدام أي لغة تريدها.

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

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

ما يعنيه هذا بالنسبة لنا، كأشخاص مهتمين بتصميم لغات البرمجة، هو أنه أصبح هناك الآن جمهور محتمل لأعمالنا.

2. السرعة تأتي من أدوات التنميط.

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

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

3. تحتاج إلى تطبيق لقيادة تصميم اللغة.

قد لا تكون هذه قاعدة مطلقة، ولكن يبدو أن أفضل اللغات تطورت جميعًا جنبًا إلى جنب مع بعض التطبيقات التي كانت تُستخدم لكتابتها. تمت كتابة C من قبل أشخاص احتاجوها لبرمجة الأنظمة. تم تطوير Lisp جزئيًا لإجراء التفاضل الرمزي، وكان McCarthy متحمسًا جدًا للبدء لدرجة أنه كان يكتب برامج التفاضل حتى في الورقة الأولى عن Lisp، في عام 1960.

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

[خلال الحلقة، أشار Guy Steele أيضًا إلى هذه النقطة، مع اقتراح إضافي بأن التطبيق لا ينبغي أن يتكون من كتابة مترجم لغتك، إلا إذا كانت لغتك مخصصة لكتابة المترجمات.]

4. يجب أن تكون اللغة جيدة لكتابة البرامج التي يمكن التخلص منها.

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

5. بناء الجملة مرتبط بالدلالات.

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

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

1. لغات البرمجة الجديدة.

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

2. المشاركة الزمنية.

قدم Richard Kelsey هذا كفكرة حان وقتها مرة أخرى في الحلقة النقاشية الأخيرة، وأنا أتفق معه تمامًا. تخميني (وتخمين Microsoft، على ما يبدو) هو أن الكثير من الحوسبة ستنتقل من سطح المكتب إلى الخوادم البعيدة. بعبارة أخرى، المشاركة الزمنية عادت. وأعتقد أنه ستكون هناك حاجة للدعم على مستوى اللغة. على سبيل المثال، أعرف أن Richard و Jonathan Rees قد قاما بالكثير من العمل في تنفيذ جدولة العمليات داخل Scheme 48.

3. الكفاءة.

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

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

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

1. العملاء.

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

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

2. البرمجة كائنية التوجه.

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

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

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

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

3. التصميم عن طريق اللجنة.

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

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