أوكامل
| النماذج | متعدد النماذج : وظيفي ، إلزامي ، معياري ، [1] موجه نحو الكائنات |
|---|---|
| عائلة | ML : كامل |
| صمم بواسطة | خافيير ليروي ، جيروم فويلون، داميان دوليجيز ، ديدييه ريمي، أسكندر سواريز |
| المطور | إينريا |
| ظهرت لأول مرة | 1996 [2] |
| إصدار مستقر | 5.2.0 [3]
/ 13 مايو 2024 |
| الانضباط في الطباعة | مستنتج ، ثابت ، قوي ، بنيوي |
| لغة التنفيذ | أوكامل، سي |
| منصة | IA-32 ، x86-64 ، الطاقة ، SPARC ، ARM 32-64 ، RISC-V |
| نظام التشغيل | متعدد المنصات : Linux ، Unix ، macOS ، Windows |
| رخصة | رخصة LGPLv2.1 |
| ملحقات اسم الملف | .مل، .ملي |
| موقع إلكتروني | ocaml.org |
| متأثر بـ | |
| C ، Caml ، Modula-3 ، Pascal ، Standard ML | |
| متأثر | |
| ATS ، Coq ، Elm ، F# ، F* ، Haxe ، Opa ، Rust ، [4] Scala | |
OCaml ( / oʊ ˈkæməl / oh - KAM -əl ، كانت تُعرف سابقًا باسم Objective Caml ) هي لغة برمجة متعددة النماذج وعالية المستوى وذات أغراض عامة ، والتي توسع لهجة Caml من التعلم الآلي بميزات موجهة للكائنات . تم إنشاء OCaml في عام 1996 بواسطة Xavier Leroy وJérôme Vouillon و [5] Damien Doligez وDidier Rémy و [6] Ascánder Suárez وآخرين.
تتضمن سلسلة أدوات OCaml مفسّرًا تفاعليًا من المستوى الأعلى ، ومُجمِّعًا للبايت كود ، ومُجمِّعًا للكود الأصلي المُحسِّن ، ومُصحِّحًا قابلًا للعكس ، ومدير حزم (OPAM) إلى جانب نظام بناء قابل للتكوين لـ OCaml (Dune). تم تطوير OCaml في البداية في سياق إثبات النظريات الآلي ، ويُستخدم في التحليل الثابت وبرامج الطرق الرسمية . وبخلاف هذه المجالات، فقد وجد استخدامًا في برمجة الأنظمة ، وتطوير الويب ، والمرافق المالية المحددة، من بين مجالات التطبيق الأخرى.
كان الاختصار CAML في الأصل يرمز إلى لغة الآلة المجردة الفئوية ، لكن OCaml يغفل هذه الآلة المجردة . [7] OCaml هو مشروع برمجي مفتوح المصدر ومجاني يديره ويديره بشكل أساسي المعهد الفرنسي للأبحاث في علوم الكمبيوتر والأتمتة (Inria). في أوائل العقد الأول من القرن الحادي والعشرين، تم اعتماد عناصر من OCaml بواسطة العديد من اللغات، ولا سيما F# و Scala .
فلسفة
تشتهر اللغات المشتقة من ML بأنظمة الأنواع الثابتة ومترجمات استنتاج الأنواع . توحد OCaml البرمجة الوظيفية والإلزامية والموجهة للكائنات تحت نظام نوع يشبه ML. وبالتالي، لا يحتاج المبرمجون إلى أن يكونوا على دراية كبيرة بنموذج اللغة الوظيفية البحتة لاستخدام OCaml.
من خلال مطالبة المبرمج بالعمل ضمن قيود نظام النوع الثابت الخاص به، يزيل OCaml العديد من مشكلات وقت التشغيل المتعلقة بالنوع المرتبطة باللغات ذات النوع الديناميكي . كما يقلل مُجمِّع الاستدلال على النوع الخاص بـ OCaml بشكل كبير من الحاجة إلى التعليقات التوضيحية اليدوية للنوع المطلوبة في معظم اللغات ذات النوع الثابت. على سبيل المثال، لا يلزم عادةً الإعلان عن أنواع بيانات المتغيرات وتوقيعات الوظائف بشكل صريح، كما هو الحال في لغات مثل Java و C# ، لأنه يمكن استنتاجها من المشغلات والوظائف الأخرى التي يتم تطبيقها على المتغيرات والقيم الأخرى في الكود. قد يتطلب الاستخدام الفعال لنظام النوع الخاص بـ OCaml بعض التطور من جانب المبرمج، ولكن هذا التخصص يُكافأ ببرامج موثوقة وعالية الأداء.
ربما يكون OCaml هو الأكثر تميزًا عن اللغات الأخرى ذات الأصول الأكاديمية من خلال التركيز على الأداء. يمنع نظام النوع الثابت الخاص به عدم تطابق النوع وقت التشغيل وبالتالي يتجنب فحوصات النوع والسلامة وقت التشغيل التي تثقل كاهل أداء اللغات ذات النوع الديناميكي، مع ضمان سلامة وقت التشغيل، باستثناء عندما يتم إيقاف تشغيل فحص حدود المصفوفة أو عند استخدام بعض الميزات غير الآمنة للنوع مثل التسلسل . هذه نادرة بما يكفي بحيث يكون تجنبها ممكنًا تمامًا في الممارسة العملية.
بصرف النظر عن تكلفة فحص النوع، فإن لغات البرمجة الوظيفية ، بشكل عام، تشكل تحديًا في التجميع إلى كود لغة الآلة الفعال، بسبب مشكلات مثل مشكلة funarg . جنبًا إلى جنب مع تحسينات الحلقة القياسية والسجلات والتعليمات، يستخدم المترجم المحسن لـ OCaml أساليب تحليل البرنامج الثابتة لتحسين مربعات القيمة وتخصيص الإغلاق ، مما يساعد على تعظيم أداء الكود الناتج حتى لو استخدم بشكل مكثف بنيات البرمجة الوظيفية.
صرح Xavier Leroy أن "OCaml تقدم ما لا يقل عن 50٪ من أداء مُجمِّع C اللائق"، [8] على الرغم من استحالة المقارنة المباشرة. يتم تنفيذ بعض الوظائف في مكتبة OCaml القياسية باستخدام خوارزميات أسرع من الوظائف المكافئة في المكتبات القياسية للغات أخرى. على سبيل المثال، يكون تنفيذ اتحاد المجموعة في مكتبة OCaml القياسية أسرع نظريًا من الوظيفة المكافئة في المكتبات القياسية للغات الآمرة (على سبيل المثال، C++ وJava) لأن تنفيذ OCaml يمكنه استغلال ثبات المجموعات لإعادة استخدام أجزاء من مجموعات الإدخال في الإخراج (انظر بنية البيانات المستمرة ).
تاريخ

تطوير ML (لغة ميتا)
بين سبعينيات وثمانينيات القرن العشرين، عمل روبن ميلنر ، عالم الكمبيوتر البريطاني والحائز على جائزة تورينج ، في مختبر جامعة إدنبرة لأسس علوم الكمبيوتر . [9] [10] كان ميلنر وآخرون يعملون على أدوات إثبات النظريات ، والتي تم تطويرها تاريخيًا بلغات مثل ليسب . واجه ميلنر مرارًا وتكرارًا مشكلة أن أدوات إثبات النظريات ستحاول ادعاء صحة الإثبات من خلال وضع غير الإثباتات معًا. [10] ونتيجة لذلك، واصل تطوير لغة التعريف لمنطق الوظائف القابلة للحساب ، وهي لغة تسمح للكاتب فقط ببناء أدلة صالحة بنظام النوع المتعدد الأشكال الخاص بها. [11] تم تحويل ML إلى مُجمِّع لتبسيط استخدام LCF على أجهزة مختلفة، وبحلول الثمانينيات، تم تحويله إلى نظام كامل خاص به. [11] سيخدم ML في النهاية كأساس لإنشاء OCaml.
في أوائل الثمانينيات، كانت هناك بعض التطورات التي دفعت فريق فورميل التابع لـ INRIA إلى الاهتمام بلغة التعلم الآلي. استخدم لوكا كارديلي ، أستاذ الأبحاث في جامعة أكسفورد ، آلته المجردة الوظيفية لتطوير تنفيذ أسرع للتعلم الآلي، واقترح روبن ميلنر تعريفًا جديدًا للتعلم الآلي لتجنب التباعد بين التطبيقات المختلفة. في الوقت نفسه، طور بيير لويس كورين، الباحث الأول في جامعة باريس ديدرو ، حسابًا للمجموعات التصنيفية وربطه بحساب لامدا ، مما أدى إلى تعريف الآلة المجردة التصنيفية (CAM). أدرك جاي كوزينو، الباحث في جامعة باريس ديدرو، أنه يمكن تطبيق ذلك كطريقة تجميع للتعلم الآلي. [12]
التنفيذ الأول
تم تصميم وتطوير Caml في البداية بواسطة فريق Formel التابع لـ INRIA برئاسة Gérard Huet . تم إنشاء أول تنفيذ لـ Caml في عام 1987 واستمر في التطوير حتى عام 1992. على الرغم من أن Ascánder Suárez كان يقودها، إلا أن Pierre Weis وMichel Mauny استمروا في التطوير بعد رحيله في عام 1988. [12]
يُقتبس من جاي كوزينو أنه يتذكر أن خبرته في تنفيذ لغات البرمجة كانت محدودة للغاية في البداية، وأنه كان هناك العديد من أوجه القصور التي كان مسؤولاً عنها. وعلى الرغم من هذا، فإنه يعتقد أن "أسكندر وبيير وميشيل قاموا بعمل جيد للغاية". [12]
كامل لايت
بين عامي 1990 و1991، صمم Xavier Leroy تنفيذًا جديدًا لـ Caml يعتمد على مفسّر بايت كود مكتوب بلغة C. بالإضافة إلى ذلك، كتب Damien Doligez نظام إدارة ذاكرة، يُعرف أيضًا باسم جامع القمامة المتسلسل ، لهذا التنفيذ. [11] هذا التنفيذ الجديد، المعروف باسم Caml Light ، حل محل تنفيذ Caml القديم وتم تشغيله على أجهزة سطح مكتب صغيرة. [12] في السنوات التالية، ظهرت مكتبات مثل أدوات معالجة بناء الجملة الخاصة بـ Michel Mauny وساعدت في الترويج لاستخدام Caml في الفرق التعليمية والبحثية. [11]
كامل لايت خاص
في عام 1995، أصدر Xavier Leroy برنامج Caml Special Light، والذي كان نسخة محسنة من Caml. [12] تمت إضافة مُجمِّع كود أصلي مُحسَّن إلى مُجمِّع البايت كود، مما أدى إلى زيادة الأداء بشكل كبير إلى مستويات قابلة للمقارنة مع اللغات السائدة مثل C++ . [11] [12] كما صمم Leroy نظام وحدات عالي المستوى مستوحى من نظام وحدات Standard ML والذي قدم مرافق قوية للتجريد والمعلمة وجعل البرامج الأكبر حجمًا أسهل في البناء. [11]
الهدف الكامل
قام ديدييه ريمي وجيروم فويون بتصميم نظام كتابة معبر للأشياء والفئات، والذي تم دمجه داخل Caml Special Light. أدى هذا إلى ظهور لغة Objective Caml، التي تم إصدارها لأول مرة في عام 1996 ثم تمت إعادة تسميتها إلى OCaml في عام 2011. دعم نظام الكائنات هذا بشكل ملحوظ العديد من التعبيرات الشائعة الموجهة للكائنات بطريقة آمنة للنوع بشكل ثابت، في حين تسببت نفس التعبيرات في عدم صحة أو تطلبت فحوصات وقت التشغيل في لغات مثل C++ أو Java . في عام 2000، قام جاك جاريج بتوسيع Objective Caml بميزات جديدة متعددة مثل الطرق المتعددة الأشكال والمتغيرات والحجج المسمى والاختيارية. [11] [12]
التطوير المستمر
تمت إضافة تحسينات اللغة بشكل تدريجي على مدار العقدين الماضيين لدعم قواعد البيانات التجارية والأكاديمية المتنامية في OCaml. [11] أضاف إصدار OCaml 4.0 في عام 2012 أنواع البيانات الجبرية المعممة (GADTs) ووحدات من الدرجة الأولى لزيادة مرونة اللغة. [11] إصدار OCaml 5.0.0 في عام 2022 [13] هو إعادة كتابة كاملة لوقت تشغيل اللغة، وإزالة قفل GC العالمي وإضافة معالجات التأثير عبر الاستمرارية المحددة . تمكن هذه التغييرات من دعم التوازي في الذاكرة المشتركة والتزامن دون تمييز الألوان على التوالي.
استمر تطوير OCaml داخل فريق Cristal في INRIA حتى عام 2005، عندما خلفه فريق Gallium. [14] بعد ذلك، خلف فريق Cambium Gallium في عام 2019. [15] [16] اعتبارًا من عام 2023، يوجد 23 مطورًا أساسيًا لتوزيع المترجم من مجموعة متنوعة من المنظمات [17] و 41 مطورًا لنظام أدوات وتغليف OCaml الأوسع. [18] في عام 2023، تم الاعتراف بمترجم OCaml بجائزة ACM SIGPLAN's Programming Languages Software Award .
سمات
يتميز OCaml بنظام نوع ثابت ، واستدلال النوع ، وتعدد الأشكال البارامترية ، والتكرار الذيلي ، ومطابقة الأنماط ، والإغلاقات المعجمية من الدرجة الأولى ، والمتتابعات (الوحدات النمطية البارامترية) ، ومعالجة الاستثناءات ، ومعالجة التأثير ، وجمع القمامة التلقائي التدريجي .
تتميز لغة OCaml بقدرتها على توسيع نطاق استدلال النوع على غرار ML إلى نظام كائنات في لغة عامة الغرض. وهذا يسمح بالتصنيف الفرعي البنيوي ، حيث تكون أنواع الكائنات متوافقة إذا كانت توقيعات طريقتها متوافقة، بغض النظر عن وراثتها المعلنة (وهي ميزة غير عادية في اللغات ذات النوع الثابت).
يتم توفير واجهة وظيفة أجنبية للربط ببدائيات C ، بما في ذلك دعم اللغة للمصفوفات الرقمية الفعالة في التنسيقات المتوافقة مع كل من C و Fortran . يدعم OCaml أيضًا إنشاء مكتبات من وظائف OCaml التي يمكن ربطها ببرنامج رئيسي في C، بحيث يمكن توزيع مكتبة OCaml على مبرمجي C الذين ليس لديهم أي معرفة أو تثبيت لـ OCaml.
على الرغم من أن OCaml لا يحتوي على نظام ماكرو كجزء لا يتجزأ من اللغة (البرمجة الوصفية)، أي الدعم المدمج للمعالجة المسبقة، فإن منصة OCaml تدعم رسميًا مكتبة لكتابة مثل هذه المعالجات المسبقة. يمكن أن تكون هذه من نوعين: نوع يعمل على مستوى الكود المصدر (كما في C)، ونوع يعمل على مستوى شجرة بناء الجملة المجردة . النوع الأخير، والذي يسمى PPX، وهو اختصار لـ Pre-Processor eXtension، هو النوع الموصى به.
يحتوي توزيع OCaml على:
- أدوات التحليل المعجمي والتحليل تسمى ocamllex و ocamlyacc
- مصحح أخطاء يدعم الرجوع إلى الوراء للتحقيق في الأخطاء
- مولد الوثائق
- Profiler – لقياس الأداء
- العديد من المكتبات ذات الأغراض العامة
يتوفر مُجمِّع الكود الأصلي للعديد من المنصات، بما في ذلك Unix و Microsoft Windows و Apple macOS . يتم تحقيق قابلية النقل من خلال دعم إنشاء الكود الأصلي للهندسة المعمارية الرئيسية:
- X86-64 (AMD64)، و RISC-V ، و ARM64 (في OCaml 5.0.0 والإصدارات الأحدث) [19]
- IBM Z (قبل OCaml 5.0.0، والعودة إلى OCaml 5.1.0)
- الطاقة (قبل OCaml 5.0.0، ومن المقرر أن تظهر مرة أخرى في OCaml 5.2.0)
- IA-32 و ARM (قبل OCaml 5.0.0)
- SPARC (قبل OCaml 4.06.0)
- DEC Alpha و HPPA و IA64 و MIPS (قبل OCaml 4.00.0)
يدعم مُجمِّع البايت كود التشغيل على أي بنية 32 بت أو 64 بت عندما لا يتوفر إنشاء كود أصلي، مما يتطلب مُجمِّع C فقط.
يمكن كتابة برامج البايت كود OCaml والبرامج الأصلية بأسلوب متعدد الخيوط ، مع التبديل المسبق للسياق. يتم تنفيذ خيوط OCaml في نفس المجال [20] من خلال تقاسم الوقت فقط. ومع ذلك، يمكن لبرنامج OCaml أن يحتوي على عدة مجالات.
أمثلة التعليمات البرمجية
تعتمد هذه المقالة بشكل كبير أو كليًا على مصدر واحد . ( يناير 2024 ) |
يمكن دراسة مقتطفات من كود OCaml بسهولة عن طريق إدخالها في REPL على المستوى الأعلى . هذه جلسة OCaml تفاعلية تطبع الأنواع المستنتجة من التعبيرات الناتجة أو المحددة. [21] يتم بدء تشغيل المستوى الأعلى لـ OCaml ببساطة عن طريق تنفيذ برنامج OCaml:
$ ocaml
الهدف Caml الإصدار 3.09.0
#
يمكن بعد ذلك إدخال الكود عند موجه "#". على سبيل المثال، لحساب 1+2*3:
# 1 + 2 * 3 ;; - : int = 7
يستنتج OCaml نوع التعبير بأنه "int" ( عدد صحيح بدقة الآلة ) ويعطي النتيجة "7".
مرحبا بالعالم
البرنامج التالي "hello.ml":
print_endline "مرحبا بالعالم!"
يمكن تجميعها في ملف بايت كود قابل للتنفيذ:
$ ocamlc hello.ml -o hello
أو تم تجميعها في ملف تنفيذي محسّن للكود الأصلي:
$ ocamlopt hello.ml -o hello
ونفذت:
$ ./مرحبا
مرحبا بالعالم!
$
تحدد الحجة الأولى لـ ocamlc، "hello.ml"، ملف المصدر الذي سيتم تجميعه، كما تحدد العلامة "-o hello" ملف الإخراج. [22]
خيار
يقوم منشئ optionالنوع في OCaml، على غرار Maybeالنوع في Haskell ، بزيادة نوع البيانات المحدد إما لإرجاع Someقيمة نوع البيانات المحدد، أو لإرجاع None. [23] يتم استخدام هذا للتعبير عن أن القيمة قد تكون موجودة أو قد لا تكون موجودة.
# بعض 42 ;;
- : int option = بعض 42
# لا شيء ;;
- : ' خيار = لا شيء
هذا مثال لوظيفة تقوم إما باستخراج int من خيار، إذا كان هناك واحد بالداخل، وتحويله إلى سلسلة ، أو إذا لم يكن كذلك، فترجع سلسلة فارغة:
دعونا نستخرج o =
نطابق o مع
| Some i -> string_of_int i
| None -> "" ;;
# استخراج ( بعض 42 );;
- : سلسلة = "42"
# استخراج لا شيء ;;
- : سلسلة = ""
تلخيص قائمة الأعداد الصحيحة
القوائم هي أحد أنواع البيانات الأساسية في OCaml. يحدد مثال التعليمات البرمجية التالي دالة متكررة sum تقبل وسيطة واحدة، وهي integers ، والتي من المفترض أن تكون قائمة من الأعداد الصحيحة. لاحظ الكلمة الأساسية recالتي تشير إلى أن الدالة متكررة. تتكرر الدالة بشكل متكرر على القائمة المعطاة من الأعداد الصحيحة وتوفر مجموع العناصر. تحتوي عبارة match على أوجه تشابه مع عنصر switch في C ، على الرغم من أنها أكثر عمومية.
دع rec sum integers = (* تعني الكلمة الأساسية rec "متكرر". *)
تطابق الأعداد الصحيحة مع
| [] -> 0 (* العائد 0 إذا كانت الأعداد الصحيحة هي القائمة الفارغة
[]. *)
| first :: rest -> first + sum rest ;; (* استدعاء متكرر إذا كانت الأعداد الصحيحة هي
قائمة غير فارغة؛ first هو العنصر الأول
في القائمة، و rest هي
قائمة ببقية العناصر،
ربما []. *)
# مجموع [ 1 ؛ 2 ؛ 3 ؛ 4 ؛ 5 ]؛
- : int = 15
هناك طريقة أخرى وهي استخدام وظيفة الطي القياسية التي تعمل مع القوائم.
دع مجموع الأعداد الصحيحة =
قائمة . fold_left ( مجمع المرح x -> المجمع + x ) 0 عدد صحيح ؛؛
# مجموع [ 1 ؛ 2 ؛ 3 ؛ 4 ؛ 5 ]؛
- : int = 15
نظرًا لأن الوظيفة المجهولة هي ببساطة تطبيق لمشغل +، فيمكن اختصارها إلى:
دع مجموع الأعداد الصحيحة =
قائمة . fold_left (+) 0 أعداد صحيحة
علاوة على ذلك، من الممكن حذف وسيطة القائمة من خلال الاستفادة من التطبيق الجزئي :
دع المجموع =
قائمة . fold_left (+) 0
فرز سريع
يُعد OCaml مناسبًا للتعبير بشكل موجز عن الخوارزميات المتكررة. ينفذ مثال التعليمات البرمجية التالي خوارزمية مشابهة لخوارزمية quicksort التي تقوم بفرز القائمة بترتيب تصاعدي.
دع rec qsort = function
| [] -> []
| pivot :: rest ->
دع is_less x = x < pivot in
دع left , right = List . تقسيم is_less rest in
qsort left @ [ pivot ] @ qsort right
أو باستخدام التطبيق الجزئي للعامل >=.
دع rec qsort = function
| [] -> []
| pivot :: rest ->
دع is_less = (>=) pivot in
دع left , right = List . تقسيم is_less rest in
qsort left @ [ pivot ] @ qsort right
مشكلة عيد الميلاد
يقوم البرنامج التالي بحساب أصغر عدد من الأشخاص في غرفة حيث يكون احتمال أعياد الميلاد الفريدة تمامًا أقل من 50٪ ( مشكلة عيد الميلاد ، حيث يكون الاحتمال بالنسبة لشخص واحد هو 365/365 (أو 100٪)، بالنسبة لـ 2 يكون 364/365، بالنسبة لـ 3 يكون 364/365 × 363/365، إلخ) (الإجابة = 23).
دع year_size = 365 .
دع rec birthday_paradox prob people =
دع prob = ( year_size -. float people ) /. year_size *. prob in
إذا كانت prob < 0.5 ثم اطبع f . printf " answer = %d \n " ( people + 1 ) وإلا birthday_paradox prob ( people + 1 ) ;;
مفارقة عيد الميلاد 1 . 0 1
أرقام الكنيسة
يحدد الكود التالي ترميز Church للأعداد الطبيعية ، مع الخليفة (succ) والإضافة (add). رقم Church nهو دالة من الدرجة الأعلى تقبل دالة fوقيمة xوتنطبق fعلى الأوقات xبالضبط n. لتحويل رقم Church من قيمة دالة إلى سلسلة، نمرر إليه دالة تضيف السلسلة "S"إلى مدخلاتها والثابت string "0".
دع صفر f x = x
دع succ n f x = f ( n f x )
دع واحدًا = succ صفرًا
دع اثنين = succ ( succ صفر )
دع الجمع n1 n2 f x = n1 f ( n2 f x )
دع to_string n = n ( fun k -> "S" ^ k ) "0"
دع _ = to_string ( إضافة ( succ اثنان ) اثنان )
دالة عاملية ذات دقة تعسفية (المكتبات)
يمكن الوصول إلى مجموعة متنوعة من المكتبات مباشرةً من OCaml. على سبيل المثال، تحتوي OCaml على مكتبة مدمجة للحسابات ذات الدقة التعسفية . نظرًا لأن دالة العامل تنمو بسرعة كبيرة، فإنها تتجاوز بسرعة أرقام الدقة الآلية (عادةً 32 أو 64 بت). وبالتالي، فإن دالة العامل هي مرشح مناسب للحسابات ذات الدقة التعسفية.
في OCaml، توفر وحدة Num (التي حلت محلها الآن وحدة ZArith) عمليات حسابية ذات دقة تعسفية ويمكن تحميلها إلى مستوى أعلى قيد التشغيل باستخدام:
# # استخدم "topfind" ;;
# # تتطلب "num" ;;
# افتح Num ;;
يمكن بعد ذلك كتابة الدالة العاملية باستخدام العوامل الرقمية ذات الدقة التعسفية =/ و */ و -/ :
# دع rec fact n =
if n =/ Int 0 then Int 1 else n * / fact ( n -/ Int 1 );
val fact : Num . num - > Num . num = <fun>
يمكن لهذه الوظيفة حساب عوامل أكبر بكثير، مثل 120!:
# سلسلة من الأرقام ( حقيقة ( عدد صحيح 120 ));
- : سلسلة =
"6689502913449127057588118054090372586752746333138029810295671352301633
55724496298936687416527198498130815763789321409055253440858940812185989
848111438965000596496052125696000000000000000000000000000000"
مثلث (رسومات)
يقوم البرنامج التالي بعرض مثلث دوار في 2D باستخدام OpenGL :
دع () =
تجاهل ( Glut . init Sys . argv )؛
Glut . initDisplayMode ~ double_buffer : true () ؛
تجاهل ( Glut . createWindow ~ title : "OpenGL Demo" )؛
دع الزاوية t = 10. *. t * . t في دع 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 () في وضع GlMat . ` modelview ؛ Glut . displayFunc ~ cb : render ؛ Glut . idleFunc ~ cb :( Some Glut . postRedisplay )؛ Glut . mainLoop ()
تعتبر روابط LablGL مع OpenGL مطلوبة. يمكن بعد ذلك تجميع البرنامج إلى رمز ثنائي باستخدام:
$ ocamlc -I +lablGL lablglut.cma lablgl.cma simple.ml -o بسيط
أو إلى nativecode مع:
$ ocamlopt -I +lablGL lablglut.cmxa lablgl.cmxa simple.ml -o simple
أو ببساطة أكثر، استخدام أمر البناء ocamlfind
$ ocamlfind opt simple.ml -package lablgl.glut -linkpkg -o simple
وركض:
$./بسيط
يمكن تطوير برامج رسومية ثنائية وثلاثية الأبعاد أكثر تطورًا وأداءً في OCaml. وبفضل استخدام OpenGL وOCaml، يمكن أن تكون البرامج الناتجة متعددة المنصات، ويمكن تجميعها دون أي تغييرات على العديد من المنصات الرئيسية.
متتالية فيبوناتشي
يقوم الكود التالي بحساب تسلسل فيبوناتشي لرقم n تم إدخاله. ويستخدم التكرار الذيلي ومطابقة الأنماط.
دع fib n =
دع rec fib_aux m a b =
تطابق m مع
| 0 -> a
| _ -> fib_aux ( m - 1 ) b ( a + b )
في fib_aux n 0 1
وظائف من الدرجة الأعلى
قد تأخذ الدوال الدوال كمدخلات وتعيد الدوال كنتيجة. على سبيل المثال، يؤدي تطبيق مرتين على الدالة f إلى إنشاء دالة تطبق f مرتين على وسيطتها.
دع مرتين ( f : ' a -> ' a ) = fun ( x : ' a ) -> f ( f x )؛
دع inc ( x : int ) : int = x + 1 ؛
دع add2 = twice inc ؛
دع inc_str ( x : string ) : string = x ^ " " ^ x ؛
دع add_str = twice ( inc_str )؛
# add2 98 ;;
- : int = 100
# add_str "اختبار" ;; - : string = "اختبار اختبار اختبار اختبار"
تستخدم الدالة مرتين متغير النوع 'a' للإشارة إلى إمكانية تطبيقها على أي دالة f يتم تعيينها من النوع 'a' إلى نفسها، وليس فقط على الدوال int->int . وبشكل خاص، يمكن تطبيق الدالة مرتين على نفسها.
# دع fourtimes f = ( twice twice ) f ;;
val fourtimes : ( ' a -> ' a ) -> ' a -> ' a = < fun >
# دع add4 = fourtimes inc ;; val add4 : int -> int = < fun > # add4 98 ;; - : int = 102
اللغات المشتقة
ميتاوكامل
MetaOCaml [24] هو امتداد برمجة متعدد المراحل لـ OCaml يتيح التجميع التدريجي لرمز الجهاز الجديد أثناء وقت التشغيل. في بعض الظروف، من الممكن تحقيق تسريعات كبيرة باستخدام البرمجة متعددة المراحل، لأن المعلومات الأكثر تفصيلاً حول البيانات المراد معالجتها متاحة في وقت التشغيل مقارنة بوقت التجميع العادي، وبالتالي يمكن للمترجم التدريجي التخلص من العديد من حالات التحقق من الحالة، وما إلى ذلك.
على سبيل المثال: إذا كان من المعروف في وقت التجميع أن هناك حاجة إلى بعض وظائف الطاقة بشكل متكرر، ولكن قيمة معروفة فقط في وقت التشغيل، يمكن استخدام وظيفة طاقة ذات مرحلتين في MetaOCaml:
x -> x^nn
دع rec power n x =
إذا كان n = 0
، فإن .< 1 >.
وإلا
إذا كان n زوجيًا ، فإن sqr ( القوة ( n / 2 ) x ) وإلا .<.~ x *. .~( القوة ( n - 1 ) x )>.
بمجرد nمعرفة ذلك في وقت التشغيل، يمكن إنشاء دالة طاقة متخصصة وسريعة جدًا:
.< متعة x -> .~( القوة 5 .< x >.)>.
النتيجة هي:
مرح x_1 -> ( x_1 *
دع y_3 =
دع y_2 = ( x_1 * 1 )
في ( y_2 * y_2 )
في ( y_3 * y_3 ))
يتم تجميع الوظيفة الجديدة تلقائيًا.
لغات مشتقة أخرى
- F# هي لغة إطار عمل .NET تعتمد على OCaml.
- يدمج JoCaml الإنشاءات لتطوير البرامج المتزامنة والموزعة.
- Reason عبارة عن صيغة OCaml بديلة وسلسلة أدوات لـ OCaml تم إنشاؤها في Facebook ، والتي يمكن تجميعها إلى كل من الكود الأصلي وJavaScript.
البرمجيات المكتوبة بلغة OCaml
- Ahrefs، منتج برمجي لتحسين محركات البحث
- Alt-Ergo ، مُحلل SMT.
- أستري ، محلل ثابت
- Be Sport، شبكة اجتماعية
- Coccinelle ، أداة مساعدة لتحويل الكود المصدر لبرامج C.
- Coq ، نظام إدارة الأدلة الرسمي .
- Easycrypt، مجموعة أدوات لكتابة الأدلة بمساعدة الكمبيوتر. [25]
- F* ، لغة برمجة عالية المستوى، متعددة النماذج، وظيفية وموجهة نحو الكائنات، تهدف إلى التحقق من البرامج.
- FFTW ، مكتبة لحساب تحويلات فورييه المنفصلة . تم إنشاء العديد من روتينات C بواسطة برنامج OCaml المسمى
genfft. - النسخة الويبية من Facebook Messenger . [26]
- Flow، وهو محلل ثابت تم إنشاؤه في Facebook يستنتج ويتحقق من الأنواع الثابتة لـ JavaScript . [27]
- Ocsigen، إطار عمل لتطوير الويب والهواتف المحمولة وخادم العميل
- Owl Scientific Computing ، وهو نظام مخصص للحوسبة العلمية والهندسية.
- Frama-C ، إطار عمل لتحليل برامج C.
- GeneWeb ، برنامج علم الأنساب مجاني ومفتوح المصدر ومتعدد المنصات.
- مُجمِّع لغة البرمجة Hack ، الذي تم إنشاؤه في Facebook، يعمل على توسيع PHP باستخدام أنواع ثابتة.
- مُجمِّع لغة البرمجة Haxe .
- HOL Light ، مساعد إثبات رسمي.
- Infer، وهو محلل ثابت تم إنشاؤه في Facebook لـ Java وC و C++ و Objective-C ، ويستخدم للكشف عن الأخطاء في تطبيقات iOS و Android . [28]
- Liquidsoap ، لغة برمجة لإنشاء تدفقات الوسائط المتعددة.
- MirageOS ، إطار عمل برمجة أحادي النواة مكتوب بلغة OCaml النقية.
- MLdonkey ، وهو تطبيق مشاركة الملفات من نظير إلى نظير يعتمد على شبكة EDonkey .
- أوبا ، لغة برمجة مجانية ومفتوحة المصدر لتطوير الويب.
- Reason / ReScript ، لغة برمجة عامة الغرض، عالية المستوى، متعددة النماذج، وظيفية وموجهة نحو الكائنات.
- Rust ، لغة برمجة عامة الغرض تركز على الأداء وسلامة النوع والتزامن.
- Tezos ، منصة عقود ذكية قابلة للتعديل ذاتيًا تستخدم XTZ كعملة أصلية.
- Unison ، برنامج مزامنة الملفات لمزامنة الملفات بين دليلين.
- المترجم المرجعي لـ WebAssembly ، وهو بايت كود منخفض المستوى مخصص للتنفيذ داخل متصفحات الويب . [29]
- منصة Xen Cloud (XCP)، وهي عبارة عن حل جاهز للاستخدام للمحاكاة الافتراضية لبرنامج Xen hypervisor .
المستخدمون
تستخدم عشرات الشركات على الأقل OCaml بدرجة ما. [30] ومن الأمثلة البارزة ما يلي:
- Bloomberg LP ، التي أنشأت BuckleScript، وهو برنامج تجميعي خلفي لـ OCaml يستهدف JavaScript. [31]
- Citrix Systems ، التي تستخدم OCaml في XenServer (تمت إعادة تسميتها باسم Citrix Hypervisor خلال عام 2018). [32]
- فيسبوك ، الذي طور Flow، [33] Hack، Infer، Pfff، و ReasonML في OCaml.
- Jane Street Capital ، وهي شركة تجارية خاصة ، اعتمدت لغة OCaml كلغة مفضلة لها في أيامها الأولى [34] وتستمر في استخدامها حتى عام 2023. [35] [36]
- Docker ، الذي يستخدم OCaml في إصدارات سطح المكتب على macOS و Windows . [37] [38]
في سياق التدريس والبحث الأكاديمي، تتمتع OCaml بحضور ملحوظ في برامج تدريس علوم الكمبيوتر، سواء في الجامعات أو الكليات. يمكن العثور على قائمة بالموارد التعليمية وبرامج التدريس هذه على ocaml.org.
مراجع
- ^ "الوحدات النمطية" . تم الاسترجاع في 22 فبراير 2020 .
- ^ لوروي، زافييه (1996). "Objective Caml 1.00". قائمة بريدية caml-list.
- ^ "ملاحظات إصدار OCaml 5.2.0" . تم الاسترجاع في 24 مايو 2024 .
- ^ "التأثيرات - مرجع Rust". مرجع Rust . تم الاسترجاع في 31 ديسمبر 2023 .
- ^ “جيروم فويلون”. www.irif.fr . تم الاسترجاع في 14 يونيو 2024 .
- ^ "ديدييه ريمي". pauillac.inria.fr . تم الاسترجاع في 14 يونيو 2024 .
- ^ "تاريخ OCaml" . تم الاسترجاع في 24 ديسمبر 2016 .
- ^ أخبار لينكس الأسبوعية.
- ^ "AJ Milner - AM Turing Award Laureate". amturing.acm.org . تم الاسترجاع في 6 أكتوبر 2022 .
- ^ ab Clarkson, Michael; et al. "1.2. OCaml: Functional Programming in OCaml". courses.cs.cornell.edu . تم الاسترجاع في 6 أكتوبر 2022 .
- ^ abcdefghi "Prologue - Real World OCaml". dev.realworldocaml.org . تم الاسترجاع في 6 أكتوبر 2022 .
- ^ abcdefg "تاريخ OCaml – OCaml". v2.ocaml.org . تم الاسترجاع في 7 أكتوبر 2022 .
- ^ "إصدار حزمة OCaml 5.0.0 OCaml". OCaml . تم الاسترجاع في 16 ديسمبر 2022 .
- ^ "Projet Cristal". cristal.inria.fr . تم الاسترجاع في 7 أكتوبر 2022 .
- ^ "فريق جاليوم - الصفحة الرئيسية". gallium.inria.fr . تم الاسترجاع في 7 أكتوبر 2022 .
- ^ "الصفحة الرئيسية". cambium.inria.fr . تم الاسترجاع في 7 أكتوبر 2022 .
- ^ "حوكمة وعضوية مُجمِّع OCaml". 2023.
- ^ "حوكمة ومشاريع OCaml". 2023.
- ^ "ocaml/asmcomp at trunk · ocaml/ocaml · GitHub". GitHub . تم الاسترجاع في 2 مايو 2015 .
- ^ المجال هو وحدة التوازي في OCaml، وعادة ما يتوافق المجال مع نواة وحدة المعالجة المركزية
- ^ "OCaml - نظام المستوى الأعلى أو REPL (ocaml)". ocaml.org . تم الاسترجاع في 17 مايو 2021 .
- ^ "OCaml - التجميع الدفعي (Ocamlc)".
- ^ "3.7. الخيارات — برمجة OCaml: صحيحة + فعّالة + جميلة". cs3110.github.io . تم الاسترجاع في 7 أكتوبر 2022 .
- ^ oleg-at-okmij.org. "BER MetaOCaml". okmij.org .
- ^ EasyCrypt/easycrypt, EasyCrypt, 5 يوليو 2024 , تم الاسترجاع 5 يوليو 2024
- ^ "Messenger.com تم تحويله الآن بنسبة 50% إلى Reason · Reason". reasonml.github.io . تم الاسترجاع في 27 فبراير 2018 .
- ^ "Flow: A Static Type Checker for JavaScript". Flow . مؤرشف من الأصل في 8 أبريل 2022 . تم الاسترجاع 10 فبراير 2019 .
- ^ "استنتاج محلل ثابت". استنتاج .
- ^ "WebAssembly/spec: مواصفات WebAssembly ومترجمها المرجعي ومجموعة الاختبارات". اتحاد شبكة الويب العالمية . 5 ديسمبر 2019. تم الاسترجاع في 14 مايو 2021 - عبر GitHub.
- ^ "الشركات التي تستخدم OCaml". OCaml.org . تم الاسترجاع في 14 مايو 2021 .
- ^ "BuckleScript: الإصدار 1.0 قد وصل! | Tech at Bloomberg". Tech at Bloomberg . 8 سبتمبر 2016 . تم الاسترجاع في 21 مايو 2017 .
- ^ سكوت، ديفيد؛ شارب، ريتشارد؛ جازانيير، توماس؛ مادهافابيدى، أنيل (2010). استخدام البرمجة الوظيفية ضمن مجموعة منتجات صناعية: وجهات نظر وتصورات. المؤتمر الدولي حول البرمجة الوظيفية . رابطة آلات الحوسبة . doi :10.1145/1863543.1863557.
- ^ "Flow on GitHub". GitHub . 2023.
- ^ يارون مينسكي (1 نوفمبر 2011). "OCaml for the Masses" . تم الاسترجاع في 2 مايو 2015 .
- ^ يارون مينسكي (2016). "الكلمة الرئيسية - ملاحظات المبرمج الوظيفي". الاستخدامات التجارية للبرمجة الوظيفية في ACM .
- ^ يارون مينسكي (2023). "الإشارات والخيوط" (بودكاست). جين ستريت كابيتال .
- ^ أنيل مادهافابييدي (2016). "تحسين Docker باستخدام Unikernels: تقديم HyperKit وVPNKit وDataKit". Docker, Inc.
- ^ "VPNKit على GitHub". GitHub . 2023.
روابط خارجية
- الموقع الرسمي
- دليل OCaml
- مدير الحزم OCaml
- OCaml في العالم الحقيقي
