Design notes
Commandments#
नौ नियम जो Faber को Faber जैसा बनाते हैं।
ये वे डिज़ाइन नियम हैं जो Faber के चरित्र को परिभाषित करते हैं। सिंटैक्स विकसित हो सकता है और नई सुविधाएँ जोड़ी जा सकती हैं, लेकिन बदलावों को इन सिद्धांतों को बनाए रखना चाहिए। जो प्रोग्राम इनका उल्लंघन करता है, वह वैध Faber हो सकता है, लेकिन वह Faber जैसा महसूस नहीं होता।
ये आदेश हर स्तर पर लागू होते हैं — स्वयं ग्रामर से लेकर मानक लाइब्रेरी API के नाम रखने तक। यही कारण है कि कोई पाठक Faber स्रोत को एक नज़र में पहचान सकता है, चाहे कीवर्ड किस मानव भाषा में प्रस्तुत किए गए हों या कोड किस लक्ष्य बैकएंड के लिए संकलित हो।
I. नामों से पहले प्रकार#
घोषणाएँ आकार से बाइंडिंग की ओर पढ़ी जाती हैं। प्रकार पहले आता है, क्योंकि पाठक को नाम से यह जानने से पहले कि यह कौन-सी चीज़ है, यह जानना ज़रूरी है कि यह किस प्रकार की चीज़ है। यह उन भाषाओं के अनुरूप है जिनका व्याकरणिक क्रम श्रेणी से उदाहरण की ओर पढ़ा जाता है — चीनी, हिंदी और अरबी — और ऐसी घोषणाएँ बनाता है जिन्हें एकरूपता से स्कैन किया जा सकता है।
# Type before name in every declaration
पाठ नाम
संख्या aetas
फलन salve(पाठ name) → पाठII. जादुई के बजाय यांत्रिक#
एक ही निर्माण का अर्थ हर जगह एक जैसा होना चाहिए। यदि किसी पाठक को यह जानने के लिए दूर के संदर्भ की आवश्यकता पड़े कि कोई प्रतीक क्या करता है, तो सिंटैक्स संदिग्ध है। Faber स्पष्ट, स्थानीय तर्क को प्राथमिकता देता है — घोषणा-स्थल पर इतनी जानकारी होनी चाहिए कि उपयोग-स्थल पर होने वाली क्रिया को समझा जा सके।
# The meaning of a call is determined by the function's signature,
# not by invisible trait resolution or implicit conversions.
फलन duplica(संख्या n) → संख्या {
लौटाओ n * 2
}III. ग्लिफ़ संरचना वहन करते हैं#
संरचनात्मक और ऑपरेटर संबंधी अर्थ शब्दों के बजाय ग्लिफ़ से व्यक्त होते हैं: बाइंडिंग के लिए ←, रिटर्न प्रकार के लिए →, त्रुटि-निकास के लिए ⇥, संक्षिप्त कथन-बॉडी के लिए अतः, समानता के लिए ≡, और यूनियन प्रकारों के लिए ∪। ग्लिफ़ सार्वभौमिक होते हैं — वे कभी स्थानीयकृत नहीं होते और अलग-अलग रेंडरिंग में अपना अर्थ नहीं बदलते। थाई पाठक और फ़्रेंच पाठक एक ही ग्लिफ़ देखते हैं, भले ही उनके आसपास के कीवर्ड अलग हों।
IV. लैटिन व्यवहार वहन करता है#
शब्द घोषणाओं, कथनों, जीवनचक्र और व्यवहारगत आशय के लिए होते हैं: फलन, वर्ग, स्थिर, चर, लौटाओ, पकड़ो। इन्हें रीडर-लोकेल पैक के माध्यम से बाइंड किया जा सकता है — ये शब्दावली हैं, ग्रामर नहीं। लैटिन का चुनाव लैटिन की श्रेष्ठता के बारे में नहीं है; इसका उद्देश्य एक सुसंगत शास्त्रीय स्रोत चुनना है, ताकि सभी कीवर्ड एक ही रजिस्टर में रहें और कोई भी कीवर्ड केवल इसलिए विशेषाधिकार प्राप्त न करे कि कार्यान्वयन उसी भाषा में लिखा गया है।
V. क्रिया-रूप समय और प्रवाह वहन करता है#
जब वही मूल तर्क समकालिक, असमकालिक या जनरेटर के रूप में चल सकता हो, तो क्रिया का रूपांतरित रूप उस निष्पादन मोड को वहन करना चाहिए। ओनरशिप युग्म — म्यूटेट बनाम कॉपी-आउट — एक ही मूल धातु के संबंधित रूपों का उपयोग करते हैं। यही morphologia सिद्धांत है। मानक लाइब्रेरी (Norma) सभी मेथड नामों में इस परंपरा का पालन करती है: पढ़ो (समकालिक रीड) बनाम leget (असमकालिक रीड), adde (यथास्थान म्यूटेट) बनाम addita (नई कॉपी लौटाना)। कंपाइलर रूपांतरों को लागू या व्युत्पन्न नहीं करता — यह नामकरण नीति है, भाषा-सुविधा नहीं।
VI. एक संकेत, एक काम#
किसी ग्लिफ़ या कीवर्ड के सटीक उपनाम हो सकते हैं, लेकिन उसे असंबंधित अर्थ नहीं रखने चाहिए। उपनामों को एक ही कैनोनिकल अवधारणा की ओर लौटना चाहिए। यही सिद्धांत Faber के ← (रनटाइम बाइंडिंग) और = (संरचनात्मक फ़ील्ड आकार) के बीच विभाजन को प्रेरित करता है — अधिकांश भाषाएँ दोनों को = में समेट देती हैं, लेकिन ऐसा ओवरलोडिंग यह छिपा देती है कि कोई पंक्ति डेटा-फ़्लो ऑपरेशन है या प्रकार-स्तरीय परिभाषा।
# ← is always runtime flow
स्थिर संख्या count ← 0
count ← count + 1
# = is always structural shape inside Type { }
स्थिर _ p ← Point {
x = 10,
y = 20
}VII. रनटाइम प्रवाह स्पष्ट होता है#
रनटाइम बाइंडिंग, पुनःअसाइनमेंट और म्यूटेशन के लिए ← का उपयोग होता है; संरचनात्मक परिभाषा के लिए = का। स्रोत को स्कैन करते समय पाठक हर डेटा-फ़्लो ऑपरेशन को तुरंत देख सकता है: हर ← एक रनटाइम घटना है। इस बारे में कोई सिंटैक्टिक अस्पष्टता नहीं रहती कि किसी विशेष = का अर्थ “इस वेरिएबल में स्टोर करो” है या “इस फ़ील्ड को परिभाषित करो।”
VIII. अनुपस्थिति टाइप की जाती है#
नल योग्य वैल्यू प्रकारों को यूनियन के रूप में लिखा जाता है: T ∪ शून्य_मान। वैकल्पिक घोषणा स्लॉट नाम के बाद लगाए जाने वाले चिह्न स्वेच्छा का उपयोग करते हैं। ये अलग-अलग अवधारणाएँ हैं — ऐसी वैल्यू जो अनुपस्थित हो सकती है बनाम ऐसा स्लॉट जिसे कॉलर छोड़ सकता है — और Faber दोनों को T? या Option<T> में समेटने के बजाय सिंटैक्टिक रूप से अलग रखता है।
# Absence in a value: T ∪ शून्य_मान
फलन find(पाठ key) → संख्या ∪ शून्य_मान
# Omission at declaration: स्वेच्छा
फलन connect(पाठ host, संख्या port स्वेच्छा) → रिक्तIX. कंपाइलर अनुपलब्ध जानकारी छिपाने के लिए अनुमान नहीं लगाता#
अनुपलब्ध प्रकार की जानकारी ऐसी विश्लेषण समस्या है जिसे ऊपर की परत पर ठीक किया जाना चाहिए, न कि कोडजनरेशन के किसी विवरण से ढका जाना चाहिए। जब जानकारी वास्तव में अनुपस्थित हो, तो कंपाइलर प्रोग्रामर द्वारा न दी गई किसी प्रकार की जानकारी का चुपचाप अनुमान कभी नहीं लगाता — वह इस कमी की सूचना देता है और रुक जाता है। यही नियम Faber को ईमानदार बनाए रखता है: यदि कोई पाठक स्थानीय स्रोत से यह निर्धारित नहीं कर सकता कि किसी प्रतीक का अर्थ क्या है, तो कंपाइलर को ऐसा दिखावा नहीं करना चाहिए कि वह यह कर सकता है।
उद्देश्य#
इन आदेशों का उद्देश्य उस प्रश्न का उत्तर देना है जो हर भाषा-डिज़ाइन चर्चा में उठता है: “क्या यह बदलाव अब भी Faber है?” ये किसी सुविधा-सूची के विरुद्ध नहीं, बल्कि एक चरित्र के विरुद्ध की जाने वाली अपरिवर्तनीयता जाँच हैं। कोई बदलाव किसी आदेश का उल्लंघन करते हुए भी अच्छा विचार हो सकता है, लेकिन उसे नियमित जोड़ के बजाय Faber के डिज़ाइन-चरित्र से विचलन के रूप में पहचाना जाना चाहिए।
व्यवहार में, ये आदेश प्रायः नए सिंटैक्स प्रस्तावों के लिए समीक्षा मानदंड के रूप में काम आते हैं। जो प्रस्ताव “नामों से पहले प्रकार” को कमजोर करके नाम-पहले विकल्प जोड़ता है, या किसी ग्लिफ़ पर ओवरलोडिंग करके “एक संकेत, एक काम” को धुंधला करता है, उसे यह उचित ठहराना होगा कि उस सुविधा के लिए Faber को अपने चरित्र से क्यों झुकना चाहिए।
Design documents#
Radix रिपॉज़िटरी में Faber भाषा और कंपाइलर के रूप में कैसे काम करता है, इसके आधिकारिक डिज़ाइन दस्तावेज़ मौजूद हैं। ये radix/docs/design/ के अंतर्गत हैं।
इंडेक्स#
| क्षेत्र | फ़ाइलें |
|---|---|
| टार्गेट और लोअरिंग | target-capability-matrix.md, lowering-routes.md, semantic-ownership.md |
| प्रकार और शुगर | numeric-type-sugar.md, comparison-operators.md, annotation-sugar.md |
| कलेक्शन इंट्रिंसिक्स | lista-intrinsics.md, tabula-intrinsics.md, tensor-intrinsics.md, numerus-intrinsics.md, fractus-intrinsics.md, textus-intrinsics.md, intervallum-intrinsics.md, instans-intrinsics.md, copia-intrinsics.md |
| कन्वर्ज़न | conversio-valor.md, failable-conversio.md |
| फ़्रेम और इफ़ेक्ट | frame-stream-types.md, host-provider-gateway.md |
| रीडर और फ़ॉर्मैट | reader-locale.md, faber-canonical-surface.md |
| सिस्टम / AIR | air-dialect.md, aiml-foundation.md, systems-shaped-values.md |
| टूलिंग सतह | faber-scripting.md |
| नामकरण संबंधी ऋण | mixed-case-naming-debt.md |
स्टैंडर्ड लाइब्रेरी डिज़ाइन दस्तावेज़#
radix/docs/stdlib/ डायरेक्टरी में ये दस्तावेज़ हैं:
| दस्तावेज़ | भूमिका |
|---|---|
morphologia.md | सभी स्टैंडर्ड लाइब्रेरी मेथड नामों के लिए रूप-परिवर्तन नीति |
tensor-methods.md | Tensor रिसीवर मेथड संदर्भ |
chorda-methods.md | Chorda (टेक्स्ट) मेथड संदर्भ |
mathesis-methods.md | गणितीय मेथड संदर्भ |
tempus-methods.md | समय संबंधी मेथड संदर्भ |
stdlib-mechanical-verbs.md | pange/solve/tempta त्रयी की नीति |
History#
उत्पत्ति#
Radix कंपाइलर का पहला कमिट 20 दिसंबर 2025 को Bun + TypeScript प्रोजेक्ट के रूप में किया गया था, जिसमें केवल एक docs/decisions.md फ़ाइल थी। दूसरे कमिट में पाँच Architecture Decision Records को औपचारिक रूप दिया गया, जो आज भी भाषा की दिशा तय करते हैं।
ADR-003, जिसका शीर्षक था "Case endings carry semantic meaning", ने शुरुआत में ही स्थापित कर दिया था कि लैटिन रूप-विज्ञान केवल कीवर्ड की बाहरी परत नहीं होगा — कंपाइलर विभक्ति और क्रिया-रूपों को समझकर प्रोग्राम के आशय का अनुमान लगाएगा। मूल case mappings इस प्रकार थे:
Nominative (subject) → return value, caller
Accusative (direct object) → primary argument
Dative (indirect obj.) → recipient, callback, destination
Genitive (possession) → property access, "of" relationships
Ablative (instrument) → dependencies, context, "using X"उसी दस्तावेज़ में यह भी लिखा था: "Verb conjugation is a natural follow-on question (future tense → async?)." यही बीज आगे चलकर आधुनिक morphologia नामकरण परंपरा में विकसित हुआ, जिसमें standard library sync बनाम async और mutate बनाम copy-out का संकेत देने के लिए लैटिन क्रियाओं के conjugated रूपों का उपयोग करती है — और इसके लिए कंपाइलर को स्वयं लैटिन व्याकरण समझने की आवश्यकता नहीं होती।
प्रोजेक्ट की शुरुआत TypeScript में हुई, बाद में इसे Rust में फिर से लिखा गया, और edition 2026 के साथ 1.x श्रृंखला के लिए व्याकरण को स्थिर कर दिया गया। मूल पाँच ADRs (फ़ाइल एक्सटेंशन .fab, error hints, case endings, recursive descent parser, custom AST) आज भी git इतिहास में दिखाई देते हैं।
रिलीज़#
पहले वर्तमान Faber रिलीज़ के CLI archive, फिर faberlang/releases में प्रकाशित हर tag और binary:
- [रिलीज़](/releases/) — डाउनलोड लिंक और ऐतिहासिक सूची
- [इंस्टॉल और डाउनलोड](/start/) — PATH सेटअप और पहला
faber check