การเรนเดอร์th-TH

Design notes

Commandments#

กฎเก้าข้อที่ทำให้ Faber ให้ความรู้สึกเป็น Faber

กฎเหล่านี้คือหลักการออกแบบที่กำหนดลักษณะเฉพาะของ Faber ไวยากรณ์อาจพัฒนาได้ และสามารถเพิ่มฟีเจอร์ใหม่ได้ แต่การเปลี่ยนแปลงควรรักษาหลักการเหล่านี้ไว้ โปรแกรมที่ละเมิดหลักการเหล่านี้อาจยังเป็น Faber ที่ถูกต้อง แต่จะไม่ให้ความรู้สึก เป็น Faber

บัญญัติเหล่านี้ใช้ได้กับทุกระดับ — ตั้งแต่ตัวไวยากรณ์เองไปจนถึงวิธีตั้งชื่อ API ในไลบรารีมาตรฐาน นี่คือเหตุผลที่ผู้อ่านสามารถระบุซอร์สโค้ด Faber ได้ทันที ไม่ว่าจะเรนเดอร์คีย์เวิร์ดด้วยภาษามนุษย์ใด หรือโค้ดจะคอมไพล์ไปยังแบ็กเอนด์เป้าหมายใด

I. ประเภทมาก่อนชื่อ#

การประกาศอ่านจากรูปร่างไปสู่การผูกชื่อ ประเภทมาก่อนเพราะผู้อ่านจำเป็นต้องรู้ สิ่งนี้เป็นสิ่งประเภทใด ก่อนที่ชื่อจะบอกว่า เป็นสิ่งใด ลำดับนี้สอดคล้องกับ ภาษาที่มีโครงสร้างทางไวยากรณ์จากหมวดหมู่ไปยังสิ่งเฉพาะ — เช่น ภาษาจีน ภาษาฮินดี และภาษาอาหรับ — และทำให้การประกาศกวาดสายตาได้อย่างสม่ำเสมอ

# Type before name in every declaration
textus nomen
numerus aetas
functio salve(textus name) → textus

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. อักขระภาพทำหน้าที่บอกโครงสร้าง#

ความหมายเชิงโครงสร้างและตัวดำเนินการใช้สัญลักษณ์ภาพ ไม่ใช้คำ: สำหรับการผูกค่า, สำหรับประเภทผลลัพธ์, สำหรับการออกเมื่อเกิดข้อผิดพลาด, ergo สำหรับบอดีของแขนงแบบกระชับ, สำหรับความเท่ากัน และ สำหรับประเภท ยูเนียน สัญลักษณ์ภาพเป็นสากล — ไม่แปลตามภาษาและไม่เปลี่ยนความหมาย ระหว่างการเรนเดอร์ ภาษาไทยและภาษาฝรั่งเศสจึงเห็นสัญลักษณ์ภาพเดียวกัน แม้คีย์เวิร์ดที่อยู่รอบข้างจะแตกต่างกัน

IV. อักษรละตินทำหน้าที่บอกพฤติกรรม#

คำต่าง ๆ ใช้สำหรับการประกาศ คำสั่ง วงจรชีวิต และเจตนาเชิงพฤติกรรม: ฟังก์ชัน, ชนิด, คงที่, แปร, คืน, จับ คำเหล่านี้สามารถผูกเข้ากับแพ็กภาษาของผู้อ่านได้ — คำเหล่านี้คือคลังคำศัพท์ ไม่ใช่ไวยากรณ์ การเลือกใช้ภาษาละตินไม่ได้หมายถึงความเหนือกว่าของภาษาละติน แต่หมายถึงการเลือกแหล่งภาษาคลาสสิก เพียงแหล่งเดียว ที่สอดคล้องกัน เพื่อให้คีย์เวิร์ดทั้งหมดอยู่ในระดับภาษาเดียวกัน และไม่มีคีย์เวิร์ดใดได้รับสิทธิพิเศษ เพียงเพราะเป็นภาษาที่ใช้เขียนตัวระบบ

V. การผันคำกริยาทำหน้าที่บอกเวลาและการไหลของการทำงาน#

เมื่อสามารถเรียกใช้ตรรกะรากเดียวกันแบบซิงโครนัส แบบอะซิงโครนัส หรือในฐานะเจเนอเรเตอร์ได้ รูปผันของคำกริยาควรเป็นตัวบอกโหมดการทำงานนั้น คู่คำที่เกี่ยวกับ ownership — กลายค่าเทียบกับคัดลอกผลลัพธ์ออก — ควรใช้รูปที่สัมพันธ์กันของรากคำเดียวกัน นี่คือหลักการ morphologia ไลบรารีมาตรฐาน (Norma) ใช้แบบแผนนี้กับชื่อเมธอดทั้งหมด: lege (อ่านแบบซิงโครนัส) เทียบกับ leget (อ่านแบบอะซิงโครนัส), adde (กลายค่าในที่เดิม) เทียบกับ addita (คืนสำเนาใหม่) คอมไพเลอร์ไม่ได้บังคับหรือสร้างรูปผันเหล่านี้ เพราะนี่เป็นนโยบายการตั้งชื่อ ไม่ใช่ฟีเจอร์ของภาษา

VI. หนึ่งสัญลักษณ์ หนึ่งหน้าที่#

สัญลักษณ์ภาพหรือคีย์เวิร์ดอาจมีนามแฝงที่มีความหมายตรงกันได้ แต่ไม่ควรมีความหมายที่ไม่เกี่ยวข้องกัน นามแฝงต้องชี้กลับไปยังแนวคิดหลักเพียงหนึ่งเดียว นี่คือหลักการที่ขับเคลื่อนการแยกระหว่าง (การผูกค่าในขณะทำงาน) และ = (รูปร่างฟิลด์เชิงโครงสร้าง) — ภาษาส่วนใหญ่รวมทั้งสองอย่างไว้เป็น = แต่การใช้ซ้ำเช่นนั้นบดบังว่าบรรทัดหนึ่งเป็นการดำเนินการไหลของข้อมูล หรือเป็นการกำหนดในระดับประเภท

# ← is always runtime flow
fixum numerus count ← 0
count ← count + 1

# = is always structural shape inside Type { }
fixum _ p ← Point {
    x = 10,
    y = 20
}

VII. การไหลของการทำงานขณะรันไทม์ต้องชัดเจน#

การผูกค่าในขณะทำงาน การกำหนดค่าใหม่ และการกลายค่าใช้ ; การกำหนดเชิงโครงสร้างใช้ = ผู้อ่านที่กวาดสายตาผ่านซอร์สโค้ดจะเห็น การดำเนินการไหลของข้อมูลทุกจุดได้ทันที: ทุก คือเหตุการณ์ขณะรันไทม์ จึงไม่มีความกำกวมทางไวยากรณ์ว่า = ในบรรทัดหนึ่งหมายถึง “เก็บค่าลงในตัวแปรนี้” หรือ “กำหนดฟิลด์นี้”

VIII. การไม่มีค่าต้องมีประเภท#

ประเภทค่าที่อาจเป็นค่าว่างเขียนเป็นยูเนียน: T ∪ nihil ช่องการประกาศที่เลือกละเว้นได้ใช้เครื่องหมายหลังชื่อ: sponte สองอย่างนี้เป็นแนวคิดที่แตกต่างกัน — ค่าที่อาจไม่มีอยู่ เทียบกับ ช่องที่ผู้เรียกอาจไม่ระบุ — และ Faber แยกสองแนวคิดนี้ทางไวยากรณ์ แทนที่จะรวมทั้งคู่ไว้เป็น T? หรือ Option<T>

# Absence in a value: T ∪ nihil
functio find(textus key) → numerus ∪ nihil

# Omission at declaration: sponte
functio connect(textus host, numerus port sponte) → vacuum

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
ระบบ / AIRair-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 ซึ่งมีชื่อว่า "การลงท้ายของคำบ่งบอกความหมายเชิงอรรถศาสตร์" ได้วางหลักไว้ตั้งแต่เริ่มต้นว่า สัณฐานวิทยาของภาษาละตินจะมีบทบาทมากกว่า การเป็นเพียงผิวหน้าของคีย์เวิร์ด — คอมไพเลอร์จะเข้าใจการผันคำนามและการผันกริยา เพื่ออนุมานเจตนาของโปรแกรม การจับคู่รูปแบบกรณีดั้งเดิมมีดังนี้:

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"

เอกสารฉบับเดียวกันยังระบุว่า: *"คำถามถัดไปตามธรรมชาติคือการผันกริยา (อนาคตกาล → async?)"* เมล็ดพันธุ์นี้เติบโตเป็นหลักการตั้งชื่อ morphologia ในปัจจุบัน โดยไลบรารีมาตรฐานใช้รูปกริยาภาษาละตินที่ผันแล้ว เพื่อสื่อว่าเป็นการทำงานแบบ sync หรือ async และเป็นการกลายค่าเดิมหรือ การคัดลอกผลลัพธ์ออกมา — โดยไม่กำหนดให้คอมไพเลอร์ต้องเข้าใจไวยากรณ์ภาษาละตินเอง

โครงการเริ่มต้นด้วย TypeScript จากนั้นจึงเขียนใหม่ด้วย Rust และตรึงไวยากรณ์ไว้ สำหรับสายรุ่น 1.x โดยใช้เอดิชัน 2026 ADR ดั้งเดิมทั้งห้ารายการ (นามสกุลไฟล์ .fab, คำแนะนำข้อผิดพลาด, การลงท้ายของคำตามกรณี, ตัวแยกวิเคราะห์แบบ recursive descent และ AST แบบกำหนดเอง) ยังคงมองเห็นได้ในประวัติ git

รุ่นเผยแพร่#

ไฟล์ CLI ที่สร้างไว้ล่วงหน้า — รุ่น Faber ปัจจุบันอยู่ด้านบน ตามด้วยแท็กและไบนารีที่เผยแพร่แล้วทั้งหมดจาก faberlang/releases:

  • [รุ่นเผยแพร่](/releases/) — ลิงก์ดาวน์โหลดและรายการประวัติ
  • [ติดตั้งและดาวน์โหลด](/start/install.html) — การตั้งค่า PATH และการรัน faber check ครั้งแรก