渲染zh-Hant

Types and values

Data types#

Faber 採用靜態、型別優先的型別系統。每個宣告都將型別置於名稱之前:textus nomen,而非 nomen: textus。型別系統涵蓋純量原始型別、泛型集合、定寬數值、張量,以及面向 GPU 的暫存器型別。

原始型別#

型別作用字面值範例
文字Unicode 字串"Salve, munde"
ascii固定機器權杖'solum:lege'
整數有號整數(預設為 i64)42
小數浮點數(預設為 f64)3.14
布林布林值
空值單位/無值
空值/不存在
執行個體持續時間/時間瞬間
JSON編譯期 JSON 值{ "key": "value" }
位元組十六進位位元組序列\|00ff\|

定寬數值型別#

整數小數 具有預設定寬(i64 和 f64),也支援明確指定定寬的形式:

定值 整數<i32> narrow  7整數<i32>

定值 整數<u64> wide  255整數<u64>

定值 f32 single  1.5 ∷ f32

在型別位置可使用定寬簡寫:i8u64f16f32f64 分別等同於 numerus<W>fractus<W>

可空型別#

可空值使用聯集語法 T ∪ nihil

函式 find(文字 key)  整數   {
    傳回 
}

函式 maybe()  文字   {
    傳回 
}

Faber 不提供 T?Option<T> 語法。聯集必須明確寫出。

型別別名#

型別 UserId = 整數

泛型#

函式、型別別名、類型implendum 使用 <T> 語法接受型別參數:

函式 identitas<T>(T valor)  T {
    傳回 valor
}

函式 primum<T>(列表<T> res)  T   {
    傳回 res.primus()
}

支援在呼叫位置明確指定型別引數:

函式 identitas<T>(T valor)  T {
    傳回 valor
}

定值 整數 value  identitas<整數>(7)

集合#

型別作用簡寫
lista<T>有序動態集合lf32lu32
tabula<K, V>鍵值對映
tensor<T, Figura>密集固定形狀緩衝區tf32[4]ti64[2,3]
sparsa<T, Figura>稀疏固定形狀緩衝區sf32[4]si64[2,3]
intervallum範圍型別
copia<T>無序集合
cursor<T>惰性串流
定值 列表<整數> nums  [1, 2, 3]

定值 表格<文字, 整數> scores  { "alice": 10, "bob": 20 }

張量型別#

tensor<T, Figura> 是密集固定形狀容器:

形式意義
tensor<T, Figura>標準拼寫
tensor<T, []>秩 0(純量容器)
tensor<T, _>形狀推論缺口
tensor<T, [N]>秩 1 向量
tensor<T, [N, M]>秩 2 矩陣
定值 張量<f32, []> scalar  空集

定值 張量<整數, [4]> vector  [1, 2, 3, 4] ↦ 張量<整數, [4]>

定值 整數   first  vector[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(ex textus buffer)  textus {
    redde buffer
}

比較規則#

運算子類別行為
精確相等必須使用相同型別; 可略過此要求
數值相等僅限數值格
<>排序數值、瞬間、純量文字
intra範圍包含數值位於範圍內
inter集合成員資格元素位於集合內

Variables and binding#

Faber 有三個變數關鍵字,以及專用的指派字元。關鍵差異在於 定值(只能寫入一次)與 變值(可自由重新指派),以及 (執行期流程)與 =(結構欄位形狀)之間的區別。

fixum — 不可變繫結#

定值 繫結只能寫入一次。宣告時可以提供初始值,也可以不提供;若未提供初始值,則必須在讀取前恰好指派一次。第二次指派會被拒絕。

定值 整數 count  0

定值 文字 name  "Marcus"

定值 列表<整數> inferred  [1, 2, 3]

延遲初始化:

入口 {
    定值 整數 factor
      {
        factor  10
    }
    否則 {
        factor  100
    }
    註記 factor
}

varia — 可變繫結#

變值 繫結可以自由重新指派:

入口 {
    變值 整數 count  0
    count  count + 1
    count  count * 2
}

sit — 推導的不可變語法糖#

sitfixum _ 的語法糖——具有推導型別的不可變繫結:

入口 {
    定值 文字 salve  "Salve"
    定值 文字 nomen  "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
    定值 Point p  Point {x = 10, y = 20}
}

ex 欄位擷取#

取自 將值中的欄位擷取至區域繫結:

類型 Persona {
    文字 nomen
    整數 aetas
}

入口 {
    定值 Persona p  Persona {nomen = "Marcus", aetas = 30}
    定值 文字 nomen  p.nomen
    定值 整數 aetas  p.aetas
    # prints "Marcus"
    註記 nomen
}

後置遞增與遞減#

是可變 整數 儲存處的後置遞增/遞減陳述式。它們只能作為陳述式使用——沒有運算式值,也沒有前置形式:

入口 {
    變值 整數 i  0
    # i becomes 1
    i 
    # i becomes 0
    i ⊖
}

Collections#

Faber 有數種由編譯器擁有的集合型別。它們的標準方法定義於編譯器中,而非標準函式庫。

Lista — 有序動態集合#

定值 列表<整數> empty  空集

定值 列表<整數> numbers  [1, 2, 3, 4, 5]

定值 列表<文字> names  ["Marcus", "Julia", "Gaius"]

定值 列表<列表<整數>> nested  [[1, 2], [3, 4]]

使用 sparge 展開:

定值 列表<整數> a  [1, 2, 3]

定值 列表<整數> b  [4, 5, 6]

定值 列表<整數> combined  [展開 a, 展開 b]

定值 列表<整數> headed  [0, 展開 a, 99]

主要方法:longitudoaccipeappendesummaprimusnovissimus

Tabula — 鍵值對映射#

定值 表格<文字, 整數> scores  { "alice": 10, "bob": 20 }

Tensor — 密集固定形狀緩衝區#

定值 張量<f32, []> scalar  空集

定值 張量<整數, [4]> vector  [1, 2, 3, 4] ↦ 張量<整數, [4]>

定值 整數   first  vector[0]

Tensor 語法糖(數值運算密集的程式碼):

定值 張量<f32, []> seed  空集

定值 張量<f32, [4]> lanes  seed.strue([1.0, 2.0, 3.0, 4.0], [4])

主要方法:formaaccipepondecreastructastrue,以及逐元素算術、矩陣乘法(multiplicatio)和歸約(summaproductum)。

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()
}

在密集與稀疏格式之間轉換:

定值 張量<f32, [2, 2]> dense  [[1.0, 0.0], [0.0, 2.0]] ↦ 張量<f32, [2, 2]>

定值 稀疏<f32, [2, 2]> sparse  dense ↦ 稀疏<f32, [2, 2]>

定值 張量<f32, [2, 2]> roundtrip  sparse ↦ 張量<f32, [2, 2]>

Cursors — 延遲串流#

cursor<T> 是延遲串流型別。它可以由集合迭代器、tuus 檢視或產生器函式建立。使用 itera ex 消費:

定值 列表<整數> items  [1, 2, 3]

入口 {
    遍歷 取自 items 定值 item {
        註記 item
    }
}

Intervallum — 範圍#

入口 {
    # exclusive range: 0, 1, 2, 3, 4
    遍歷 範圍 05 定值 i {
        註記 i
    }
    # inclusive range: 0, 1, 2, 3, 4, 5
    遍歷 範圍 05 定值 i {
        註記 i
    }
}

表示不包含終點的範圍; 表示包含終點的範圍。

String and template literals#

Faber 使用分隔符語義——每種引號形式都代表不同的原始碼形狀。它們不是可互換的同義詞。

字面形式#

形式類型作用
'…'ascii固定機器標記;不含 §;不含 (…)
"…"文字短 Unicode 行字串;可解析 (…)
«…»文字區塊/多行 Unicode;可解析 (…)
forma擷取的範本;可擷取 (…)
{ … }JSON編譯期 JSON 文件
``位元組編譯期十六進位位元組
[ … ]lista<T>Faber 清單字面值

字串範本套用#

Faber 使用字串範本套用來格式化文字:先寫入含有 § 佔位符的 "…"«…» 字面值,再接上括號引數:

函式 greet(文字 nomen)  文字 {
    傳回 "Salve, §!"(nomen)
}

定值 整數 pagina  3

定值 整數 totum  10

定值 文字 code  "200"

定值 文字 label  "OK"

定值 文字 msg  "Page § of §"(pagina, totum)

定值 文字 block  "status: § (§)"(code, label)

主要規則:

  • §(U+00A7)是範本佔位符
  • 位置佔位符:§0§1、…,用於明確指定順序
  • 尾端的 ! 選取顯示格式:"Salve, §!"(nomen)
  • (args) 尾碼是範本套用,不是函式呼叫

區塊字串#

多行區塊使用書名號 «…»

定值 文字 sql  «
    select id, email
    from accounts
»

擷取的範本(forma)#

反引號範本會擷取文字與參數,但不進行解析。 適合用於繫結的 SQL/URL 承載內容:

定值 整數 user_id  42

定值 forma query  `select * from users where id = §`(user_id)

內嵌 JSON#

裸露的 { … } 是內嵌 JSON:它是編譯期的 JSON 文件,不是匿名的 Faber 物件。鍵是以引號括起、並以 : 分隔的字串:

定值 JSON empty  {}

定值 JSON user  { "name": "Marcus", "age": 30, "active": true }

定值 JSON nested  { "meta": { "version": 1 }, "tags": ["alpha", "beta"] }

若要建構具型別的 類型,請使用型別名稱與 = 欄位形狀:

類型 Point {
    整數 x
    整數 y
}

定值 Point p  Point {x = 10, y = 20}

Nullability and optionality#

Faber 區分值中的缺失與宣告位置上的可選提供。

可為空值 — T ∪ nihil#

當值可能缺失時,使用 T ∪ nihil

函式 find(文字 key)  整數   {
    傳回 
}

函式 divide(整數 a, 整數 b)  整數   {
     b  0  傳回 
    傳回 a / b
}

可選宣告槽位 — sponte#

當參數或欄位可由呼叫者或建構函式省略時,在名稱後使用 sponte

函式 connect(文字 host, 整數 port 可選)  空值 {
}

類型 User {
    文字 email 可選
}

借用標記可以與可選參數結合:

函式 process( 整數 depth 可選)  空值 {
}

非空值斷言 — !#

使用 !.![!( 來斷言可為空值不是

類型 Box {
    整數   val
}

定值 Box   maybe_name  Box {val = 7}

定值 整數   name  maybe_name!.val

進行非空值斷言會在執行階段中止。

空值合併 — vel#

定值 文字   provided  

定值 文字 name  provided 或取 "default"

ignotum#

ignotum 是頂層未知型別,用於逃生閘道與不完整的知識。它不是可為空值的機制。

Conversion and construction#

兩個重要的轉換運算子,一個用於執行期,另一個用於編譯期:

# runtime conversion
定值 整數 parsed  "42"整數
# static ascription
定值 整數 value  7

定值 文字 text  value ∷ 文字

執行期轉換 — ↦#

使用 進行執行期轉換,尤其適用於可能失敗的剖析或強制轉型。使用 提供行內復原:

定值 文字 input  "9"

定值 整數 n  "42"整數

定值 整數 safe  input ↦ 整數0

由型別導向的具現化:

定值 文字 path  "/etc/hosts"

定值 向量<f32, 4> lanes  [1.0, 2.0, 3.0, 4.0] ↦ 向量<f32, 4>

定值 文字 body  端點 'solum:lege' (path) ↦ 文字

靜態歸屬 — ∷#

使用 明確標註靜態型別。它是後綴運算子,並由目標型別決定:

定值 整數 value  7

定值 整數<i32> x  7整數<i32>

定值 文字 text  value ∷ 文字

空值合併 — vel#

當值為 時,使用 vel 進行空值合併:

定值 文字   provided_name  

定值 文字 name  provided_name 或取 "default"