Kết xuấtvi

Types and values

Data types#

Faber có hệ thống kiểu tĩnh, ưu tiên kiểu. Mọi khai báo đều đặt kiểu trước tên: textus nomen, không phải nomen: textus. Hệ thống kiểu bao phủ các kiểu nguyên thủy vô hướng, tập hợp tổng quát, kiểu số có kích thước, tensor và các kiểu thanh ghi hướng đến GPU.

Các kiểu nguyên thủy#

KiểuVai tròLiteral ví dụ
văn_bảnChuỗi Unicode"Salve, munde"
asciiToken máy có độ dài cố định'solum:lege'
sốSố nguyên có dấu (mặc định i64)42
thập_phânSố dấu phẩy động (mặc định f64)3.14
logicBooleanđúng, sai
trốngĐơn vị / không có giá trị
rỗngNull / vắng mặtrỗng
thời_điểmKhoảng thời gian / thời điểm
jsonGiá trị JSON tại thời điểm biên dịch{ "key": "value" }
byteChuỗi byte dạng thập lục phân\|00ff\|

Các kiểu số có kích thước#

sốthập_phân có độ rộng mặc định (i64 và f64) cùng các dạng chỉ rõ độ rộng:

hằng số<i32> narrow  7số<i32>

hằng số<u64> wide  255số<u64>

hằng f32 single  1.5 ∷ f32

Có thể dùng cú pháp rút gọn độ rộng ở vị trí kiểu: i8u64, f16, f32, f64 tương đương với numerus<W> / fractus<W>.

Các kiểu nullable#

Giá trị nullable sử dụng cú pháp hợp T ∪ nihil:

hàm find(văn_bản key)  số  rỗng {
    trả rỗng
}

hàm maybe()  văn_bản  rỗng {
    trả rỗng
}

Faber không có cú pháp T? hoặc Option<T>. Hợp kiểu phải được viết tường minh.

Bí danh kiểu#

kiểu_tên UserId = số

Generics#

Hàm, bí danh kiểu, kiểuimplendum chấp nhận tham số kiểu với cú pháp <T>:

hàm identitas<T>(T valor)  T {
    trả valor
}

hàm primum<T>(danh_sách<T> res)  T  rỗng {
    trả res.primus()
}

Có thể chỉ rõ đối số kiểu tại vị trí gọi:

hàm identitas<T>(T valor)  T {
    trả valor
}

hằng số value  identitas<số>(7)

Tập hợp#

KiểuVai tròCú pháp rút gọn
lista<T>Tập hợp động có thứ tựlf32, lu32
tabula<K, V>Bản đồ khóa-giá trị
tensor<T, Figura>Bộ đệm dày có hình dạng cố địnhtf32[4], ti64[2,3]
sparsa<T, Figura>Bộ đệm thưa có hình dạng cố địnhsf32[4], si64[2,3]
intervallumKiểu khoảng
copia<T>Tập hợp không có thứ tự
cursor<T>Luồng lười
hằng danh_sách<số> nums  [1, 2, 3]

hằng bảng<văn_bản, số> scores  { "alice": 10, "bob": 20 }

Các kiểu tensor#

tensor<T, Figura> là bộ chứa dày có hình dạng cố định:

DạngÝ nghĩa
tensor<T, Figura>Cách viết chuẩn
tensor<T, []>Rank 0 (bộ chứa vô hướng)
tensor<T, _>Vị trí để suy luận hình dạng
tensor<T, [N]>Vector rank 1
tensor<T, [N, M]>Ma trận rank 2
hằng ten_xo<f32, []> scalar  tập_rỗng

hằng ten_xo<số, [4]> vector  [1, 2, 3, 4] ↦ ten_xo<số, [4]>

hằng số  rỗng first  vector[0]

Các kiểu lõi GPU#

Các kiểu này được lane hệ thống nhận diện để xử lý GPU và thanh ghi. Các đích gói không hỗ trợ phần cứng sẽ từ chối chúng:

hàm half(f16 x)  f16 {
    trả x
}

hàm add(ma_trận<f32, [2, 2]> a, ma_trận<f32, [2, 2]> b)  ma_trận<f32, [2, 2]> {
    trả a.addita(b)
}

hàm swap(nguyên_tử<số<i32>> cell, số<i32> value)  số<i32> {
    trả cell.exchange(value)
}

Marker mượn trên kiểu#

Các marker mượn (ra, vào, từ) có thể xuất hiện trên kiểu ở vị trí tham số để cho biết cách truyền một giá trị:

# 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
}

Chính sách so sánh#

Toán tửNhómHành vi
, Bằng chính xácBắt buộc các kiểu giống hệt nhau; rỗng được bỏ qua
, Bằng theo giá trị sốChỉ áp dụng cho lattice số
<, , >, Thứ tựSố, thời điểm, văn bản vô hướng
intraChứa trong khoảngSố nằm trong khoảng
interThành viên tập hợpPhần tử nằm trong tập hợp

Variables and binding#

Faber có ba từ khóa biến và một ký hiệu gán riêng. Điểm khác biệt chính nằm giữa hằng (chỉ ghi một lần) và biến (có thể gán lại tự do), cũng như giữa (luồng thực thi) và = (hình dạng trường mang tính cấu trúc).

fixum — liên kết bất biến#

Các liên kết hằng chỉ được ghi một lần. Có thể khai báo chúng có hoặc không có trình khởi tạo; nếu khai báo mà không có trình khởi tạo, chúng phải được gán đúng một lần trước khi đọc. Lần gán thứ hai sẽ bị từ chối.

hằng số count  0

hằng văn_bản name  "Marcus"

hằng danh_sách<số> inferred  [1, 2, 3]

Khởi tạo trì hoãn:

bắt_đầu {
    hằng số factor
    nếu đúng {
        factor  10
    }
    khác {
        factor  100
    }
    ghi_chú factor
}

varia — liên kết khả biến#

Các liên kết biến có thể được gán lại tự do:

bắt_đầu {
    biến số count  0
    count  count + 1
    count  count * 2
}

sit — cú pháp rút gọn cho liên kết bất biến suy luận kiểu#

sit là cú pháp rút gọn của fixum _ — một liên kết bất biến với kiểu được suy luận:

bắt_đầu {
    hằng văn_bản salve  "Salve"
    hằng văn_bản nomen  "Marcus"
    hằng số x  42

    # Deferred form
    hằng văn_bản label
    label  "deferred"
}

Liên kết thời gian chạy và định nghĩa cấu trúc#

Faber tách biệt hai vai trò mà hầu hết các ngôn ngữ gộp chung vào =:

Ký hiệuVai tròDùng cho
Luồng thời gian chạyLiên kết ban đầu, gán lại, biến đổi
=Hình dạng cấu trúcTên trường bên trong literal và siêu dữ liệu
kiểu Point {
    số x
    số y
}

bắt_đầu {
    # Runtime: ← attaches a value to a name at execution time
    biến số count  0
    biến văn_bản label  "ready"
    count  count + 1

    # Structural: = defines field values inside a type literal
    hằng Point p  Point {x = 10, y = 20}
}

Trích xuất trường bằng ex#

từ trích xuất các trường từ một giá trị vào các liên kết cục bộ:

kiểu Persona {
    văn_bản nomen
    số aetas
}

bắt_đầu {
    hằng Persona p  Persona {nomen = "Marcus", aetas = 30}
    hằng văn_bản nomen  p.nomen
    hằng số aetas  p.aetas
    # prints "Marcus"
    ghi_chú nomen
}

Tăng và giảm hậu tố#

là các câu lệnh tăng/giảm hậu tố dành cho các vị trí số khả biến. Chúng chỉ được dùng như câu lệnh — không có giá trị biểu thức và không có dạng tiền tố:

bắt_đầu {
    biến số i  0
    # i becomes 1
    i 
    # i becomes 0
    i ⊖
}

Collections#

Faber có một số kiểu tập hợp do trình biên dịch sở hữu. Các phương thức chuẩn của chúng nằm trong trình biên dịch, không nằm trong thư viện chuẩn.

Lista — tập hợp động có thứ tự#

hằng danh_sách<số> empty  tập_rỗng

hằng danh_sách<số> numbers  [1, 2, 3, 4, 5]

hằng danh_sách<văn_bản> names  ["Marcus", "Julia", "Gaius"]

hằng danh_sách<danh_sách<số>> nested  [[1, 2], [3, 4]]

Trải phần tử bằng sparge:

hằng danh_sách<số> a  [1, 2, 3]

hằng danh_sách<số> b  [4, 5, 6]

hằng danh_sách<số> combined  [rải a, rải b]

hằng danh_sách<số> headed  [0, rải a, 99]

Các phương thức chính: longitudo, accipe, appende, summa, primus, novissimus.

Tabula — ánh xạ khóa–giá trị#

hằng bảng<văn_bản, số> scores  { "alice": 10, "bob": 20 }

Tensor — bộ đệm dày có hình dạng cố định#

hằng ten_xo<f32, []> scalar  tập_rỗng

hằng ten_xo<số, [4]> vector  [1, 2, 3, 4] ↦ ten_xo<số, [4]>

hằng số  rỗng first  vector[0]

Cú pháp rút gọn cho Tensor (mã thiên về số):

hằng ten_xo<f32, []> seed  tập_rỗng

hằng ten_xo<f32, [4]> lanes  seed.strue([1.0, 2.0, 3.0, 4.0], [4])

Các phương thức chính: forma, accipe, ponde, crea, structa, strue, cùng với phép tính theo từng phần tử, phép nhân ma trận (multiplicatio) và các phép rút gọn (summa, productum).

Sparsa — bộ đệm thưa có hình dạng cố định#

hằng thưa<f32, [2, 3]> sparse  tập_rỗng

bắt_đầu {
    sparse.ponde([0, 1], 4.0)
    sparse.ponde([1, 2], 9.0)

    # accipe returns the stored value, here 4.0
    ghi_chú sparse.accipe([0, 1])
    # count of stored entries
    ghi_chú sparse.nonnihil()
}

Chuyển đổi giữa dạng dày và dạng thưa:

hằng ten_xo<f32, [2, 2]> dense  [[1.0, 0.0], [0.0, 2.0]] ↦ ten_xo<f32, [2, 2]>

hằng thưa<f32, [2, 2]> sparse  dense ↦ thưa<f32, [2, 2]>

hằng ten_xo<f32, [2, 2]> roundtrip  sparse ↦ ten_xo<f32, [2, 2]>

Cursors — luồng lười#

cursor<T> là một kiểu luồng lười. Nó được tạo từ các bộ lặp của tập hợp, các view tuus hoặc các hàm sinh. Luồng được tiêu thụ bằng itera ex:

hằng danh_sách<số> items  [1, 2, 3]

bắt_đầu {
    lặp từ items hằng item {
        ghi_chú item
    }
}

Intervallum — các khoảng#

bắt_đầu {
    # exclusive range: 0, 1, 2, 3, 4
    lặp khoảng 05 hằng i {
        ghi_chú i
    }
    # inclusive range: 0, 1, 2, 3, 4, 5
    lặp khoảng 05 hằng i {
        ghi_chú i
    }
}

là điểm cuối khoảng loại trừ; là điểm cuối khoảng bao gồm.

String and template literals#

Faber sử dụng ngữ nghĩa của các dấu phân cách — mỗi dạng dấu nháy biểu thị một dạng mã nguồn khác nhau. Chúng không phải là các từ đồng nghĩa có thể thay thế cho nhau.

Dạng literal#

DạngKiểuVai trò
'…'asciiToken cố định dành cho máy; không có §; không có (…)
"…"văn_bảnChuỗi Unicode một dòng ngắn; (…) được nội suy
«…»văn_bảnUnicode dạng khối/nhiều dòng; (…) được nội suy
formaTemplate được thu giữ; (…) được thu giữ
{ … }jsonTài liệu JSON tại thời điểm biên dịch
``byteDãy byte hex tại thời điểm biên dịch
[ … ]lista<T>Literal danh sách Faber

Áp dụng template chuỗi#

Faber định dạng văn bản bằng phép áp dụng template chuỗi: một literal "…" hoặc «…» có các vị trí trống §, theo sau là các đối số trong ngoặc đơn:

hàm greet(văn_bản nomen)  văn_bản {
    trả "Salve, §!"(nomen)
}

hằng số pagina  3

hằng số totum  10

hằng văn_bản code  "200"

hằng văn_bản label  "OK"

hằng văn_bản msg  "Page § of §"(pagina, totum)

hằng văn_bản block  "status: § (§)"(code, label)

Các quy tắc chính:

  • § (U+00A7) là vị trí trống của template
  • Vị trí trống theo thứ tự: §0, §1, … để chỉ rõ thứ tự
  • Dấu ! ở cuối chọn cách định dạng hiển thị: "Salve, §!"(nomen)
  • Hậu tố (args) là phép áp dụng template, không phải lời gọi hàm

Chuỗi dạng khối#

Các khối nhiều dòng sử dụng dấu ngoặc kép kiểu guillemet «…»:

hằng văn_bản sql  «
    select id, email
    from accounts
»

Template được thu giữ (forma)#

Template dùng dấu backtick thu giữ văn bản và tham số mà không thực hiện việc kết xuất. Phù hợp cho payload SQL/URL có liên kết tham số:

hằng số user_id  42

hằng forma query  `select * from users where id = §`(user_id)

JSON nội tuyến#

{ … } trần là JSON nội tuyến: một tài liệu json tại thời điểm biên dịch, không phải là đối tượng Faber ẩn danh. Các khóa là chuỗi được đặt trong dấu nháy và phân tách bằng ::

hằng json empty  {}

hằng json user  { "name": "Marcus", "age": 30, "active": true }

hằng json nested  { "meta": { "version": 1 }, "tags": ["alpha", "beta"] }

Để tạo một kiểu có kiểu, hãy sử dụng tên kiểu và dạng trường với =:

kiểu Point {
    số x
    số y
}

hằng Point p  Point {x = 10, y = 20}

Nullability and optionality#

Faber phân biệt sự vắng mặt trong một giá trị với việc cung cấp tùy chọn tại vị trí khai báo.

Giá trị nullable — T ∪ nihil#

Dùng T ∪ nihil khi giá trị có thể vắng mặt:

hàm find(văn_bản key)  số  rỗng {
    trả rỗng
}

hàm divide(số a, số b)  số  rỗng {
    nếu b  0 do_đó trả rỗng
    trả a / b
}

Vị trí khai báo tùy chọn — sponte#

Đặt sponte sau tên khi tham số hoặc trường có thể được lược bỏ bởi bên gọi hoặc hàm khởi tạo:

hàm connect(văn_bản host, số port tự_nguyện)  trống {
}

kiểu User {
    văn_bản email tự_nguyện
}

Các dấu mượn có thể kết hợp với tham số tùy chọn:

hàm process(ra số depth tự_nguyện)  trống {
}

Khẳng định non-null — !#

Dùng !., ![, !( để khẳng định rằng một giá trị nullable không phải là rỗng:

kiểu Box {
    số  rỗng val
}

hằng Box  rỗng maybe_name  Box {val = 7}

hằng số  rỗng name  maybe_name!.val

Khẳng định non-null trên rỗng sẽ hủy thực thi tại thời điểm chạy.

Kết hợp nullish — vel#

hằng văn_bản  rỗng provided  rỗng

hằng văn_bản name  provided hoặc_nếu_rỗng "default"

ignotum#

ignotum là kiểu unknown cấp cao nhất dành cho các lối thoát tạm thời và tri thức chưa hoàn chỉnh. Đây không phải là cơ chế biểu diễn tính nullable.

Conversion and construction#

Hai toán tử chuyển đổi quan trọng, một toán tử dùng khi chạy chương trình và một toán tử dùng tại thời điểm biên dịch:

# runtime conversion
hằng số parsed  "42"số
# static ascription
hằng số value  7

hằng văn_bản text  value ∷ văn_bản

Chuyển đổi khi chạy chương trình — ↦#

Dùng để chuyển đổi khi chạy chương trình, đặc biệt là khi phân tích cú pháp hoặc ép kiểu có thể thất bại. Cung cấp xử lý phục hồi nội tuyến bằng :

hằng văn_bản input  "9"

hằng số n  "42"số

hằng số safe  input ↦ số0

Vật chất hóa theo kiểu:

hằng văn_bản path  "/etc/hosts"

hằng vectơ<f32, 4> lanes  [1.0, 2.0, 3.0, 4.0] ↦ vectơ<f32, 4>

hằng văn_bản body  gọi 'solum:lege' (path) ↦ văn_bản

Gán kiểu tĩnh — ∷#

Dùng để gán kiểu tĩnh một cách tường minh. Toán tử này đặt ở hậu tố và được điều khiển bởi kiểu đích:

hằng số value  7

hằng số<i32> x  7số<i32>

hằng văn_bản text  value ∷ văn_bản

Kết hợp giá trị null — vel#

Dùng vel để kết hợp giá trị null khi một giá trị là rỗng:

hằng văn_bản  rỗng provided_name  rỗng

hằng văn_bản name  provided_name hoặc_nếu_rỗng "default"