Go
HIR projection with file emission and end-to-end floors.
Part of the HIR lane. Every panel below is compiler output.
How to read it#
Go has no generics-free way to express some Faber types, so the emitter materialises helpers the source never wrote. Borrow modes (ref / mut / from) erase here — they lower, but they do not survive as distinctions.
Typed tensors#
Builds two shaped matrices, multiplies them, and reduces the product to a scalar. Exercises shape-bearing types and a reduction.
Faber source
faber format --locale en — English reader surfacemain {
const list<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
const list<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
const tensor<f32, []> seed ← vacua
const tensor<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
const tensor<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
const tensor<f32, [2, 4]> product ← a.matmul(b)
const f32 mean ← product.media()
print mean
}faber format --locale la — canonical Faberincipit {
fixum lista<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
fixum lista<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
fixum tensor<f32, []> seed ← vacua
fixum tensor<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
fixum tensor<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
fixum tensor<f32, [2, 4]> product ← a.matmul(b)
fixum f32 mean ← product.media()
nota mean
}faber format --locale th-TH — Thaiเริ่ม {
คงที่ รายการ<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
คงที่ รายการ<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
คงที่ เทนเซอร์<f32, []> seed ← เซตว่าง
คงที่ เทนเซอร์<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
คงที่ เทนเซอร์<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
คงที่ เทนเซอร์<f32, [2, 4]> product ← a.matmul(b)
คงที่ f32 mean ← product.media()
บันทึก mean
}faber format --locale zh-Hans — Simplified Chinese入口 {
常量 列表<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
常量 列表<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
常量 张量<f32, []> seed ← 空集
常量 张量<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
常量 张量<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
常量 张量<f32, [2, 4]> product ← a.matmul(b)
常量 f32 mean ← product.media()
显示 mean
}faber format --locale zh-Hant — Traditional Chinese入口 {
定值 列表<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
定值 列表<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
定值 張量<f32, []> seed ← 空集
定值 張量<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
定值 張量<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
定值 張量<f32, [2, 4]> product ← a.matmul(b)
定值 f32 mean ← product.media()
註記 mean
}faber format --locale vi — Vietnamesebắt_đầu {
hằng danh_sách<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
hằng danh_sách<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
hằng ten_xo<f32, []> seed ← tập_rỗng
hằng ten_xo<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
hằng ten_xo<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
hằng ten_xo<f32, [2, 4]> product ← a.matmul(b)
hằng f32 mean ← product.media()
ghi_chú mean
}faber format --locale ar — Arabicبداية {
ثابت قائمة<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
ثابت قائمة<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
ثابت موتر<f32, []> seed ← فارغ
ثابت موتر<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
ثابت موتر<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
ثابت موتر<f32, [2, 4]> product ← a.matmul(b)
ثابت f32 mean ← product.media()
اعرض mean
}faber format --locale hi — Hindiआरंभ {
स्थिर सूची<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
स्थिर सूची<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
स्थिर टेंसर<f32, []> seed ← खाली
स्थिर टेंसर<f32, [2, 3]> a ← seed.strue(flat_a, [2, 3])
स्थिर टेंसर<f32, [3, 4]> b ← seed.strue(flat_b, [3, 4])
स्थिर टेंसर<f32, [2, 4]> product ← a.matmul(b)
स्थिर f32 mean ← product.media()
दिखाओ mean
}Go — 10 lines in, 221 out (22.1×)
// Generated by radix - do not edit
package main
import (
"fmt"
"strconv"
"strings"
)
type faberTensor[T any] struct {
data []T
shape []int
}
func faberTensorElementCount(shape []int) int {
const maxInt = int(^uint(0) >> 1)
total := 1
for _, dim := range shape {
if dim < 0 { panic("tensor shape dimension must be non-negative") }
if dim > 0 && total > maxInt/dim { panic("tensor shape element count overflow") }
total *= dim
}
return total
}
func faberIndexSlice(indices any) []int {
switch values := indices.(type) {
case []int:
return append([]int{}, values...)
case []uint32:
out := make([]int, len(values)); for i, value := range values { out[i] = int(value) }; return out
case []uint64:
out := make([]int, len(values)); for i, value := range values { out[i] = int(value) }; return out
case []int32:
out := make([]int, len(values)); for i, value := range values { out[i] = int(value) }; return out
case []int64:
out := make([]int, len(values)); for i, value := range values { out[i] = int(value) }; return out
default:
panic("tensor index must be a numeric list")
}
}
func faberTensorOffset(shape []int, rawIndices any) *int {
const maxInt = int(^uint(0) >> 1)
indices := faberIndexSlice(rawIndices)
if len(indices) != len(shape) { return nil }
offset := 0
stride := 1
for axis := len(shape) - 1; axis >= 0; axis-- {
idx := indices[axis]
dim := shape[axis]
if dim < 0 || idx < 0 || idx >= dim { return nil }
if idx > 0 && stride > (maxInt-offset)/idx { return nil }
offset += idx * stride
if dim > 0 && stride > maxInt/dim { return nil }
stride *= dim
}
return &offset
}
func (t faberTensor[T]) Crea(fill T, shape []int) faberTensor[T] {
data := make([]T, faberTensorElementCount(shape))
for i := range data { data[i] = fill }
return faberTensor[T]{data: data, shape: append([]int{}, shape...)}
}
func (t faberTensor[T]) Strue(data []T, shape []int) faberTensor[T] {
if faberTensorElementCount(shape) != len(data) { panic("tensor structa element count does not match shape") }
return faberTensor[T]{data: append([]T{}, data...), shape: append([]int{}, shape...)}
}
func (t faberTensor[T]) Longitudo() int { return len(t.shape) }
func (t faberTensor[T]) Magnitudines() []int { return append([]int{}, t.shape...) }
func (t faberTensor[T]) Planata() []T { return append([]T{}, t.data...) }
func (t faberTensor[T]) Materialize() faberTensor[T] { return faberTensor[T]{data: append([]T{}, t.data...), shape: append([]int{}, t.shape...)} }
func faberTensorAdd[T any](left T, right T) T {
switch value := any(left).(type) {
case int: return any(value + any(right).(int)).(T)
case int32: return any(value + any(right).(int32)).(T)
case int64: return any(value + any(right).(int64)).(T)
case uint: return any(value + any(right).(uint)).(T)
case uint32: return any(value + any(right).(uint32)).(T)
case uint64: return any(value + any(right).(uint64)).(T)
case float32: return any(value + any(right).(float32)).(T)
case float64: return any(value + any(right).(float64)).(T)
default: panic("tensor arithmetic requires numeric elements")
}
}
func faberTensorMul[T any](left T, right T) T {
switch value := any(left).(type) {
case int: return any(value * any(right).(int)).(T)
case int32: return any(value * any(right).(int32)).(T)
case int64: return any(value * any(right).(int64)).(T)
case uint: return any(value * any(right).(uint)).(T)
case uint32: return any(value * any(right).(uint32)).(T)
case uint64: return any(value * any(right).(uint64)).(T)
case float32: return any(value * any(right).(float32)).(T)
case float64: return any(value * any(right).(float64)).(T)
default: panic("tensor arithmetic requires numeric elements")
}
}
func faberTensorSub[T any](left T, right T) T {
switch value := any(left).(type) {
case int: return any(value - any(right).(int)).(T)
case int32: return any(value - any(right).(int32)).(T)
case int64: return any(value - any(right).(int64)).(T)
case uint: return any(value - any(right).(uint)).(T)
case uint32: return any(value - any(right).(uint32)).(T)
case uint64: return any(value - any(right).(uint64)).(T)
case float32: return any(value - any(right).(float32)).(T)
case float64: return any(value - any(right).(float64)).(T)
default: panic("tensor arithmetic requires numeric elements")
}
}
func faberTensorShapeEqual(left []int, right []int) bool {
if len(left) != len(right) { return false }
for i, dim := range left { if dim != right[i] { return false } }
return true
}
func faberTensorMean[T any](data []T) T {
if len(data) == 0 { panic("tensor media requires non-empty data") }
switch any(data[0]).(type) {
case float32:
var total float32
for _, value := range data { total += any(value).(float32) }
return any(total / float32(len(data))).(T)
case float64:
var total float64
for _, value := range data { total += any(value).(float64) }
return any(total / float64(len(data))).(T)
default: panic("tensor media requires floating-point elements")
}
}
func (t faberTensor[T]) Summa() T {
var total T
for _, value := range t.data { total = faberTensorAdd(total, value) }
return total
}
func (t faberTensor[T]) Media() T { return faberTensorMean(t.data) }
func (a faberTensor[T]) Addita(b faberTensor[T]) faberTensor[T] {
if !faberTensorShapeEqual(a.shape, b.shape) { panic("tensor elementwise arithmetic requires equal shapes") }
data := make([]T, len(a.data))
for i := range data { data[i] = faberTensorAdd(a.data[i], b.data[i]) }
return faberTensor[T]{data: data, shape: append([]int{}, a.shape...)}
}
func (a faberTensor[T]) Subtrahe(b faberTensor[T]) faberTensor[T] {
if !faberTensorShapeEqual(a.shape, b.shape) { panic("tensor elementwise arithmetic requires equal shapes") }
data := make([]T, len(a.data))
for i := range data { data[i] = faberTensorSub(a.data[i], b.data[i]) }
return faberTensor[T]{data: data, shape: append([]int{}, a.shape...)}
}
func (a faberTensor[T]) Multiplica(b faberTensor[T]) faberTensor[T] {
if !faberTensorShapeEqual(a.shape, b.shape) { panic("tensor elementwise arithmetic requires equal shapes") }
data := make([]T, len(a.data))
for i := range data { data[i] = faberTensorMul(a.data[i], b.data[i]) }
return faberTensor[T]{data: data, shape: append([]int{}, a.shape...)}
}
func (a faberTensor[T]) Matmul(b faberTensor[T]) faberTensor[T] {
if len(a.shape) != 2 || len(b.shape) != 2 || a.shape[1] != b.shape[0] { panic("tensor matmul requires compatible rank-2 shapes") }
rows, inner, cols := a.shape[0], a.shape[1], b.shape[1]
data := make([]T, rows*cols)
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
var sum T
for k := 0; k < inner; k++ { sum = faberTensorAdd(sum, faberTensorMul(a.data[row*inner+k], b.data[k*cols+col])) }
data[row*cols+col] = sum
}
}
return faberTensor[T]{data: data, shape: []int{rows, cols}}
}
func (t faberTensor[T]) Forma(shape []int) faberTensor[T] {
if faberTensorElementCount(shape) != len(t.data) { panic("tensor forma (reshape) element count mismatch") }
return faberTensor[T]{data: append([]T{}, t.data...), shape: append([]int{}, shape...)}
}
func (t faberTensor[T]) Accipe(indices any) *T {
offset := faberTensorOffset(t.shape, indices)
if offset == nil || *offset < 0 || *offset >= len(t.data) { return nil }
return &t.data[*offset]
}
func (t *faberTensor[T]) Ponde(indices any, value T) {
offset := faberTensorOffset(t.shape, indices)
if offset == nil || *offset < 0 || *offset >= len(t.data) { panic("tensor ponde invalid index") }
t.data[*offset] = value
}
func (t *faberTensor[T]) Reple(value T) {
for i := range t.data { t.data[i] = value }
}
func (t faberTensor[T]) Sectio(start int, end int) faberTensor[T] {
if len(t.shape) == 0 || start < 0 || end < start || end > t.shape[0] { panic("tensor sectio invalid slice bounds") }
inner := faberTensorElementCount(t.shape[1:])
shape := append([]int{end - start}, t.shape[1:]...)
return faberTensor[T]{data: append([]T{}, t.data[start*inner:end*inner]...), shape: shape}
}
func main() {
flat_a := []float32{float32(1), float32(2), float32(3), float32(4), float32(5), float32(6)}
flat_b := []float32{float32(1), float32(2), float32(3), float32(4), float32(5), float32(6), float32(7), float32(8), float32(9), float32(10), float32(11), float32(12)}
seed := faberTensor[float32]{shape: []int{}}
a := seed.Strue(flat_a, []int{2, 3})
b := seed.Strue(flat_b, []int{3, 4})
product := a.Matmul(b)
mean := float32(product.Media())
fmt.Println(func(v float64) string { s := strconv.FormatFloat(v, 'f', -1, 64); if !strings.ContainsAny(s, ".eE") { return s + ".0" }; return s }(float64(mean)))
}The error channel#
A function that may fail, and a caller that catches. Shows how the ⇥ channel becomes each target's own error idiom.
Faber source
faber format --locale en — English reader surfacefn divide(int a, int b) → int ⇥ string {
if b ≡ 0 {
throw "division by zero"
}
return a / b
}
main {
do {
print divide(10, 2)
}
catch err {
warn err
}
}faber format --locale la — canonical Faberfunctio divide(numerus a, numerus b) → numerus ⇥ textus {
si b ≡ 0 {
iace "division by zero"
}
redde a / b
}
incipit {
fac {
nota divide(10, 2)
}
cape err {
mone err
}
}faber format --locale th-TH — Thaiฟังก์ชัน divide(จำนวน a, จำนวน b) → จำนวน ⇥ ข้อความ {
ถ้า b ≡ 0 {
โยน "division by zero"
}
คืน a / b
}
เริ่ม {
ทำ {
บันทึก divide(10, 2)
}
จับ err {
เตือน err
}
}faber format --locale zh-Hans — Simplified Chinese函数 divide(整数 a, 整数 b) → 整数 ⇥ 文本 {
如果 b ≡ 0 {
抛错 "division by zero"
}
返回 a / b
}
入口 {
执行 {
显示 divide(10, 2)
}
捕获 err {
警告 err
}
}faber format --locale zh-Hant — Traditional Chinese函式 divide(整數 a, 整數 b) → 整數 ⇥ 文字 {
若 b ≡ 0 {
拋出 "division by zero"
}
傳回 a / b
}
入口 {
執行 {
註記 divide(10, 2)
}
捕捉 err {
警告 err
}
}faber format --locale vi — Vietnamesehàm divide(số a, số b) → số ⇥ văn_bản {
nếu b ≡ 0 {
ném "division by zero"
}
trả a / b
}
bắt_đầu {
làm {
ghi_chú divide(10, 2)
}
bắt err {
cảnh_báo err
}
}faber format --locale ar — Arabicدالة divide(عدد a, عدد b) → عدد ⇥ نص {
إذا b ≡ 0 {
ارم "division by zero"
}
أعد a / b
}
بداية {
افعل {
اعرض divide(10, 2)
}
التقط err {
نبه err
}
}faber format --locale hi — Hindiफलन divide(संख्या a, संख्या b) → संख्या ⇥ पाठ {
यदि b ≡ 0 {
इधरफेंको "division by zero"
}
लौटाओ a / b
}
आरंभ {
करो {
दिखाओ divide(10, 2)
}
पकड़ो err {
चेताओ err
}
}Go — 13 lines in, 27 out (2.1×)
// Generated by radix - do not edit
package main
import (
"errors"
"fmt"
"os"
)
func divide(a int, b int) (int, error) {
if (b == 0) {
return 0, errors.New("division by zero")
}
return func() int { left := a; right := b; max := int(^uint(0) >> 1); min := -max - 1; if right == 0 || (left == min && right == -1) { panic("numerus division failed") }; return left / right }(), nil
}
func main() {
faberErr0 := func() error {
fmt.Println(divide(10, 2))
return nil
}()
if faberErr0 != nil {
err := faberErr0
fmt.Fprintln(os.Stderr, err)
}
}Collections and iteration#
A list folded to a total with itera ex. The plainest possible read on how loops lower.
Faber source
faber format --locale en — English reader surfacefn summa(list<int> numeri) → int {
var int total ← 0
for from numeri const n {
total ← total + n
}
return total
}
main {
const list<int> valores ← [1, 2, 3, 4, 5]
print summa(valores)
}faber format --locale la — canonical Faberfunctio summa(lista<numerus> numeri) → numerus {
varia numerus total ← 0
itera ex numeri fixum n {
total ← total + n
}
redde total
}
incipit {
fixum lista<numerus> valores ← [1, 2, 3, 4, 5]
nota summa(valores)
}faber format --locale th-TH — Thaiฟังก์ชัน summa(รายการ<จำนวน> numeri) → จำนวน {
แปร จำนวน total ← 0
วน ออก numeri คงที่ n {
total ← total + n
}
คืน total
}
เริ่ม {
คงที่ รายการ<จำนวน> valores ← [1, 2, 3, 4, 5]
บันทึก summa(valores)
}faber format --locale zh-Hans — Simplified Chinese函数 summa(列表<整数> numeri) → 整数 {
变量 整数 total ← 0
遍历 取自 numeri 常量 n {
total ← total + n
}
返回 total
}
入口 {
常量 列表<整数> valores ← [1, 2, 3, 4, 5]
显示 summa(valores)
}faber format --locale zh-Hant — Traditional Chinese函式 summa(列表<整數> numeri) → 整數 {
變值 整數 total ← 0
遍歷 取自 numeri 定值 n {
total ← total + n
}
傳回 total
}
入口 {
定值 列表<整數> valores ← [1, 2, 3, 4, 5]
註記 summa(valores)
}faber format --locale vi — Vietnamesehàm summa(danh_sách<số> numeri) → số {
biến số total ← 0
lặp từ numeri hằng n {
total ← total + n
}
trả total
}
bắt_đầu {
hằng danh_sách<số> valores ← [1, 2, 3, 4, 5]
ghi_chú summa(valores)
}faber format --locale ar — Arabicدالة summa(قائمة<عدد> numeri) → عدد {
متغير عدد total ← 0
كرر من numeri ثابت n {
total ← total + n
}
أعد total
}
بداية {
ثابت قائمة<عدد> valores ← [1, 2, 3, 4, 5]
اعرض summa(valores)
}faber format --locale hi — Hindiफलन summa(सूची<संख्या> numeri) → संख्या {
चर संख्या total ← 0
दोहराओ सेवन numeri स्थिर n {
total ← total + n
}
लौटाओ total
}
आरंभ {
स्थिर सूची<संख्या> valores ← [1, 2, 3, 4, 5]
दिखाओ summa(valores)
}Go — 12 lines in, 18 out (1.5×)
// Generated by radix - do not edit
package main
import "fmt"
func summa(numeri []int) int {
total := 0
for _, n := range numeri {
total = func() int { left := total; right := n; max := int(^uint(0) >> 1); min := -max - 1; if (right > 0 && left > max-right) || (right < 0 && left < min-right) { panic("numerus overflow") }; return left + right }()
}
return total
}
func main() {
valores := []int{1, 2, 3, 4, 5}
fmt.Println(summa(valores))
}---