العرضar

Types and values

Data types#

يمتلك Faber نظام أنواع ثابتاً، النوع أولاً. كل تصريح يضع النوع قبل الاسم: نص اسم، وليس اسم: نص. يغطي نظام الأنواع البدائيات القياسية، والمجموعات العامة، والأعداد محددة الحجم، والموترات، وأنواع السجلات الموجهة لوحدة معالجة الرسوميات.

الأنواع البدائية#

النوعالدورمثال حرفي
نصسلسلة نصية يونيكود"Salve, munde"
أسكيرمز آلة ثابت'solum:lege'
i32عدد صحيح بإشارة42
f64عدد عشري3.14
منطقيقيمة منطقيةصواب، خطأ
فراغوحدة / بلا قيمة—
نوع_لاشيءمعدوم / غائبنوع_لاشيء
لحظةمدة / لحظة زمنية—
جسونقيمة JSON وقت الترجمة{ "key": "value" }
بايتاتتسلسل بايتات ست عشرية\|00ff\|

الأنواع العددية محددة الحجم#

اكتب العرض في موضع النوع. هذه هي الأنواع العددية — نفس القائمة في Math in the ether:

العائلةالعروض
بإشارةi8 i16 i32 i64
بلا إشارةu8 u16 u32 u64
عشريd64
عدد صحيح غير محدودinf
عشري عائمf16 bf16 f32 f64
بداية {
    ثابت i32 narrow ← 7 ∷ i32
    ثابت u64 wide ← 255 ∷ u64
    ثابت f32 single ← 1.5 ∷ f32
}

علامة العرض المجردة هي النوع.

الأنواع القابلة للإعدام#

تستخدم القيم القابلة للإعدام صيغة الاتحاد T ∪ نوع_لاشيء:

دالة find(نص key) → عدد ∪ نوع_لاشيء {
    أعد خال
}

دالة maybe() → نص ∪ نوع_لاشيء {
    أعد خال
}

لا توجد صيغة T? أو Option<T> في Faber. الاتحاد صريح.

أسماء الأنواع المستعارة#

نمط UserId = عدد

الأنواع العامة#

تقبل الدوال، وأسماء الأنواع المستعارة، وصنف، وعقد معاملات نوع بصيغة <T>:

دالة identitas<T>(T قيمة) → T {
    أعد قيمة
}

دالة primum<T>(قائمة<T> res) → T ∪ نوع_لاشيء {
    أعد res.الأول()
}

تُدعم معاملات النوع الصريحة في موقع الاستدعاء:

دالة identitas<T>(T قيمة) → T {
    أعد قيمة
}

بداية {
    ثابت عدد value ← identitas<عدد>(7)
}

المجموعات#

النوعالدوراختزال
قائمة<T>مجموعة ديناميكية مرتبةlf32، lu32
جدول<K, V>خريطة مفتاح-قيمة—
موتر<T, Figura>حاوية كثيفة ثابتة الشكلtf32[4]، ti64[2,3]
متفرقة<T, Figura>حاوية متفرقة ثابتة الشكلsf32[4]، si64[2,3]
فترةنوع مجال—
مجموعة<T>مجموعة غير مرتبة—
cursor<T>دفق كسول—
بداية {
    ثابت قائمة<عدد> nums ← [1, 2, 3]
    ثابت جدول<نص, عدد> scores ← { "alice": 10, "bob": 20 }
}

أنواع الموترات#

موتر<T, Figura> هو الحاوية الكثيفة ثابتة الشكل:

الصيغةالمعنى
موتر<T, Figura>التهجئة القانونية
موتر<T, []>الرتبة 0 (حاوية قياسية)
موتر<T, _>فجوة استدلال الشكل
موتر<T, [N]>الرتبة 1 (متجه)
موتر<T, [N, M]>الرتبة 2 (مصفوفة)
بداية {
    ثابت موتر<f32, []> scalar ← فارغ
    ثابت موتر<عدد, [4]> lanes ← [1, 2, 3, 4] ↦ موتر<عدد, [4]>
    ثابت عدد ∪ نوع_لاشيء head ← lanes[0]
}

أنواع نواة وحدة معالجة الرسوميات#

يتعرف مسار الأنظمة على هذه الأنواع لأعمال وحدة معالجة الرسوميات والسجلات. ترفضها أهداف الحزمة التي تفتقر إلى دعم العتاد:

دالة half(f16 x) → f16 { أعد x }

دالة add(مصفوفة<f32, [2, 2]> a, مصفوفة<f32, [2, 2]> b) → مصفوفة<f32, [2, 2]> {
    أعد a.addita(b)
}

دالة swap(ذري<i32> cell, i32 value) → i32 {
    أعد cell.exchange(value)
}

علامات الاستعارة على الأنواع#

يمكن أن تظهر علامات الاستعارة (عن، في، ملك) على الأنواع في مواضع المعاملات للإشارة إلى كيفية تمرير القيمة:

# shared borrow — caller retains ownership
functio imprime(de textus label) → vacuum { }

# mutable borrow — caller lends mutable access
functio duplica(in numerus value) → vacuum { }

# move — caller gives up ownership
functio consume(own textus buffer) → textus {
    redde buffer
}

سياسة المقارنة#

المعاملالعائلةالسلوك
≡، ≠، ≢مساواة تامةتتطلب أنواعاً متطابقة؛ استثناء نوع_لاشيء
≅، ≇مساواة تامة بعد الترقيةتُدمج العروض العددية ثم مقارنة تامة
≈، ≉مساواة تقريبيةمطابقة ضمن سماحية — افتراضيات isclose (rel_tol 1e-09)؛ معاملات عددية فقط
<، ≤، >، ≥ترتيبعددي، لحظي، نص قياسي
ضمناحتواء مجالعدد ضمن مجال
بينعضوية مجموعةعنصر في مجموعة

Variables and binding#

Faber تمتلك ثلاث كلمات مفتاحية للمتغيرات ورمز تخصيص مخصص. الفرق الأساسي هو بين ثابت (كتابة مرة واحدة) و متغير (قابل لإعادة التخصيص بحرية)، وبين ← (تدفق وقت التشغيل) و = (شكل الحقل الهيكلي).

ثابت — ربط غير قابل للتغيير#

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

بداية {
    ثابت عدد count ← 0
    ثابت نص name ← "Marcus"
    ثابت _ inferred ← [1, 2, 3]
}

التهيئة المؤجلة:

بداية {
    ثابت عدد factor
    إذا صواب {
        factor ← 10
    }
    وإلا {
        factor ← 100
    }
    اعرض factor
}

متغير — ربط قابل للتغيير#

روابط متغير قابلة لإعادة التخصيص بحرية:

بداية {
    متغير عدد count ← 0
    count ← count + 1
    count ← count * 2
}

ليكن — اختصار للربط غير القابل للتغيير مع استنتاج النوع#

ليكن هو اختصار لـ ثابت _ — رابط غير قابل للتغيير مع نوع مستنتج:

بداية {
    ثابت _ salve ← "Salve"
    ثابت _ اسم ← "Marcus"
    ثابت _ x ← 42

    # Deferred form
    ثابت _ label
    label ← "deferred"
}

الربط وقت التشغيل مقابل التعريف الهيكلي#

Faber يفصل ما تدمجه معظم اللغات في =:

الرمزالدورالاستخدام
←تدفق وقت التشغيلالربط الأولي، إعادة التخصيص، التغيير
=الشكل الهيكليأسماء الحقول داخل القيم الحرفية والبيانات الوصفية
صنف Point {
    ثابت عدد x
    ثابت عدد y
}

بداية {
    # Runtime: ← attaches a value to a name at execution time
    متغير عدد count ← 0
    متغير نص label ← "ready"
    count ← count + 1

    # Structural: = defines field values inside a type literal
    ثابت _ p ← Point { x = 10, y = 20 }
}

استخراج الحقول باستخدام من#

من يستخرج الحقول من قيمة إلى روابط محلية:

صنف Persona {
    ثابت نص اسم
    ثابت عدد aetas
}

بداية {
    ثابت _ p ← Persona { اسم = "Marcus", aetas = 30 }
    ثابت نص اسم ← p.nomen
    ثابت عدد aetas ← p.aetas
    # prints "Marcus"
    اعرض اسم
}

الزيادة والنقصان اللاحقة#

⊕ و ⊖ هما عبارتا زيادة ونقصان لاحقة للأماكن عدد القابلة للتغيير. هما عبارات فقط — لا قيمة تعبيرية، ولا أشكال بادئة:

بداية {
    متغير عدد i ← 0
    # i becomes 1
    i ← i + 1
    # i becomes 0
    i ← i - 1
}

Collections#

لدى Faber عدة أنواع مجموعات مملوكة للمترجم. طرائقها القانونية موجودة في المترجم، وليس في المكتبة القياسية.

Lista — مجموعة ديناميكية مرتبة#

بداية {
    ثابت قائمة<عدد> empty ← فارغ
    ثابت _ numbers ← [1, 2, 3, 4, 5]
    ثابت _ names ← ["Marcus", "Julia", "Gaius"]
    ثابت _ nested ← [[1, 2], [3, 4]]
}

النشر باستخدام انشر:

بداية {
    ثابت قائمة<عدد> a ← [1, 2, 3]
    ثابت قائمة<عدد> b ← [4, 5, 6]
    ثابت _ combined ← [انشر a, انشر b]
    ثابت _ headed ← [0, انشر a, 99]
}

الطرائق الرئيسية: longitudo، accipe، appende، المجموع، primus، novissimus.

Tabula — خريطة مفتاح-قيمة#

بداية {
    ثابت جدول<نص, عدد> scores ← { "alice": 10, "bob": 20 }
}

Tensor — مصفوفة كثيفة ثابتة الشكل#

بداية {
    ثابت موتر<f32, []> scalar ← فارغ
    ثابت موتر<عدد, [4]> lanes ← [1, 2, 3, 4] ↦ موتر<عدد, [4]>
    ثابت عدد ∪ نوع_لاشيء head ← lanes[0]
}

تبسيط Tensor (للأكواد ذات الحسابات العددية الكثيفة):

بداية {
    ثابت tf32[] seed ← فارغ
    ثابت tf32[4] lanes ← seed.ابن_من_مسطح([1.0, 2.0, 3.0, 4.0], [4])
}

الطرائق الرئيسية: forma، accipe، ponde، crea، structa، strue، بالإضافة إلى الحساب العنصري، وضرب المصفوفات (multiplicatio)، والاختزالات (المجموع، productum).

Sparsa — مصفوفة متفرقة ثابتة الشكل#

بداية {
    ثابت متفرقة<f32, [2, 3]> sparse ← فارغ
    sparse.ponde([0, 1], 4.0)
    sparse.ponde([1, 2], 9.0)

    # accipe returns the stored value, here 4.0
    اعرض sparse.accipe([0, 1])
    # count of stored entries
    اعرض sparse.nonnihil()
}

التحويل بين الكثيف والمتفرق:

بداية {
    ثابت tf32[2, 2] dense ← [[1.0, 0.0], [0.0, 2.0]] ↦ موتر<f32, [2, 2]>
    ثابت sf32[2, 2] sparse ← dense ↦ متفرقة<f32, [2, 2]>
    ثابت tf32[2, 2] roundtrip ← sparse ↦ موتر<f32, [2, 2]>
}

Cursors — تيارات كسولة#

cursor<T> هو نوع تيار كسول. يُنشأ من مكررات المجموعات، أو مناظير استقبال، أو دوال مولدة. يُستهلك عبر كرر من:

بداية {
    ثابت _ items ← [1, 2, 3]
    كرر من items ثابت item {
        اعرض item
    }
}

Intervallum — نطاقات#

# exclusive range: 0, 1, 2, 3, 4
كرر نطاق 0‥5 ثابت i {
    اعرض i
}
# inclusive range: 0, 1, 2, 3, 4, 5
كرر نطاق 0…5 ثابت i {
    اعرض i
}

‥ هو حد نطاق حصري؛ … هو حد شامل.

String and template literals#

تستخدم Faber دلالات المحددات — كل صيغة اقتباس تعني شكل مصدر مختلف. وهي ليست مرادفات قابلة للتبادل.

الصيغ الحرفية#

الصيغةالنوعالدور
'…'أسكيرموز آلية ثابتة؛ لا §؛ لا (…)
"…"نصسلاسل يونيكود نصية قصيرة؛ (…) يُنتِج
«…»نصيونيكود كتلي/متعدد الأسطر؛ (…) يُنتِج
… formaقوالب مأسورة؛ (…) يأسر
{ … }جسونوثيقة JSON في زمن الترجمة
`…`بايتاتبايتات سداسية عشرية في زمن الترجمة
[ … ]قائمة<T>قيمة حرفية من نوع قائمة Faber

تطبيق قالب السلسلة النصية#

تُنسّق Faber النص عبر تطبيق قالب السلسلة النصية: قيمة حرفية "…" أو «…» تحتوي ثقوب §، ثم وسيطات بين قوسين:

دالة greet(نص اسم) → نص {
    أعد "Salve, §!"(اسم)
}

بداية {
    ثابت عدد pagina ← 3
    ثابت عدد totum ← 10
    ثابت نص code ← "200"
    ثابت نص label ← "OK"
    ثابت _ msg ← "Page § of §"(pagina, totum)
    ثابت _ block ← "status: § (§)"(code, label)
}

القواعد الأساسية:

  • § (U+00A7) هو ثقب القالب
  • الثقوب الموضعية: §0، §1، … للترتيب الصريح
  • اللاحقة ! تختار تنسيق العرض: "Salve, §!"(اسم)
  • ملحقة (وسائط) هي تطبيق قالب، وليس استدعاء دالة

السلاسل النصية الكتلية#

تستخدم الكتل متعددة الأسطر علامات التنصيص المزدوجة «…»:

بداية {
    ثابت _ sql ← «
        select id, email
        from accounts
    »
}

القوالب المأسورة (forma)#

تأسر قوالب الفاصلة العليا المائلة النص والوسائط دون إنتاج. آمنة للحمولات المقيّدة SQL/URL:

بداية {
    ثابت عدد user_id ← 42
    ثابت _ query ← `select * from users where id = §`(user_id)
}

JSON المُضمّن#

الصيغة المجردة { … } هي JSON مُضمّن: وثيقة جسون في زمن الترجمة، وليست كائن Faber مجهول. المفاتيح هي سلاسل نصية بين علامتي تنصيص مفصولة بـ ::

بداية {
    ثابت _ empty ← {}
    ثابت _ user ← { "name": "Marcus", "age": 30, "active": true }
    ثابت _ nested ← { "meta": { "version": 1 }, "tags": ["alpha", "beta"] }
}

لبناء صنف مُنمّط، استخدم اسم النوع وشكل الحقل =:

صنف Point {
    ثابت عدد x
    ثابت عدد y
}

بداية {
    ثابت _ p ← Point { x = 10, y = 20 }
}

Nullability and optionality#

تُميِّز Faber بين غياب القيمة وتوفيرها الاختياري في موقع الإعلان.

القيم القابلة للعدم — T ∪ نوع_لاشيء#

استخدِم T ∪ نوع_لاشيء عندما يمكن أن تكون القيمة غائبة:

دالة find(نص key) → عدد ∪ نوع_لاشيء {
    أعد خال
}

دالة divide(عدد a, عدد b) → عدد ∪ نوع_لاشيء {
    إذا b ≡ 0 إذن أعد خال
    أعد a / b
}

فتحات الإعلان الاختيارية — اختياري#

استخدِم اختياري بعد الاسم عندما يمكن للمُستدعي أو المنشئ حذف مُعامل أو حقل:

دالة connect(نص host, عدد port اختياري) → فراغ {
}

صنف User {
    ثابت نص email اختياري
}

يمكن دمج علامات الاستعارة مع المُعاملات الاختيارية:

دالة process(عن عدد depth اختياري) → فراغ {
}

تأكيد عدم العدم — !#

استخدِم !. و ![ و !( لتأكيد أن القيمة القابلة للعدم ليست نوع_لاشيء:

صنف Box {
    ثابت عدد ∪ نوع_لاشيء val
}

بداية {
    ثابت Box ∪ نوع_لاشيء maybe_name ← Box { val = 7 }
    ثابت _ name ← maybe_name!.val
}

يؤدي تأكيد عدم العدم على نوع_لاشيء إلى إجهاض التنفيذ وقت التشغيل.

الدمج العدمي — vel#

بداية {
    ثابت نص ∪ نوع_لاشيء provided ← خال
    ثابت _ name ← provided عوض "default"
}

مجهول#

مجهول هو النوع غير المعروف عالي المستوى لمخارج الطوارئ والمعرفة غير المكتملة. وهو ليس آليةً للتعامل مع العدم.

Conversion and construction#

عاملَا تحويل مهمّان: أحدهما لوقت التشغيل والآخر لوقت الترجمة:

# runtime حوّل
بداية {
    ثابت _ parsed ← "42" ↦ عدد ⊥ 0
    # static ascription
    ثابت عدد value ← 7
    ثابت _ text ← value ∷ نص
}

التحويل وقت التشغيل — ↦#

استعمل ↦ للتحويل وقت التشغيل، خصوصًا التحليل أو الإكراه الذي قد يفشل. وفّر استردادًا مضمنًا باستعمال ⊥:

بداية {
    ثابت نص input ← "9"
    ثابت _ n ← "42" ↦ عدد ⊥ 0
    ثابت _ safe ← input ↦ عدد ⊥ 0
}

تجسيد موجّه بالنوع:

بداية {
    ثابت نص path ← "/etc/hosts"
    ثابت _ lanes ← [1.0, 2.0, 3.0, 4.0] ↦ متجه<f32, 4>
    ثابت _ body ← اتصل 'solum:lege' (path) ↦ نص
}

الإسناد الثابت — ∷#

استعمل ∷ للإسناد الثابت الصريح للنوع. هو لاحق وموجّه بالنوع الهدف:

بداية {
    ثابت عدد value ← 7
    ثابت _ x ← 7 ∷ i32
    ثابت _ text ← value ∷ نص
}

الدمج العدمي — vel#

استعمل عوض للدمج العدمي حينما تكون القيمة نوع_لاشيء:

بداية {
    ثابت نص ∪ نوع_لاشيء provided_name ← خال
    ثابت _ name ← provided_name عوض "default"
}