Orb لغة للبرمجيات التي يجب أن تتبع قواعد. تعلن الحالات والأحداث، فيبني المترجم التطبيق أو يخبرك لماذا لا يستطيع.
يصف برنامج Orb سلوك جزء من البرمجيات: البيانات التي يحملها، والحالات التي يمكن أن يكون فيها، والأحداث التي تنقله بينها، وما يعرضه في كل خطوة. تكتبه بلغة .lolo، وهي صياغة صغيرة على طريقة Lisp. يتحقق المترجم منه، ثم يشغّله مباشرة أو يولّد منه تطبيقًا كاملًا.
إليك برنامجًا كاملًا. إنه يعمل الآن في هذه الصفحة:
Counting
on Counter · states: 1 · transitions: 4البرنامج أعلاه كآلات حالات، واحدة لكل سمة: كل مربع حالة، وكل سهم حدث ينقلها، والأيقونات على السهم هي التأثيرات التي يشغّلها ذلك الحدث. الرمز ◇ على السهم شرط حارس؛ مرّر المؤشر فوقه لتقرأ الشرط. كيف تقرأ AVL
1app std-orb-docex-counter "1.0.0"
2"std-orb-docex-counter — the smallest complete orbital: one entity, one trait with one state, three buttons and a closed circuit."
3orbital CounterOrbital {
4 entity Counter [runtime] {
5 id : string!
6 count : number = 0
7 }
8
9 trait Counting -> Counter [interaction, instance] {
10 initial: ready
11
12 state ready {
13 INIT -> ready
14 (render-ui main { type: stack, direction: horizontal, gap: md, align: center, children: [
15 { type: button, label: "−", action: DECREMENT, variant: secondary, aria-label: "Decrease" },
16 { type: typography, content: @entity.count, variant: h2 },
17 { type: button, label: "+", action: INCREMENT, variant: primary, aria-label: "Increase" },
18 { type: button, label: "Reset", action: RESET, variant: ghost }
19 ] })
20 INCREMENT -> ready
21 (emit MOVED { event: "INCREMENT" })
22 (set @entity.count (+ @entity.count 1))
23 DECREMENT -> ready
24 (emit MOVED { event: "DECREMENT" })
25 (set @entity.count (- @entity.count 1))
26 RESET -> ready
27 (emit MOVED { event: "RESET" })
28 (set @entity.count 0)
29 }
30
31 emits {
32 MOVED -> external {
33 event : string!
34 }
35 @description "Each move names the event it took, so the diagram beside the demo can follow it."
36 }
37 }
38
39 page "/counter" -> Counting
40}ما الذي يحدث عندما يقع الحدث INCREMENT:
(set @entity.count (+ @entity.count 1))يتكوّن كل برنامج Orb من مداريّات. المداريّ جزء مستقل من السلوك:
Counter بحقل count)؛Counting)؛/counter).Orbital = Entity + Traits + Pages
Application = orbitals that talk to each other through eventsلا يمدّ مداريّ يده إلى داخل مداريّ آخر. سمة تبثّ حدثًا، وأخرى تستمع إليه، ويتحقق المترجم من أن لكل حدث مبثوث وجهةً يصل إليها.
يتبع كل تفاعل الحلقة نفسها:
Event → Guard → Transition → Effects → UI → Eventالضغط على + يرسل INCREMENT. السمة في الحالة ready، ولهذه الحالة انتقال لـ INCREMENT، فيُنفَّذ: تأثيره (set @entity.count (+ @entity.count 1)) يحدّث الكيان، والشاشة المرتبطة بـ @entity.count تعرض القيمة الجديدة. تقدّم الشاشة الجديدة الأزرار نفسها مرة أخرى، فتنغلق الحلقة.
يفرض المترجم هذه الحلقة. الزر الذي لا تتعامل أي حالة مع حدثه، والحالة التي لا يمكن مغادرتها، والحدث المبثوث إلى لا أحد، والصفحة التي لا تعرض شيئًا، كلها أخطاء في orb validate قبل أن يعمل أي شيء.
معظم برمجيات الأعمال قواعد: لا يُشحن طلب قبل دفعه، والاسترداد فوق مبلغ معيّن يحتاج إلى مدير، والتذكرة يجب أن يُرد عليها خلال يوم. في الشيفرة المعتادة تتوزع هذه القواعد بين الواجهة والخادم وقاعدة البيانات والاختبارات، ثم تتباعد.
في Orb القاعدة هي شكل البرنامج. إن لم يكن هناك انتقال SHIP من الحالة pending فلا يمكن شحن طلب غير مدفوع، وهذا شيء مُثبَت لا مأمول. الملف نفسه هو المواصفة والتنفيذ ومدخل التحقق:
orb validate يثبت أن البرنامج سليم البنية (صفر أخطاء وصفر تحذيرات هو المعيار)؛orb verify يمر على كل انتقال ويتحقق من أنه يفعل ما يعلنه؛orb compile يولّد تطبيق TypeScript ومنصات أخرى من المصدر نفسه.نادرًا ما تكتب كل آلة حالات بنفسك. تأتي المكتبة القياسية بمئات السلوكيات (قوائم ونماذج ومعالجات خطوات ولوحات معلومات وألعاب وأدوات تعلّم) تستوردها بـ uses وتربطها ببياناتك. تحتفظ بالأجزاء الخاصة بمجالك، والمكتبة تملك البقية. يشرح التركيب الطريقة.