التصنيف | |
---|---|
التنميط | |
ظهرت في |
1996 |
صممها | |
نظام التشغيل | |
الرخصة | |
نوع |
المطور | |
---|---|
الإصدار الأول | |
الإصدار الأخير |
3.12.0 |
مشتقة من | |
---|---|
متأثرة بـ | |
أثرت في |
امتدادات الملفات | |
---|---|
موقع الويب |
لغة كامل الموضوعية أو الأو كامل هي التطبيق الرئيسي للغة البرمجة كامل والتي كتبها كل من زافيير ليروي وجيورم فويلون وداميان دوليجي وديديير ريمي وآخرين عام 1996. وتعمل لغة أو كامل على التوسع في لغة كامل الرئيسية مع مقومات توجهها موضوعي.
وتتضمن مجموعة أدوات لغة أو كامل مترجم على أعلى مستوى ومصنف بايت كود ومصنف شفرة أصلية مثالي. كما يضم مكتبة كبيرة قياسية تجعله مفيدا بالنسبة للكثير من التطبيقات الشبيهة كالبايثون أو البريل ويعد أيضا من مقومات البرمجة ذات التوجه الموضوعي والوحدوية بشكل كبير مما يجعله قابل للتطبيق بالنسبة لهندسة البرمجيات بصورة واسعة النطاق. وأو كامل هو البرنامج اللاحق لكامل لايت. وكلمة كامل هي اختصار للمصطلح Categorical Abstract Machine Language أو لغة الآلة المجردة المطلقة بالرغم من أو كامل تتخلى عن هذه الآلة المجردة.
كما أنه يتم إدارة مشروع أو كامل عبر مورد مفتوح وحر تحتفظ به شركة إنريا في الأساس. وفي السنوات الأخيرة، اشتقت العديد من اللغات الجديدة بعض عناصرها من الأو كامل وأكثرها شهرة هي #F وسكالا.
تشتهر تلك اللغات المشتقة من إم إل بأنظمتها النمطية الساكنة ومصنفات الاستدلال على النمط. كما توحد الأو كامل بين البرمجة الوظيفية والإلزامية والموضوعية تحت مظلة نظام طباعة شبيه بالإم إل. وهذا يعني أنه ليس هناك ضرورة لأن يكون مؤلف البرنامج معتادا على نموذج اللغة الوظيفية البحت من أجل استخدام الأو كامل.
ويمكن أن يساعد نظام النمط الساكن للأو كامل في التخلص من المشاكل أثناء التشغيل، إلا أنه يجبر المبرمج أيضا على التأقلم مع بعض القيود الخاصة بنظام الطباعة والتي تتطلب تفكيرا عميقا وانتباها شديدا. أما المصنف المستدل على النمط فهو يقلل بشدة من الحاجة لحواشي طباعة تفسيرية يدوية (على سيبل المثال لا تحتاج طباعة البيانات للمتغيرات وتوقيع الوظائف عادة أن يتم التصريح عنها علنا، كما تفعل في الجافا). وبالرغم من ذلك فإن الاستخدام الفاعل لنظام طباعة الأو كامل يمكن أن يحتاج إلى بعض التعقيدات من جانب المبرمج.
ويتم تمييز لغة أو كامل عن اللغات الأخرى بتأكيدها على الأداء. أولا فإن نظام نمطيتها الساكن يجعل عدم التوافق في الطباعة أثناء التشغيل أمرا مستحيلا ومن ثم يمكن تجنب الطباعة أثناء التشغيل والتدقيقات الأمنية التي تكون عبئا على أداء اللغات المطبوعة ديناميكيا بينما لا تزال تكفل الأمان أثناء التشغيل (فيما عدا حين يتم إغلاق ميزة تدقيق حدود الصفوف أو حين يتم استخدام ميزات طباعة معينة غير آمنة، وهي حالات نادرة بما يكفي يمكن تجنبها بسهولة عمليا).
وبغض النظر عن تدقيق الطباعة فإن لغات البرمجة الوظيفية هي بوجه عام تتحدى تصنيف شيفرة لغة الآلة ذات الكفاءة بسبب بعض الأمور مثل مشكلة «فانارج»، بالإضافة إلى الحلقة والسجل وتعليمات المثالية القياسية، فإن المصنف المثالي لأو كامل يقوم بتوظيف تقنيات تحاليل برامج ساكنة لجعل القيمة الخاصة بالفراغات الصندوقية وتقسيم الإغلاق أفضل بما يساعد على زيادة أداء الشفرة الناتجة حتى إذا كانت تستغل مقومات البرمجة الوظيفية بشكل مكثف.
وقد صرح زافير ليروي بأن «لغة أو كامل تعمل على الأقل على توصيل 50% من أداء مصنف السي المتواضع»،[2] ولكن من الممكن إجراء مقارنة مباشرة. ويمكن تطبيق بعض وظائف المكتبة القياسية للأو كامل عبر أنظمة حسابية أسرع من الوظائف المكافئة في المكتبات القياسية للغات الأخرى. على سبيل المثال فإن تطبيق اتحاد معين في مكتبة الأو كامل أسرع بشكل متقارب من الوظيفة المكافئة في المكتبات القاسية للغات الإلزامية (مثل السي بلس بلس والجافا) لأن تطبيق الأو كامل يستغل ثبوت بعض المجموعات من أجل إعادة استخدام أجزاء من مجموعات المدخلات في النتائج (المثابرة).
من بين سمات أوكامل: نظام نمطي ساكن، استدلال من النمط، تعدد الأشكال القياسي، تكرار اللاحقات، التطابق مع النموذج، إيقاف من الدرجة الأولى للمفردات، وحدات قياسية (فانكتور)، التعامل الاستثنائي وجمع القمامات الآلية الإضافية والتوليدية.
وتشتهر لغة أو كامل على وجه الخصوص بالتوسع في الاستدلال بالنمط بأسلوب إم إل نحو نظام موضوعي في اللغة ذات الهدف العام، ويتيح ذلك الطباعة الثانوية الهيكلية حيث تكون الأحرف المطبوعة متطابقة إذا كانت توقيعات طريقتها متوافقة أيضا بغض النظر عن موروثاتها المعروفة والسمة الغير معتادة في اللغات التي تطبع بطريقة ساكنة.
كما يتوافر سطح بيني للوظائف الغريبة ليتم ربطها ببدائيات لغة السي متضمنا دعما لغويا للصفوف العددية ذات الكفاءة في صياغات تتماشى مع كل من السي والفورتران. وتدعم لغة الأو كامل أيضا إنشاء مكتبات لوظائف الأو كامل يمكن ربطها بالبرنامج الرئيسي في السي بحيث يمكن للمرء توزيع مكتبة الأو كامل على مبرمجي السي الذين ليس لديهم أي معرفة أو ليس متاحا لديهم تطبيق الأو كامل.
ويتضمن توزيع أوكامل:
كما يتوافر مصنف شفرات أصلي للعديد من المنصات من بينها اليونكس والمايكروسوفت ويندوز والأبل ماك أو إس. كما يضمن مدعم توليد الشفرة الأصلية إمكانية نقل الهياكل الرئيسية بشكل ممتاز: IA-32, IA-64, AMD64, HP/PA; PowerPC, SPARC, Alpha, MIPS و StrongARM.
ويمكن تحرير شفرة البايت وبرامج الشفرة الأصلية بأسلوب متعدد المراحل مع إمكانية التحول إلى سياق وقائي. ومع ذلك نظرا لأن جامع القمامة ليس مصمم من أجل التزامن فليس هناك ميزة المعالجة المتعددة المتناسقة.[3] تنفذ مراحل الأو كامل في نفس العملية عبر مشاركة الوقت فقط ك«فانكتوري وأوكمالنت/ بلازما»
يمكن بكل سهولة دراسة قصاصات شفرة الأو كامل بإدخالها إلى «مستوى أعلى». وهذه هي جلسة أو كامل تفاعلية التي تطبع الأنماط الاستدلالية للتعبيرات الناتجة أو المحددة. يبدأ المستوى الأعلى من الأو كامل ببساطة عبر تنفيذ برنامج «أوكامل»:
$ ocaml Objective Caml version 3.09.0
#
بعد ذلك يمكن إدخال الشفرة على الفور، على سبيل المثال لحساب 1+2*3:
# 1 + 2 * 3;; - : int = 7
يستدل الأوكامل على نمط التعبير بكونه "int" (أي رقم صحيح دقيق ناتج عن الآلة) ويمنحنا الرقم "7"
البرنامج التالي "hello.ml":
يمكن تصنيفه إلى شفرة بايت قابلة للتنفيذ:
$ ocamlc hello.ml -o hello
أو تصنيفه إلى شفرة مصدرية مثالية قابلة للتنفيذ:
$ ocamlopt hello.ml -o hello
ثم يتم تنفيذها بالطريقة التالية:
$./hello Hello world! $
القوائم هي أحد أنواع البيانات الرئيسية في الأو كامل. والمثال التالي للشفرة يحدد قيم دالة متكررة تقبل برهانا واحدا xs. وتتكرر الدالة عبر قائمة موجودة وتتيح لنا قيمة من عناصر الأرقام الصحيحة. بيان: التطابق Match" يعني وجود متشابهات: ومع عنصر التحول للغات السي بلس سي سي أو الجافا، بالرغم من أنه أمر أكثر عمومية.
let rec sum xs =
match xs with
[] -> 0
| x :: xs' -> x + sum xs'
# sum [1;2;3;4;5];; - : int = 15
وهناك طريقة أخرى تكون باستخدام دالة الطي القياسية التي تنجح مع القوائم:
let sum xs =
List.fold_left (+) 0 xs
# sum [1;2;3;4;5];; - : int = 15
تعير لغة أو كامل نفسها للتعبير الدقيق لعمليات حسابية متكررة. المثال التالي على أحد الشفرات يستعين بعمليات حسابية شبيهة بالكويك سورت أو التصنيف السريع الذي يقوم بتصنيف أحد القوائم بترتيب متزايد ومتسرع.
let rec qsort = function
| [] -> []
| pivot :: rest ->
let is_less x = x <pivot in
let left, right = List.partition is_less rest in
qsort left @ [pivot] @ qsort right
البرنامج التالي يقوم بحساب أصغر عدد من الأشخاص الموجودين في غرفة ما اولذين يكون احتمال تفرد يوم مولدهم بشكل كامل أقل من 50% (بما يسمى مفارقة عيد الميلاد حيث يكون الاحتمال بالنسبة لشخص واحد 100% بينما لشخصين 364/365... الخ) (الإجابة = 23).
let year_size = 365.;;
let rec birthday_paradox prob people =
let prob' = (year_size -. float people) /. year_size *. prob in
if prob' <0.5 then
Printf.printf "answer = %d\n" (people+1)
else
birthday_paradox prob' (people+1) ;;
birthday_paradox 1.0 1
الشفرة التالية تحدد تشفيرا للكنيسة وضعته للأعداد الطبيعية، مع عدد لاحق (succ) وعدد إضافي (add). الأعداد الكنسية هي دالة ذات مستوى أعلى تقبل الدالة f والقيمة x وتضيف f إلى x لعدد n من المرات. ولتحويل العدد الكنسي من قيمته الوظيفية إلى سلسلة معلومة نقوم بإدخاله على دالة تدخل السلسلة s إلى مدخلاتها والتسلسل الثابت " 0
let zero f x = x
let succ n f x = f (n f x)
let one = succ zero
let two = succ (succ zero)
let add n1 n2 f x = n1 f (n2 f x)
let to_string n = n (fun k -> "S" ^ k) "0"
let _ = to_string (add (succ two) two)
يمكن الوصول بشكل مباشر إلى مجموعة متنوعة من المكتبات من أوكامل. على سبيل المثال، تحتوي أو كامل على مكتبة مؤسسة بداخلها للعمليات الرياضية الدقيقة في التحكم. ونظرا لأن الدوال العاملية تتزايد بسرعة كبيرة، فهي سرعان ما تغمر الأعداد الدقيقة آليا (عادة 32 أو 64 بايت). ومن ثم فإن التحويل إلى عوامل أمر مناسب للعمليات الرياضية الدقيقة تحكميا.
في الأوكامل تتيح وحدة num عمليات حسابية دقيقة تحكميا ويمكن تحميلها إلى مستوى أعلى عامل باستخدام:
# #load "nums.cma";;
# open Num;;
يمكن بعد ذلك كتابة الدالة العاملية باستخدام عمليات عددية دقيقة تحكميا =/,*/ و-/:
# let rec fact n =
if n =/ Int 0 then Int 1 else n */ fact(n -/ Int 1);;
val fact : Num.num -> Num.num = <fun>
ويمكن للدالة أن تقوم بحساب عوامل أكبر مثل 120!:
# string_of_num (fact (Int 120));;
- : string =
"6689502913449127057588118054090372586752746333138029810295671352301633
55724496298936687416527198498130815763789321409055253440858940812185989
8481114389650005964960521256960000000000000000000000000000"
تركيب الجمل المرهق بالنسبة لعمليات Num يمكن التخفيف منه وذلك بفضل الامتداد «كامل بي فور سينتاكس» الذي يسمى الحمل الزائد المعين Delimited Overloafing:
# #require "pa_do.num";;
# let rec fact n = Num.(if n = 0 then 1 else n * fact(n-1));;
val fact : Num.num -> Num.num = <fun>
# fact Num.(120);;
- : Num.num =
<num 668950291344912705758811805409037258675274633313802981029567
135230163355724496298936687416527198498130815763789321409055253440
8589408121859898481114389650005964960521256960000000000000000000000000000>
البرنامج التالي "simple.ml" يقوم بتصميم مثلث دوار ثنائي الأبعاد باستخدام أوبن جل:
let () =
ignore(Glut.init Sys.argv);
Glut.initDisplayMode ~double_buffer:true ();
ignore (Glut.createWindow ~title:"OpenGL Demo");
let angle t = 10. *. t *. t in
let render () =
GlClear.clear [ `color ];
GlMat.load_identity ();
GlMat.rotate ~angle: (angle (Sys.time ())) ~z:1. ();
GlDraw.begins `triangles;
List.iter GlDraw.vertex2 [-1., -1.; 0., 1.; 1., -1.];
GlDraw.ends ();
Glut.swapBuffers () in
GlMat.mode `modelview;
Glut.displayFunc ~cb:render;
Glut.idleFunc ~cb:(Some Glut.postRedisplay);
Glut.mainLoop ()
ويحتاج ذلك إلى روابط تربط بين لابل جل وأوبن جل. يمكن بعد ذلك تصنيف البرنامج إلى شفرة بايت باستخدام:
$ ocamlc -I +lablGL lablglut.cma lablgl.cma simple.ml -o simple
أو إلى شفرة مصدرية:
$ ocamlopt -I +lablGL lablglut.cmxa lablgl.cmxa simple.ml -o simple
ثم التنفيذ:
$./simple
وهو برنامج جرافيك ثنائي وثلاثي الأبعاد أكثر تطورا وتعقيدا وعالي الأداء تم تطويره بسهولة في الأو كامل. وبفضل استخدام أوبن جل فإن البرامج الناتجة لا تكون فقط بليغة وعلى قدر من الكفاءة ولكنها تكون أيضا ذات منصة تبادلية مصنفة دون أي تغير في كافة المنصات الرئيسية.
الشفرة التالية تستطيع حساب تسلسل فيبوناتشي لعدد تم إدخاله نشير إليه ب «ن»، وهو يستعين بالتكرار للاحقة والتوافق النمطي:
let rec fib_aux n a b =
match n with
| 0 -> a
| _ -> fib_aux (n - 1) (a + b) a;;
let fib n = fib_aux n 0 1;;
من المحتمل أكثر كتابتها: [بحاجة لمصدر]
let fib n =
let rec fib_aux n a b =
match n with
| 0 -> a
| _ -> fib_aux (n - 1) (a + b) a
in
fib_aux n 0 1;;
ميتا أو كامل [4] هو امتدادا لبرمجية متعددة الاستخدامات من أوكامل تمكن من التصنيف الإضافي لشفرات آلات جديدة خلال وقت التشغيل. وتحت ظروف معينة يمكن حدوث بعض التسارع الواضح باستخدام البرمجة متعددة المراحل نظرا لتوافر المزيد من المعلومات التفصيلية حول البيانات التي ينبغي معالجتها في وقت التشغيل أكثر من تلك في وقت التصنيف المعتاد، لذلك يمكن للمصنف الإضافي التخلص من الكثير من حالات تفقد الظروف... الخ.
فعلى سبيل المثال: إذا كان من المعروف أنه في وقت التصنيف يكون من المطلوب وجود دالة قوة محددة x -> x^n باستمرار، ولكن القيمة «ن» معلومة وقت في وقت التشغيل، فبإمكانك استخدام دالة قوة ذات مرحلتين في الميتا أوكامل:
let rec power n x =
if n = 0
then.<1>.
else
if even n
then sqr (power (n/2) x)
else.<.~x *. ~(power (n-1) x)>.
وبمجرد أن تعلم قيمة «ن» وقت التشغيل يمكنك أن تتولد دالة قوة سريعة للغاية ومتخصصة أيضا:
.<fun x ->.~(power 5.<x>.)>.
فتكون النتيجة:
fun x_1 -> (x_1 *
let y_3 =
let y_2 = (x_1 * 1)
in (y_2 * y_2)
in (y_3 * y_3))
ويتم جمع الدالة الجديدة تلقائيا:
أتومكامل وتتيح تزامما بدائيا بالنسبة للتطبيق شديد الصغر للشفرة.
وقد اتخذت شركة جين ستريت كابيتال التجارية الخاصة لغة أو كامل لتكون لغتها المفضلة.
-oriented dialect of ML -oriented extension to the functional language هاسكل