إيماكس ليسب
لغة إيماكس ليسب هي لهجة من لغة ليسب مصممة خصيصًا لبرنامج جنو إيماكس . تُستخدم هذه اللغة لتنفيذ معظم وظائف التحرير المدمجة في إيماكس، أما الباقي فهو مكتوب بلغة سي ، وكذلك مترجم ليسب .
يُستخدم كود Emacs Lisp لتعديل Emacs وتوسيعه وتخصيصه. يمكن لمن لا يرغبون بكتابة الكود بأنفسهم استخدام وظيفة التخصيص (Customize) . توفر هذه الوظيفة مجموعة من صفحات التفضيلات التي تُمكّن المستخدم من ضبط الخيارات ومعاينة تأثيرها في جلسة Emacs الجارية. عند حفظ المستخدم لتغييراته، تقوم وظيفة التخصيص ببساطة بكتابة كود Emacs Lisp اللازم إلى ملف إعدادات المستخدم ، والذي يمكن تعيينه إلى ملف خاص تستخدمه وظيفة التخصيص فقط، وذلك لتجنب إمكانية تعديل ملف المستخدم الأصلي.
إلى جانب كونها لغة برمجة قابلة للترجمة إلى بايت كود [ 1 ] وإلى لغة الآلة [ 2 ]، يمكن لـ Emacs Lisp أيضًا العمل كلغة برمجة نصية تفسيرية ، تمامًا مثل Bourne shell في أنظمة Unix أو Perl ، وذلك عن طريق استدعاء Emacs في وضع الدُفعات . بهذه الطريقة، يمكن استدعاؤها من سطر الأوامر أو عبر ملف تنفيذي، وتكون وظائف التحرير الخاصة بها، مثل المخازن المؤقتة وأوامر النقل، متاحة للبرنامج تمامًا كما في الوضع العادي. لا تظهر أي واجهة مستخدم عند بدء تشغيل Emacs في وضع الدُفعات؛ إذ يقوم ببساطة بتنفيذ البرنامج النصي المُمرر ثم يخرج، عارضًا أي مخرجات من البرنامج النصي.
يُطلق على لغة Emacs Lisp أيضًا اسم Elisp ، على الرغم من وجود لهجات Lisp أقدم وغير مرتبطة بها تحمل هذا الاسم. [ 3 ] [ 4 ]
بالمقارنة مع لهجات لغة ليسب الأخرى
تُعدّ لغة Emacs Lisp الأقرب صلةً بلغة Maclisp ، مع بعض التأثيرات اللاحقة من لغة Common Lisp . [ 5 ] وهي تدعم أساليب البرمجة الإجرائية والوظيفية . كانت Lisp لغة الإضافة الافتراضية لمشتقات Emacs مثل EINE وZWEI . عندما قام ريتشارد ستالمان بتطوير Gosling Emacs إلى GNU Emacs، اختار Lisp أيضًا كلغة إضافة، نظرًا لميزاتها القوية، بما في ذلك القدرة على التعامل مع الدوال كبيانات. على الرغم من أن معيار Common Lisp لم يكن قد وُضع بعد، وكانت لغة Scheme موجودة في ذلك الوقت، إلا أن ستالمان اختار عدم استخدامها بسبب أدائها الضعيف نسبيًا على محطات العمل (مقارنةً بالحواسيب الصغيرة التي كانت بيئة Emacs التقليدية)، وكان يرغب في تطوير لهجة يعتقد أنها ستكون أسهل في التحسين. [ 6 ]
تختلف لهجة لغة ليسب المستخدمة في إيماكس اختلافًا جوهريًا عن لهجتي كومون ليسب وسكيم الأكثر حداثة، واللتين تُستخدمان في برمجة التطبيقات. ومن أبرز خصائص ليسب إيماكس استخدامها للنطاق الديناميكي بدلًا من النطاق المعجمي افتراضيًا. أي أن الدالة قد تشير إلى متغيرات محلية في النطاق الذي استُدعيت منه، ولكن ليس في النطاق الذي عُرّفت فيه. وقد بُذلت مؤخرًا جهودٌ حثيثة لتحديث الشيفرة البرمجية لاستخدام النطاق المعجمي، وذلك للأسباب الموضحة أدناه.
| 1958 | 1960 | 1965 | 1970 | 1975 | 1980 | 1985 | 1990 | 1995 | 2000 | 2005 | 2010 | 2015 | 2020 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| LISP 1، 1.5، LISP 2 (مهجورة) | |||||||||||||||
| ماكليس | |||||||||||||||
| تداخل | |||||||||||||||
| MDL | |||||||||||||||
| آلة التأتأة | |||||||||||||||
| مخطط | R5RS | R6RS | R7RS صغير | ||||||||||||
| لا شيء | |||||||||||||||
| ZIL (لغة تنفيذ Zork) | |||||||||||||||
| فرانز ليسب | |||||||||||||||
| muLisp | |||||||||||||||
| لغة الشفرة الشائعة | معيار ANSI | ||||||||||||||
| لي لِسْب | |||||||||||||||
| مخطط معهد ماساتشوستس للتكنولوجيا | |||||||||||||||
| XLISP | |||||||||||||||
| تي | |||||||||||||||
| شيز سكيم | |||||||||||||||
| إيماكس ليسب | |||||||||||||||
| أوتو ليسب | |||||||||||||||
| PicoLi sp | |||||||||||||||
| غامبيت | |||||||||||||||
| EuLisp | |||||||||||||||
| لغة ISLISP | |||||||||||||||
| أوبن ليسب | |||||||||||||||
| مخطط PLT | مضرب | ||||||||||||||
| لغة نيو ليسب | |||||||||||||||
| جنو غايل | |||||||||||||||
| لغة ليسب المرئية | |||||||||||||||
| كلوجر | |||||||||||||||
| قوس | |||||||||||||||
| LFE | |||||||||||||||
| هي | |||||||||||||||
مثال
استرشد تطوير لغة Emacs Lisp بهدف توفير هياكل بيانات وميزات خاصة لإنشاء محرر نصوص متعدد الاستخدامات، بدلاً من تطبيق لغة برمجة عامة الأغراض. على سبيل المثال، لا تستطيع Emacs Lisp قراءة ملف سطرًا سطرًا بسهولة، بل يجب قراءة الملف بأكمله في مخزن مؤقت (buffer) خاص بها. مع ذلك، توفر Emacs Lisp العديد من الميزات للتنقل بين نصوص المخزن المؤقت وتعديلها على مستوى الجملة أو الفقرة أو حتى على مستوى أعلى من حيث البنية النحوية، وذلك وفقًا للأوضاع البرمجية.
فيما يلي مثال بسيط لإضافة لبرنامج Emacs مكتوبة بلغة Emacs Lisp. في Emacs، يمكن تقسيم منطقة التحرير إلى مناطق منفصلة تُسمى نوافذ ، تعرض كل منها مخزنًا مؤقتًا مختلفًا . المخزن المؤقت هو جزء من النص يتم تحميله في ذاكرة Emacs (ربما من ملف) ويمكن حفظه في مستند نصي.
C-x 2يمكن للمستخدمين الضغط على مفتاح الاختصار الافتراضي لفتح نافذة جديدة. يؤدي هذا إلى تشغيل دالة Emacs Lisp split-window-below. عادةً، عند ظهور النافذة الجديدة، تعرض نفس المخزن المؤقت الذي عرضته النافذة السابقة. لنفترض أننا نرغب في عرض المخزن المؤقت التالي المتاح. لتحقيق ذلك، يكتب المستخدم كود Emacs Lisp التالي، إما في ملف مصدر Emacs Lisp موجود أو في مخزن مؤقت Emacs فارغ:
( defun my-split-window-func () ( interactive ) ( split-window-below ) ( set-window-buffer ( next-window ) ( other-buffer )))( global-set-key ( kbd "Cx 2" ) #' my-split-window-func )يُعرّف البيان الأول (defun ...)دالةً جديدةً my-split-window-funcتستدعي split-window-belowدالة تقسيم النافذة القديمة، ثم تُخبر النافذة الجديدة بعرض مخزن مؤقت آخر (جديد). أما البيان الثاني، (global-set-key ...)فيُعيد ربط تسلسل المفاتيح "Cx 2" بالدالة الجديدة.
يمكن كتابة هذا الكود أيضًا باستخدام ميزة "النصائح" ، التي تتيح للمستخدم إنشاء أغلفة حول الدوال الموجودة بدلًا من تعريف دوال خاصة به. تتميز هذه الطريقة بعدم الحاجة إلى تغيير اختصارات لوحة المفاتيح، وإمكانية العمل أينما تم استدعاء الدالة الأصلية، وسهولة الكتابة، ولكن يعيبها تعقيد عملية تصحيح الأخطاء. لهذا السبب، لا يُسمح باستخدام ميزة "النصائح " في شفرة المصدر لبرنامج GNU Emacs، [ 7 ] ولكن إذا رغب المستخدم، فيمكنه استخدامها في شفرته لإعادة تنفيذ الكود المذكور أعلاه كما يلي:
( defadvice split-window-below ( after my-window-splitting-advice first () activate ) ( set-window-buffer ( next-window ) ( other-buffer )))يُوجّه هذا الأمر split-window-belowإلى تنفيذ الكود الذي يُدخله المستخدم عند استدعائه، بعد تنفيذ باقي الدالة. كما يُمكن تحديد توجيهات لتنفيذ الكود قبل الدالة الأصلية، أو حولها (أي تغليفها)، أو لتنفيذ الدالة الأصلية بشكل مشروط بناءً على نتائج التوجيهات.
يستبدل Emacs 24.4 [ 8 ] هذه defadviceالآلية بآلية أخرى advice-add، يُزعم أنها أكثر مرونة وبساطة. [ 9 ] يمكن إعادة تطبيق النصائح المذكورة أعلاه باستخدام النظام الجديد كما يلي:
( defun switch-to-next-window-in-split () ( set-window-buffer ( next-window ) ( other-buffer )))( نصيحة - أضف 'split-window-below :before #' التبديل إلى النافذة التالية في التقسيم )تُطبَّق هذه التغييرات فور تنفيذ الكود . لا حاجة لإعادة تجميع الكود، أو إعادة تشغيل إيماكس، أو حتى تعديل ملف الإعدادات. إذا حُفِظ الكود في ملف تهيئة إيماكس، فسيقوم إيماكس بتحميل الإضافة عند تشغيله في المرة القادمة. وإلا، يجب إعادة تنفيذ التغييرات يدويًا عند إعادة تشغيل إيماكس.
شفرة المصدر
يُخزَّن كود مصدر Emacs Lisp في أنظمة الملفات كملفات نصية عادية ، وفقًا للعرف، مع لاحقة اسم الملف " .el". ويُستثنى من ذلك ملف تهيئة المستخدم، الذي غالبًا ما يظهر كـ " .emacs" على الرغم من تقييمه كأي كود Emacs Lisp. منذ منتصف التسعينيات، يقوم Emacs أيضًا بتحميل ~/.emacs.elو ~/.emacs.d/init.el. علاوة على ذلك، يمكن للمستخدمين تحديد أي ملف لتحميله كملف تهيئة عبر سطر الأوامر، أو تحديد عدم تحميل أي ملف تهيئة بشكل صريح. عند تحميل الملفات، يقوم مُفسِّر برنامج Emacs بقراءة وتحليل الدوال والمتغيرات، وتخزينها في الذاكرة. ثم تصبح متاحة لوظائف التحرير الأخرى، ولأوامر المستخدم. يمكن تعديل الدوال والمتغيرات وإعادة تعريفها بحرية دون الحاجة إلى إعادة تشغيل المحرر أو إعادة تحميل ملف التهيئة.
لتوفير الوقت ومساحة الذاكرة، لا يتم تحميل معظم وظائف إيماكس إلا عند الحاجة. تُنفَّذ كل مجموعة من الميزات الاختيارية المرفقة مع إيماكس بواسطة مجموعة من أكواد إيماكس تُسمى حزمة أو مكتبة . على سبيل المثال، توجد مكتبة لتظليل الكلمات المفتاحية في شفرة المصدر للبرنامج، ومكتبة أخرى للعب لعبة تتريس . تُنفَّذ كل مكتبة باستخدام ملف مصدر واحد أو أكثر من ملفات إيماكس ليسب. يمكن للمكتبات تحديد وضع رئيسي واحد أو أكثر لتفعيل وظائفها والتحكم بها.
يكتب مطورو Emacs بعض الدوال بلغة C. تُعرف هذه الدوال بالدوال الأساسية، أو الدوال المدمجة ، أو الدوال الفرعية . على الرغم من إمكانية استدعاء الدوال الأساسية من كود Lisp، إلا أنه لا يمكن تعديلها إلا بتحرير ملفات مصدر C وإعادة تجميعها. في GNU Emacs ، لا تتوفر الدوال الأساسية كمكتبات خارجية، بل هي جزء من ملف Emacs التنفيذي. أما في XEmacs ، فيمكن تحميل هذه الدوال الأساسية أثناء التشغيل، باستخدام دعم نظام التشغيل للربط الديناميكي . قد تُكتب الدوال كدوال أساسية لأنها تحتاج إلى الوصول إلى بيانات ومكتبات خارجية غير متوفرة في Emacs Lisp، أو لأنها تُستدعى بشكل متكرر بما يكفي ليُحدث فرق السرعة بين C و Emacs Lisp فرقًا ملحوظًا.
ومع ذلك، ولأن الأخطاء في كود C يمكن أن تؤدي بسهولة إلى انتهاكات التجزئة أو إلى أخطاء أكثر دقة، مما يؤدي إلى تعطل المحرر، ولأن كتابة كود C الذي يتفاعل بشكل صحيح مع جامع القمامة Emacs Lisp عرضة للأخطاء، يتم الحفاظ على عدد الوظائف المنفذة كبدائل عند الحد الأدنى الضروري.
رمز البايت
يمكن لتجميع البايتات أن يُسرّع تنفيذ كود Emacs Lisp. يحتوي Emacs على مُجمِّع قادر على ترجمة ملفات مصدر Emacs Lisp إلى تمثيل خاص يُسمى بايت كود . تحمل ملفات بايت كود Emacs Lisp لاحقة اسم الملف " .elc". بالمقارنة مع ملفات المصدر، يتم تحميل ملفات البايت كود وتشغيلها بشكل أسرع، وتشغل مساحة أقل على القرص، وتستهلك ذاكرة أقل عند تحميلها.
لا يزال الكود الوسيط يعمل ببطء مقارنةً بالبرامج الأساسية، ولكن يمكن تعديل الدوال المحملة ككود وسيط وإعادة تحميلها بسهولة، كما أن ملفات الكود الوسيط تُعد برامج متعددة المنصات . يتم تحميل كود Emacs Lisp القياسي الموزع مع Emacs ككود وسيط، على الرغم من توفير ملفات المصدر المطابقة عادةً كمرجع للمستخدم. لا يتم عادةً تجميع الإضافات التي يقدمها المستخدم ككود وسيط، لأنها ليست كبيرة الحجم ولا تتطلب موارد حاسوبية كبيرة.
خصائص اللغة
تُنفّذ حزمة "cl-lib" مجموعة فرعية كبيرة نسبيًا من لغة Common Lisp . تحل هذه الحزمة محل حزمة "cl" السابقة، التي كانت تستبدل تعريفات دوال Emacs Lisp الموجودة بتعريفات أقرب إلى تلك الموجودة في Common Lisp. من ناحية أخرى، تتبع حزمة "cl-lib" إرشادات أسلوب Emacs Lisp بشكل أدق، وتُضيف البادئة "cl-" إلى كل دالة ووحدة ماكرو تُعرّفها (على سبيل المثال، ، cl-defunوهو ما لا يتعارض مع اسم الدالة المدمجة defun)، متجنبةً بذلك التغييرات غير المتوقعة في السلوك التي قد تحدث عند تحميل حزمة "cl".
لا يقوم برنامج Emacs Lisp (على عكس بعض تطبيقات Lisp الأخرى) بتحسين استدعاءات الذيل . [ 10 ] وبدون ذلك، يمكن أن تؤدي الاستدعاءات المتكررة في الذيل في النهاية إلى تجاوز سعة المكدس .
تساعد مكتبة apel في كتابة كود Emacs Lisp قابل للنقل، وذلك بمساعدة جسر منصة polysylabi.
لغة Emacs Lisp هي لغة شبيهة بلغة Lisp-2 مثل Common Lisp، مما يعني أنها تحتوي على مساحة أسماء للدوال منفصلة عن مساحة الأسماء التي تستخدمها للمتغيرات الأخرى. [ 11 ]
من النطاق الديناميكي إلى النطاق المعجمي
مثل لغة ماك ليسب، تستخدم لغة إيماكس ليسب النطاق الديناميكي ، مع توفير النطاق الثابت (أو المعجمي) كخيار بدءًا من الإصدار 24. [ 12 ] ويمكن تفعيله عن طريق تعيين متغير محلي للملف lexical-binding. [ 13 ] [ 14 ] قبل إضافة هذا الخيار، كان بالإمكان استخدام lexical-letالماكرو من حزمة "cl" (التي أصبحت الآن مهملة) لتوفير نطاق معجمي فعال. [ 15 ]
في النطاق الديناميكي، إذا عرّف المبرمج متغيرًا ضمن نطاق دالة، يصبح متاحًا للبرامج الفرعية المُستدعاة من داخل تلك الدالة. في الأصل، كان الهدف من ذلك تحسين الأداء ؛ إذ كان النطاق المعجمي لا يزال غير شائع وغير مضمون الأداء. يتذكر عالم الحاسوب أولين شيفرز: "سألتُ آر إم إس عندما كان يُطوّر لغة إيماكس ليسب عن سبب استخدام النطاق الديناميكي، وكان رده تحديدًا أن النطاق المعجمي غير فعال للغاية." [ 16 ] كان الهدف من النطاق الديناميكي أيضًا توفير مرونة أكبر لتخصيصات المستخدم. مع ذلك، للنطاق الديناميكي عدة عيوب. أولًا، قد يؤدي بسهولة إلى أخطاء في البرامج الكبيرة، نتيجةً للتفاعلات غير المقصودة بين المتغيرات في الدوال المختلفة. ثانيًا، يكون الوصول إلى المتغيرات في النطاق الديناميكي أبطأ عمومًا منه في النطاق المعجمي .
مراجع
- ↑ "تجميع بايتات لغة إيماكس ليسب" . دليل جنو إيماكس . تم الاطلاع عليه بتاريخ 14-06-2024 .
- ↑ "ترجمة لغة إيماكس ليسب إلى كود أصلي" . دليل جنو إيماكس . تم الاطلاع عليه بتاريخ 14-06-2024 .
- ↑ هيدريك في روتجرز (مدير قسم ديسمبر 2020/مدير منشأة LCSR Comp (18-12-1981). ""معلومات حول تطبيق لغة Common Lisp"رسالة إلى rpg في SU-AI، و jonl في MIT-AI. مؤرشفة من الأصل بتاريخ 20 سبتمبر 2016. تم الاطلاع عليها بتاريخ 28 يوليو 2019.
لدينا الآن بعض الخبرة في تطبيق لغة Lisp، حيث أن Elisp (التطبيق الموسع للغة Rutgers/UCI Lisp) قد اكتمل بشكل أساسي.
{{cite press release}}: صيانة CS1: الأسماء الرقمية: قائمة المؤلفين ( رابط ) - ↑ "إعلان لـ CCA EMACS". مراجعة يونكس . ديسمبر 1984. ص 16.
CCA EMACS و Elisp علامتان تجاريتان لشركة CCA Uniworks, Inc.
- ↑ «لغة GNU Emacs Lisp مستوحاة بشكل كبير من لغة Maclisp ، وقليلًا من لغة Common Lisp. إذا كنت تعرف Common Lisp، فستلاحظ العديد من أوجه التشابه. مع ذلك، تم حذف أو تبسيط العديد من ميزات Common Lisp لتقليل متطلبات الذاكرة لبرنامج GNU Emacs. في بعض الأحيان، تكون التبسيطات جذرية لدرجة قد تُربك مستخدم Common Lisp. سنوضح من حين لآخر كيف تختلف GNU Emacs Lisp عن Common Lisp.» - من قسم «التاريخ» في «المقدمة» لدليل Emacs Lisp، إصدار Emacs 21
- ↑ «لذا، فإن تطوير نظام التشغيل هذا، نظام تشغيل جنو، هو ما دفعني لكتابة جنو إيماكس. وقد سعيتُ من خلال ذلك إلى إنشاء تطبيق ليسب بأقل حجم ممكن. كان حجم البرامج مصدر قلق بالغ. ففي ذلك الوقت، عام ١٩٨٥، كان هناك أشخاص يمتلكون أجهزة بسعة ١ ميجابايت بدون ذاكرة افتراضية. وكانوا يرغبون في استخدام جنو إيماكس. وهذا يعني أنه كان عليّ الحفاظ على البرنامج بأصغر حجم ممكن.» - من «تجاربي مع ليسب وتطوير جنو إيماكس»
- ↑ "ردًا على: [ Emacs-diffs ] /srv/bzr/emacs/trunk r111086: gmm-utils.el (gmm-flet) . Lists.gnu.org. 2012-12-05 . تم الاطلاع عليه بتاريخ 2013-08-18 . "
- ↑ "NEWS.24.4" .
- ↑ "نقل النصائح القديمة" .
- ↑ "الملحق ج: نقل لغة Common Lisp" . Gnu.org . تم الاطلاع عليه بتاريخ 28-10-2019 .
سيلاحظ مبرمجو لغة Lisp أن مُصرّف Emacs Lisp الحالي لا يُحسّن الاستدعاء الذاتي النهائي.
- ↑ "مجموعات جوجل" . groups.google.com .
- ↑ "إصدار Emacs 24.1" . Lists.gnu.org . تاريخ الاسترجاع: 18 أغسطس 2013 .
- ↑ "الربط المعجمي" . Lists.gnu.org. 2011-04-01 . تم الاسترجاع في 2013-08-18 .
- ↑ "الربط الديناميكي مقابل الربط المعجمي" . EmacsWiki. 2013-05-17 . تم الاطلاع عليه بتاريخ 2013-08-18 .
- ↑ "الربط المعجمي القديم" . محاكاة لغة ليسب الشائعة في GNU Emacs . مطبعة GNU . تم الاطلاع عليه بتاريخ 27 مايو 2021 .
- ↑ "T" . People.csail.mit.edu . تم الاطلاع عليه بتاريخ 18-08-2013 .
روابط خارجية
- الموقع الرسمي لمشروع جنو
- دليل مرجعي للغة ليسب في إيماكس ، مشروع جنو
- مقدمة في البرمجة بلغة إيماكس ليسب ، مشروع جنو
- عناصر Emacs Lisp ، من موقع بروتيسيلاوس ستافرو الإلكتروني
- لغات البرمجة ذات النطاق الديناميكي
- إيماكس
- مترجمات مجانية ومفتوحة المصدر
- مترجمون فوريون مجانيون ومفتوحو المصدر
- عائلة لغات البرمجة ليسب
- لغات البرمجة النصية
- محررات النصوص
- لغات البرمجة التي تم إنشاؤها عام 1985
- تطبيقات لغة البرمجة GNU Project Lisp
