English

Facebook Twitter Google Plus

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

فوائد

هناك الكثير من الأسباب التي تجعل لغة البرمجة الشاملة ليس فقط مفيدة وإنما ضرورية أيضا: بالإضافة للفوائد المذكورة أعلاه، صُممت لغة الأسُس لتمكين ما يلي:

الفكرة

لفهم فكرة الأسُس أكثر، فكّر بها كمعاكس لأطُر كـ LLVM و JVM و .NET. على سبيل المثال يوفر إطار LLVM وحدة إنشاء شفرة تنفيذية مفردة يُربط بها واجهات أمامية للغات متعددة. الأسُس عكس ذلك، فهي واجهة لغة موحدة يُربط بها العديد من وحدات إنشاء الشفرة التنفيذية.

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

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

ماذا عن التعارض؟

مع المرونة التي تقدّمها لغة الأسُس قد يتوقع البعض حصول تعارض بين مكتبات البناء المنتَجة من قبل فرق مختلفة. احتمالية التعارض ليست أكثر من احتمالية التعارض بين الحزم المختلفة لنظام تشغيل كلينُكس. بعض الحزم لا يُمكن استخدامها معاً، وليس من المنطقي أساساً استعمالها معاً. على سبيل المثال، لا يمكن تشغيل بيئتي Gnome و KDE في نفس الوقت، لكن يمكن اختيار البيئة الملائمة لنا من بين الاثنتين واختيار نظام التهيئة المناسب لنا من بين systemd و init وهكذا. الحالة في لغة الأسُس ستكون مشابهة حيث يمكن لبعض المكتبات التعارض مع غيرها، لكن بعكس نُظم التشغيل فإن زبائن لغة الأسُس من المبرمجين وهؤلاء لن يجدوا صعوبة في فهم هذه التفاصيل التقنية والتعامل معها. بالرغم من ذلك تحاول لغة الأسُس تقليل احتمالية التعارض بجعل قواعد اللغة حزمية، أي بتمكين حصر الإضافات القواعدية ضمن نطاق محدد. على سبيل المثال يمكن تعريف أمر "دالّة" وحصره داخل متن "مجال_تسمية" وتعريف أمر "دالّة" آخر بشفرة بناء مختلفة وحصره داخل متن "قاعدة_بيانات" وفي هذه الحالة لن يتعارض الأمران حتى لو حُمّلوا معاً داخل نفس المشروع.

لكن أليس بإمكاننا توسيع اللغات الحالية؟

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

ألا يجعل ذلك الأسُس لغة صعبة التعلم؟

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

أمثلة افتراضية

المثال الافتراضي التالي يوضّح كيف يمكن لشفرة الخادم والزبون أن تُكتبا كبرنامج موحّد:
import "System";
import "http://alusus.net/lib/networking";

def server : System.load_config("server_config");

@host[server] def getDate : function ()=>(System.Date)
{
  return System.Date.today
};

def main : function
{
  def d : getDate();
  d = convertToCurrentTimezone(d);
  print(d);
  return 0
}
المثال أعلاه يوضح كيف يمكن تطوير اللغة لتتعامل مع برامج الويب دون الحاجة لكتابة برنامج الخادم بلغة منفصلة أو في ملف منفصل. هذه الإمكانية أضيفت في السطر الثاني بعبارة تحميل المكتبة networking التي تقوم بإضافة المبدل @host وتضيف ما هو مطلوب لتطوير عملية الترجمة بحيث تنتج تلقائيا برنامج الخادم وتقوم بما يلزم لربط الخادم بالزبون دون الحاجة لإعادة بناء المترجم أو حتى تغيير الإعدادات في البيئة البرمجية. يمكن أيضاً تحميل أكثر من مكتبة مختلفة لاختيار المواصفات اللغوية التي نحتاجها في برنامجنا. فلو افترضنا أن أحداً ما قام بكتابة مكتبة chained_execution لتسهيل ربط الجمل في شكل سلسلة فيمكن تبسيط المثال أعلاه كما يلي:
import "System";
import "http://alusus.net/lib/networking";
import "http://example.net/lib/chained_execution";

def server : System.loadConfig("server_config");

@host[server] def getDate : function ()=>(System.Date)
{
  return System.Date.today
};

def main : function
{
  getDate() => convertToCurrentTimezone => print;
  return 0
}
لا حدود لما يمكن لإضافات لغة الأسُس تطويره فبيانات المترجم الداخلية متوفرة لهذه المكتبات. على سبيل المثال، يمكن لمكتبة معينة تغيير أسلوب إنشاء الشفرة التنفيذية لتمكين برمجة المعالجات الرسومية، كما في المثال الإفتراضي التالي الذي يمكن من كتابة المظللات (shaders) بتعليمها بالمبدّل gpu بعد تحميل مكتبة gpu_programming:
import "http://graphics.com/gpu_programming";

def matrix : Matrix;
def factor : Float;

def draw_lines : function (filename:String)
{
  set_transformation_matrix(matrix~ptr);
  def file : File(filename);
  while !!file.eof() draw_line(file.read[Point](), file.read[Point]())
};

def draw_line : @gpu function(p1:Point, p2:Point)
{
  def pp1 = p1 * matrix;
  def pp2 = p2 * matrix;
  line pp1, pp2, draw_pixel
};

def draw_pixel : @gpu function (p:Point)
{
  def c = color * (1 – (p-center).length()/factor);
  pixel p, c
}
بصورة عامة، لغة الأسُس تعتبر طريقة تنفيذ البرنامج أو ترجمته أو تخزينه ليست جزءاً من اللغة نفسها وليست جزءاً من تصميم البرنامج. لذلك تهدف اللغة إلى جعل تصميم أي برنامج يعتمد بشكل أساسي على وظيفته المنطقية بدل البيئة التنفيذية. على سبيل المثال، لا تحتاج لغة الأسُس إلى ملفات خاصة لتنظيم المشاريع أو إلى تقسيم الشفرة المصدرية حسب ناتج الترجمة، فهذا يُحدد في البرنامج نفسه وبلغة الأسُس كما في المثال التالي الذي ينتج ملفاً تنفيذياً ومكتبة في آن واحد ومن ملف مصدري واحد:
import "System";

def MyLib : namespace
{
  def MyClass : class
  {
    …
  }
};

def MyApp : namespace
{
  def main : function
  {
    def a : MyClass;
    …
  }
};

@ct output format:dynamic_lib, include:MyLib,
           filename:"mylib";

@ct output format:executable, include:MyApp,
           filename:"myapp";
ليس هناك حدود لما يمكن للمكتبات فعله وليس هناك حدود لعدد أو نوع المكتبات المحملة آنياً وقد صُممت لغة الأسُس بطريقة تسمح بإضافة عدد لا محدد من القواعد اللغوية وتُقلل احتمال تصادمها ببعض وتضمن أيضاً تناسقها. راجع تصميم اللغة في صفحة الوثائق لمزيد من المعلومات.

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

خارطة الطريق

فيما يلي العلامات الزمنية الفارقة المخطط لها: بعد ذلك يبدأ العمل على الميزات المتقدمة مثل الأنماط البرمجية الأخرى والتنفيذ المتوازي والبرامج الشبكية والتعامل عالي المستوى مع الذاكرة وقواعد البيانات وغيرها.
جميع الحقوق محفوظة لشركة الأسُس للبرمجيات 2015م \ 1436هـ - Copyright © 2015 Alusus Software Ltd