ديلان

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

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

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

وبالرغم من اشتقاق الكثير من تراكيبها من سكم ونظم ليسب الأخرى الأخرى- حيث أن بعض التطبيقات كانت في الواقع مبنية مبدئيا داخل نظم ليسب القائمة بالفعل- فإن لغة ديلان كان لها ألجول ALGOL (وهي لغة يتم التعبير فيها عن المعلومات بتنويت جبري ووفقا لقواعد الجبر المنطقي Boolean algebra) خاص بها – مثل صياغة أكثر من كونها مشروعا- مثل الصياغة الموضوعة مسبقا.

التاريخ 
نشأت لغة ديلان في تسعينيات القرن العشرين على يد مجموعة بقيادة كمبيوتر أبل. وفي إحدى مراحل تطورها كانت هذه اللغة تهدف إلى استخدام كمبيوتر نيوتن الذي صنعته أبل، لكن تطبيق ديلان لم يصل إلى النضج الكافي في ذلك الوقت، وبدلا من ذلك فقد استخدم كمبيوتر نيوتن تشكيلة من سي C ونيوتن سكريبت NewtonScript الذي طورها وولتر سميث. وقد أنهت أبل جهودها لتطوير لغة ديلان في عام 1995 بالرغم من أنها قد قامت بإتاحة نسخة «الإصدار التكنولوجي» (Apple Dylan TR1) والتي تضمنت محسن تصميم واجهات (interface design enhancement IDE) متقدمة.

وقد أسهمت مجموعتان أخرى تان في تصميم اللغة وقامتا بتطوير التطبيقات وهما: هارلجوين Harleguin التي أصدرت IDE تجارية لمايكروسوفت ويندوز وجامعة كارنيجي ميلون التي أصدرت مؤدي مصادر مفتوحة لنظم يونيكس Unix systems. وكل من هذين التطبيقين يعتبران الآن مصدرا مفتوحا وقائما على يد مجموعة من المتطوعين، وهم جديون مينتينرز Gwydion Maintainers.

وحملت لغة ديلان اسما كوديا هو رالف Ralph. وقد اختار جيمس جوكين J. Joaquin اسم ديلان اختزالا لمصطلح “Dynamic LANguage.”

البنية 
مبدئيا، استخدمت لغة ديلان بنية بادئة تشبه المشروع، وتقوم على تعبيرات بنيوية s-expressions

 (bind ((radius 5)
 (circumference (* 2 $pi radius)))
 (if (> circumference 42)
 (format-out "Hello big circle! c is %=" circumference)
 (format-out "Hello circle! c is %=" circumference)))

وبمرور الوقت اكتمل تصميم هذه اللغة، وتغيرت إلى بنية تشبه بنية ألجول Algol-synatx، التي صممها مايكل كيل، متوقعا أنها ستكون أكثر قبولا لجمهور أوسع نطاقا من المبرمجين:

 let radius = 5;
 let circumference = 2 * $pi * radius;
 if (circumference> 42)
 format-out("Hello, big circle! c is %=", circumference);
 else
 format-out("Hello, circle! c is %=", circumference);
 end if

وفيما يتشابه مع لغات البرمجة الأخرى، فإن نتيجة وظيفة ما هي قيمة آخر تعبير تم تقييمه- وليس هناك بيان «عائد» مميز. وتعيد الوظيفة التالية قيمة بيان «إذا» (إن البيانات تنتج أيضا نتائج)، والتي تقيم قيمة كل من "1" أو رقم مضاعف n*factorial (n-1):

 define method factorial(n :: <integer>)
 if (n = 0)
 1
 else
 n * factorial(n - 1)
 end
 end method;

الوحدات ضد مساحة الاسم 

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

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

وعلى سبيل المثال طالع إضافة مكتبية لدعم التعبير المنتظم regex (regular expression) حول المقطع. وفي بعض اللغات، ومن أجل تضمين الوظيفية في المقاطع، فإنه تتم إضافة الوظيفية لمسافة الاسم المقطعية نفسها. وبمجرد قيامك بذلك، تصبح فئة المقطع أكبر، ويظل لزاما على الناس الذين لا يحتاجون إلى استخدام Regex أن «يدفعوا» مقابل زيادة حجم المكتبة. ولهذا السبب فإن هذه الأنواع من الاضافات توضع تلقائيا في مساحات الأسماء والخانات الخاصة بها. إن نقطة قصور هذه المقاربة هي أن الوظيفية الجديدة لم تعد جزءا من المقطع؛ وبدلا من ذلك فإنها تكون معزولة في نطاق مجموعة وظائفها الخاصة بها والتي تستدعى بشكل منفصل. وبدلا من (نمطي) مقطعي.التحليل مع myString.parseWith(myPattern)، والذي يمكن أن يكون تنظيما طبيعيا من وجهة نظر اللغة الشيئية object-oriented (OO)، فإنك تستخدم شيئا يشبه (مقطعي) نمطي.تحليل المقطع myPattern.parseString(myString) والذي يعكس بفعالية عملية إصدار الأمر.

إضافة إلى ذلك، يمكن للعديد من واجهات لغة ديلان أن تعرف لنفس الكود، على سبيل المثال يمكن لطريقة لم المقطع أن توضع في كل من واجهة المقطع، وواجهة «اللم» التي تجمع معا جميع وظائف اللم المختلفة من فئات متنوعة. وهذا أكثر شيوعا في مكتبات الرياضيات، حيث تكون الوظائف أكثر قابلية للتطبيق لأنواع خانات مختلفة على نطاق واسع.
وهناك استخدام أكثر عملية لبنية الواجهة وهو بناء إصدارات عامة وخاصة للوحدة، وشيء آخر تستخدمه اللغات الأخرى مثل خاصية “bolt on” الداعمة التي تسبب دائما مشكلات وتضيف بنية. ووفقا للغة ديلان يمكن للمبرمج أن يضع ببساطة كل استدعاء وظيفة في واجهة «خاص» أو «تطور»، وجمع الوظائف مفتوحة الاستخدام في واجهة «عام». ووفقا للغة جافا أو سي++ فإن رؤية الخانة تعرف في الكود نفسه، وتعني دعم تغيرا مشابها قد يجبر المبرمج على إعادة كتابة التعريفات كلية، ولا يمكن أن يدون لديه نسختين في نفس الوقت.

الفئات 
تصف الفئات في لغة ديلان «فتحات» slots (بيانات المستخدمين، الخانات، الايفارس، الخ) للخانات بطريقة مشابهة لمعظم لغات OO. وتكون جميع عمليات الولوج إلى الفتحات من خلال مناهج محددة، كما هو الحال في كلوس CLOS وسمولتوك Smalltalk. إن منهجي الحصول والوضع ينطلقان تلقائيا اعتمادا على أسماء الفتحات. وفيما يتعارض مع غالبية لغات اللغة الشيئية الأخرى، فإن المناهج الأخرى القابلة للتطبيق على الفئة يمكن تعريفها خارج الفئة، ومن ثم فإن تعريفات الفئة في لغة ديلان تتضمن تلقائيا تعريف التخزين فحسب. على سبيل المثال:

 define class <window> (<view>)
 slot title :: <string> = "untitled", init-keyword: title:;
 slot position :: <point>, required-init-keyword: position:;
 end class;

على سبيل المثال فإن الفئة "<window>" تكون معرفة. ولا توجد بنية اسم الفئة <class name> إلا بالاتفاق فقط، من أجل جعل أسماء الفئات قائمة- ولا تكون أقواس الزاوية سوى جزء من اسم الفئة. ومقارنة بذلك، فإن بعض اللغات يكون الاتفاق فيها بادئا بحرف كبير لاسم الفئة أو تكون بادئة الاسم ملحقة بـ "C" أو “T” (على سبيل المثال). <window> تأتي من فئة مفردة، وهي <view>، وتحتوي فتحتين، ويحمل العنوان مقطعا لعنوان النافذة، ويحمل الوضع نقطة X-Y لزاوية النافذة. وفي هذا المثال المخصوص يمنح العنوان قيمة مبدئية، بينما لا يكون ذلك الحال بالنسبة للوضع. وتسمح بنية «لوحة المفاتيح- المبدئية» للمبرمج بتحديد القيمة المبدئية للفتحة عندما يقوم بوضع خانة للفئة.

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

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

وبالرغم من أن هذا المثال لا يستخدم لغة ديلان فإنها تدعم أيضا الواجهة المتعددة.

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

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

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

 define method turn-blue (w :: <window>)
 w.color := $blue;
 end method;

وهذا التعريف مشابه لتلك التعريفات في اللغات الأخرى، ويمكن أن يكونا مغلفا داخل فئة نافذة <window>. لاحظ واضع استدعاء الـ:=، والتي توصف بأنها سكر بنيوي syntactic sugar للواضع الملون ($ أزرق، w).
إن أداء المناهج العامة يأتي وفقا لها عندما تأخذ في اعتبارك النماذج «العامة». على سبيل المثال فإن أحد الوظائف الشائعة في غالبية اللغات هي وظيفة التقطيع to-string، والتي تعيد بعض الشكل المقروء بشريا للخانة. على سبيل المثال فإن نافذة ما يمكن أن تعيد عنوانها ووضعها في أقواس بينما سيعيد المقطع نفسه. وفي لغة ديلان فإن مثل هذه المناهج يمكن أن تجمع جميعها في وحدة مفردة تسمى «التقطيع»، ثم تتم إزالة هذا الكود من تعريف الفئة نفسها. وإذا لم تدعم خانة بعينها هذا التقطيع، فإنه سيتم بسهولة إضافتها إلى وحدة التقطيع.

القابلية للتمديد 
يمكن أن يصيب هذا المفهوم الكلي بعض القراء باعتباره مفهوما محبطا للغاية. إن كود معالجة التقطيع لنافذة ما ليس محددا في <window>؟ ولا يجدي ذلك بالنسبة لك أي معنى إلا عندما تنظرفي كيفية معالجة لغة ديلان لاستدعاء التقطيع. في غالبية اللغات عندما يقوم البرنامج بالتقطيع فإن التقطيع لـ <window> يتم البحث عنه ويحل محله مؤشر (أكثر أو أقل) للمنهج. ويحدث ذلك في لغة ديلان عندما يشغل البرنامج للمرة الأولى؛ فإن وقت التشغيل ينشيء جدولا لتفاصيل اسم المنهج/ المعاملات ويبحث في المناهج بحركية من خلال هذا الجدول. ويعني ذلك أن وظيفة ما لمناهج معين يمكن أن توجد في أي مكان، وليس فقط في وحدة وقت التصرف. وفي النهاية فإن المبرمج يمنح مرونة كبيرة فيما يخص مكان وضعه أكوادهم، وجمعها وفقا للفئات حيث لا تكون المبادئ الملائمة والوظيفية قائمة.

إن الشاهد هنا هو أنه يمكن للمبرمج أن يضيف وظيفية للفئات القائمة من خلال تعريف الوظائف في ملف منفصل. على سبيل المثال فإنك قد تأمل في إضافة مدقق إملائي لجميع المقطع/المقاطع وهو الأمر الذي يتطلب – في غالبية اللغات- ولوجا إلى الكود المصدري لفئة المقطع- ومن المعلوم أن هذه الفئات الأساسئية نادرا ما تكون موودة في شكل مصدر. وفي لغة ديلان (وغيرها من «اللغات القابلة للامتداد» extensible languages) يمكن إضافة منهج التدقيق الإملائي في وحدة التدقيق الإملائي، وتعريف جميع الفئات بالطريقة التي تجعلها قابلة للتطبيق من خلال بناء منهج التعريف. وفي هذه الحالة فإن الوظيفية الفعلية يمكن أن تعرف في وظيفة عامة مفردة، والتي تأخذ مقطعا وتعيد الأخطاء. وعندما يوضع المدقق الإملائي في برنامجك، فإن جميع المقاطع (والخانات الأخرى) ستحصل على الوظيفية المضافة.

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

أبل ديلان 
إن أبل ديلان هو تطبيق للغة ديلان أنتجته أبل كمبيوتر. وقد طور أصلا من أجل منتج أبل نيوتن.

مراجع

وصلات خارجية 
 The Dylan Reference Manual - The core language and library definition
 Getting Started with Dylan
 Gwydion Dylan - Host of two open source, optimizing Dylan compilers targeting Unix/Linux, Mac OS X, and Microsoft Windows
 The Marlais Dylan Interpreter - An implementation of a subset of Dylan, suitable for bootstrapping a compiler
 Dylan Programming Language - A general information website
 Dylan Language Wiki
 
 A Dylan Primer for Scheme Programmers

 
برمجيات متعددة المنصات
لغات برمجة أنشئت في 1992