يقول كتاب "المبرمج البراغماتي" (إذا لم تكن قد قرأته، توقف عن قراءة هذا المقال وقم بذلك الآن!) أنه يجب أن نتعلم كل عام لغة برمجة جديدة.
على الرغم من أن البعض قد يجادل بأن هذا الأمر يتطلب الكثير من الجهد، إلا أننا قد نتفق جميعاً على أنها قد تكون فكرة جيدة. اختيار لغة جديدة لتعلمها ليس بهذه السهولة. فنحن لا نريد أن نكرس وقتنا لشيء قد لا نستخدمه في الممارسة العملية، أليس كذلك؟ ولكن ربما يجب علينا أحيانًا أن نقوم باستثناء ونتعلم شيئًا ما لمجرد التسلية؟ أود أن أقدم لكم لغة Brainfuck. إنها لغة يمكنك تعلمها في بضع دقائق، لذا لا توجد مشكلة في استثمار الكثير من وقتك دون جدوى. أيضًا، يمكنني أن أعدك بأن حل أي مشكلة باستخدام Brainfuck سيحفز عقلك (كل المشاكل مجرد مكافأة ؛)). لنبدأ! وفقًا لـ ويكيبيديا
اللعنة على الدماغ هو لغة البرمجة الباطنية التي ابتكرها أوربان مولر عام 1993. تتكون اللغة من ثمانية أوامر بسيطة فقط ومؤشر تعليمات. وعلى الرغم من أنها مكتملة بشكل كامل من حيث تورينغ، إلا أنها ليست مخصصة للاستخدام العملي، بل لتحدي المبرمجين وتسليتهم.
نظرة عامة على اللغة
تخيل شريطًا طويلًا (أو شريطًا) لا نهائيًا يتألف من خلايا، كل واحدة منها مهيأة إلى 0. هناك أيضًا مؤشر بيانات متحرك يشير في البداية إلى الخلية الأولى. هناك أيضًا تياران من البايتات للإدخال والإخراج. يتم تنفيذ التعليمات بالتتابع، واحدة تلو الأخرى. تتوقف الآلة بعد تنفيذ التعليمات الأخيرة.
الأمر
ما هي وظيفتها؟
>
نقل مؤشر البيانات إلى الخلية التالية على اليمين
<
نقل مؤشر البيانات إلى الخلية التالية على اليسار
+
زيادة قيمة الخلية الحالية
–
إنقاص قيمة الخلية الحالية
.
إخراج البايت من الخلية المشار إليها حاليًا في ASCII الكود
,
قراءة بايت واحد من stdin وتخزين قيمته في الخلية الحالية
[
إذا كانت الخلية الحالية 0، فانتقل إلى الخلية المطابقة]
]
الانتقال إلى المطابقة [
جميع الأحرف بخلاف ><+-.,[] يتم تجاهلها.
دعونا نلقي نظرة على مثال بسيط:
,+.
سيتم تفسيرها على النحو التالي:
قراءة بايت واحد وتخزينه في الخلية الحالية (الخلية0)
زيادة قيمة الخلية الحالية (الخلية0 = الخلية0 + 1)
كتابة محتوى الخلية الحالية إلى الإخراج
نتيجة لذلك، ستتم قراءة حرف واحد من الإدخال وستتم طباعة الحرف التالي من جدول ASCII.
مترجم فوري/مترجم
قبل أن نكتب بعض البرامج المفيدة (؟) في Brainfuck، نحتاج إلى مترجم فوري أو مترجم. AFAIK، لا يوجد مترجم رسمي، لكنها ليست مشكلة. هناك العشرات من البرامج غير الرسمية على الإنترنت. يمكنني أن أوصي بهذين:
"Hello World!" يجب أن يكون أول برنامج نكتبه أثناء تعلم لغة جديدة. لكن كتابته بلغة Brainfuck أصعب قليلاً من اللغات الأخرى. علينا أن نبدأ بشيء أسهل... لنكتب برنامجًا يطبع حرفًا واحدًا "H" على الشاشة (مثير جدًا :D):
كيف يعمل؟ إنه يضبط قيمة الخلية الحالية على 72 (تنفيذ 72 زيادة) ويطبعها على الشاشة باستخدام "." (H لها الرمز 72 في ASCII). الآن أنت تعرف ما يجب أن نفعله لطباعة "Hello World!" على الشاشة، ولكن قبل ذلك، سنقوم بإعادة هيكلة صغيرة. تتطلب كتابة كل هذه "+" الكثير من الكتابة والعد. يمكننا جعلها أقصر باستخدام [ و ] للتكرار. لضبط القيمة على 72، يمكننا على سبيل المثال عمل حلقة تزيد القيمة 7 مرات في 10. بهذه الطريقة نحصل على 70. إضافة 2 سيجعلها 72. يبدو الأمر هكذا:
++++++++++ # ضبط الخلية0 على 10
[ # حلقة حتى تصبح الخلية0 0
- # خفض الخلية0
> # نقل مؤشر البيانات إلى اليمين (الخلية 1)
+++++++ # زيادة الخلية 1 بمقدار 7
# نقل مؤشر البيانات إلى اليمين (الخلية1)
++ 1+ # زيادة بمقدار 2
. # طباعة النتيجة
لقد أدرجت تعليقات لتوضيح كيفية عمل كل شيء. نفس البرنامج بدون تعليقات:
++++++++++[->+++++++++.
أليس جميلاً؟ 🙂
مرحباً أيها العالم!
بالعودة إلى برنامج "مرحبًا بالعالم!". يمكننا تعيين قيمة الخلية الأولى إلى 72 (H) وطباعتها، وتعيين قيمة الخلية الثانية إلى 101 (e) وطباعتها، وتعيين قيمة الخلية الثالثة إلى 108 وطباعتها، وهكذا. إليك تنفيذ هذه الخوارزمية:
أجل، 1120 بايت فقط لطباعة "مرحبًا بالعالم!"... لكن يمكننا أن نفعل ما هو أفضل! بدلاً من استخدام خلية جديدة لكل حرف، دعنا نستخدم خلية واحدة فقط. لطباعة الحرف "e" (101) يمكننا إعادة استخدام القيمة في الخلية0 (72). يمكننا زيادتها بمقدار واحد 29 مرة (101 - 72). وتكون النتيجة كما يلي:
إنها 106 بايت فقط وتطبع سطرًا جديدًا في النهاية! مدهش.
عكس السلسلة
نحن الآن مستعدون لكتابة شيء أكثر صعوبة. لنكتب برنامجًا يقرأ سطرًا من المدخلات ويطبعه بترتيب عكسي. المشكلة الأولى هي قراءة الأحرف والتوقف عند حرف السطر الجديد. تذكّر، لا يوجد استراحة, إذا أو عبارات أخرى مشابهة. يجب أن نستخدم [ و ]. لنبدأ ببرنامج يقرأ جميع الأحرف من المدخلات ويضعها في خلايا متتالية:
,[>,]
يبدأ بقراءة الحرف الأول ويستمر حتى النهاية , عوائد العملية 0. ومع ذلك، فإنه سوف يتكرر إلى الأبد في التنفيذ الذي يُرجع شيئًا آخر غير O لـ EOF (اللغة لا تحدد هذا السلوك). إذن كيف يمكننا التوقف عند حرف السطر الجديد؟ إليك الحيلة:
+[++++++++++>,----------]
نبدأ بتعيين الخلية 0 على 1 للتأكد من تنفيذ الحلقة مرة واحدة على الأقل. في حلقة نزيد قيمة الخلية الحالية بمقدار 10، وننقل مؤشر البيانات إلى الخلية التالية، ونقرأ حرفًا واحدًا ونخفض قيمته بمقدار 10. بهذه الطريقة إذا كان هناك قراءة حرف سطر جديد (10 في ASCII)، سيتوقف البرنامج في التكرار التالي، وإلا ستتم استعادة قيمته بإضافة 10.
بعد هذه الخطوة، ستبدو الخلايا بهذا الشكل:
11 C1 C1 C2 C3 0* 0 0 0
جـ هو الحرف التاسع من المدخلات، و * هو موضع مؤشر البيانات الحالي. الآن علينا البدء في تحريك مؤشر البيانات إلى اليسار، وطباعة جميع الخلايا حتى نصل إلى القيمة 11. إليك ما سأقوم به في هذه المهمة:
عندما عثرت على Brainfuck، وهي لغة برمجة مقصورة على فئة معينة من الناس، رفضتها في البداية على أنها ليست أكثر من وسيلة للتحايل أو المزاح. فقد بدت لي هذه اللغة الغريبة، والتي قد يجادل الكثيرون بأنها لغة صعبة بشكل محيّر للعقل، على أنها شيء مخصص للتسلية فقط. ولكن مع مرور الوقت، تغيرت نظرتي تجاه Brainfuck بشكل كبير جداً.
تتحداك الطبيعة الغامضة ل Brainfuck، وتدفعك إلى توسيع منظورك حول لغات البرمجة. تتيح لك هذه اللغة الباطنية تقدير جمال وضرورة اللغات عالية المستوى التي اعتدنا عليها. فهي تسلط الضوء على أهمية التجريدات واصطلاحات التسمية المناسبة وتخطيط الذاكرة المنظم في عالم لغات البرمجة. هذا شيء لا توفره Brainfuck، بتصميمها البسيط الذي يتكون من ثمانية أوامر بسيطة فقط.
Brainfuck هي لغة تورينج الكاملة التي تؤكد على أهمية وجود شيفرة مصدرية واضحة ومتماسكة. على الرغم من كونها معروفة كواحدة من أكثر اللغات الباطنية صعوبة في كتابة البرامج بها، إلا أنها تبرز بشكل مثير للسخرية كلغة مفضلة للمبتدئين لأي شخص يرغب في إنشاء مترجم برينفوك أو مترجم برينفوك خاص به. والسبب بساطة مجموعة أوامرها، وحقيقة أنها لا تتطلب تحليلاً معقداً.
إنشاء برنامج Brainfuck فريد من نوعه من ناحيتين. أولاً، تحتاج أولاً إلى التكيف مع استخدام مؤشر ذاكرة واحد، مما يجبرك على التفكير بشكل مختلف في شفرتك المصدرية. وثانيًا، لديك "خيار الصفر"، وهو القدرة على إعادة تعيين خلية الذاكرة إلى الصفر، وهي ميزة غير شائعة في لغات البرمجة الرسمية الأخرى.
فيما يتعلق بالتعلم، هناك أكثر مما تراه العين عندما يتعلق الأمر ب Brainfuck. فمن الممكن كتابة البرنامج نفسه بعدة طرق باستخدام رموز Brainfuck مختلفة باستخدام رموز Brainfuck المختلفة، وذلك إذا أُعطي الوقت الكافي والعقلية الصحيحة. يتعلق النصف الأخير من هذه الرحلة بالابتكار وإيجاد طرق جديدة ومبتكرة لاستخدام رموزه الستة.
على الرغم من بساطة مترجمي Brainfuck، إلا أنها تمنحك فهمًا عميقًا لكيفية تشغيل الشيفرة، وما يطبعه البرنامج، والآليات الأساسية للغة تورينج الكاملة. في النهاية، Brainfuck ليست مجرد لغة برمجة باطنية أخرى. إنها بُعد جديد بالكامل، ومفهوم مختلف لكيفية رؤيتنا للبرامج وفهمها وكتابتها.