Types and values
Data types#
Faber มีระบบชนิดข้อมูลแบบสถิตที่ให้ชนิดข้อมูลมาก่อน ทุกการประกาศจะวางชนิดข้อมูลไว้ก่อนชื่อ: ข้อความ ชื่อ ไม่ใช่ ชื่อ: ข้อความ ระบบชนิดข้อมูลครอบคลุมชนิดพื้นฐานแบบสเกลาร์ คอลเลกชันแบบเจเนริก ตัวเลขที่กำหนดขนาด เทนเซอร์ และชนิดรีจิสเตอร์สำหรับงาน GPU
ชนิดข้อมูลพื้นฐาน#
| ชนิดข้อมูล | บทบาท | ตัวอย่างลิเทอรัล |
|---|---|---|
ข้อความ | สตริง Unicode | "Salve, munde" |
ascii | โทเค็นเครื่องแบบความยาวคงที่ | 'solum:lege' |
i32 | จำนวนเต็มมีเครื่องหมาย | 42 |
f64 | จำนวนทศนิยม | 3.14 |
ตรรกะ | ค่าบูลีน | จริง, เท็จ |
เปล่า | หน่วย / ไม่มีค่า | — |
นัล | ค่า Null / ไม่มีอยู่ | นัล |
อินสแตนซ์ | ระยะเวลา / จุดเวลาทันที | — |
json | ค่า 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
}เครื่องหมายความกว้างเปล่าคือชนิดข้อมูล
ชนิดข้อมูลที่รับค่า Null ได้#
ค่าที่รับ Null ได้ใช้ไวยากรณ์ยูเนียน T ∪ นัล:
ฟังก์ชัน find(ข้อความ key) → จํานวน ∪ นัล {
คืน ว่างเปล่า
}
ฟังก์ชัน maybe() → ข้อความ ∪ นัล {
คืน ว่างเปล่า
}Faber ไม่มีไวยากรณ์ T? หรือ Option<T> ยูเนียนนี้ระบุไว้อย่างชัดเจน
นามแฝงชนิดข้อมูล#
ชนิดนามแฝง 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> | เซตที่ไม่เรียงลำดับ | — |
เคอร์เซอร์<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]> row ← [1, 2, 3, 4] ↦ เทนเซอร์<จํานวน, [4]>
คงที่ จํานวน ∪ นัล first ← row[0]
}ชนิดข้อมูลแกนหลักสำหรับ GPU#
ระบบเลนสำหรับงาน GPU และรีจิสเตอร์จะรู้จักชนิดข้อมูลเหล่านี้ แพ็กเกจเป้าหมายที่ไม่รองรับฮาร์ดแวร์จะปฏิเสธชนิดข้อมูลเหล่านี้:
ฟังก์ชัน 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]> row ← [1, 2, 3, 4] ↦ เทนเซอร์<จํานวน, [4]>
คงที่ จํานวน ∪ นัล first ← row[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 — สตรีมแบบประเมินค่าอย่างเลื่อนลอย#
เคอร์เซอร์<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 ใช้ความหมายของตัวคั่น โดยรูปแบบเครื่องหมายคำพูดแต่ละแบบหมายถึงรูปร่างของซอร์สโค้ดที่แตกต่างกัน รูปแบบเหล่านี้ไม่ใช่คำพ้องความหมายที่ใช้แทนกันได้
รูปแบบลิเทอรัล#
| รูปแบบ | ชนิด | บทบาท | ||
|---|---|---|---|---|
'…' | ascii | โทเคนเครื่องจักรแบบคงที่ ไม่รองรับ § และไม่รองรับ (…) | ||
"…" | ข้อความ | สตริง Unicode แบบบรรทัดสั้น โดย (…) จะทำการเรนเดอร์ | ||
«…» | ข้อความ | Unicode แบบบล็อกหรือหลายบรรทัด โดย (…) จะทำการเรนเดอร์ | ||
… | forma | เทมเพลตที่บันทึกไว้ โดย (…) จะจับค่า | ||
{ … } | json | เอกสาร 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, §!"(ชื่อ)- ส่วนต่อท้าย
(args)คือการใช้เทมเพลต ไม่ใช่การเรียกฟังก์ชัน
สตริงแบบบล็อก#
บล็อกหลายบรรทัดใช้เครื่องหมายกีโยแมต์ «…»:
เริ่ม {
คงที่ _ sql ← «
select id, email
from accounts
»
}เทมเพลตที่บันทึกไว้ (forma)#
เทมเพลตที่ใช้เครื่องหมายแบ็กทิกจะจับข้อความและพารามิเตอร์ไว้โดยไม่เรนเดอร์ เหมาะสำหรับเพย์โหลด SQL/URL ที่ผูกค่าอย่างปลอดภัย:
เริ่ม {
คงที่ จํานวน user_id ← 42
คงที่ _ query ← `select * from users where id = §`(user_id)
}JSON แบบอินไลน์#
{ … } เปล่าคือ 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 ∷ ข้อความ
}การรวมค่าเมื่อเป็นค่าว่าง — หรือว่าง#
ใช้ หรือว่าง สำหรับการรวมค่าเมื่อค่าหนึ่งเป็น นัล:
เริ่ม {
คงที่ ข้อความ ∪ นัล provided_name ← ว่างเปล่า
คงที่ _ name ← provided_name หรือว่าง "default"
}