Early preview: syntax, standard library APIs, and tooling may change.

Numerics and SystemsVectors, Matrices, and Tensors

Vectors, Matrices, and Tensors

Vectors, matrices, and higher-rank tensors carry dimensions in their types.

Float[#3]

Float[#3] is a vector with exactly three Float values.

point: Float[#3] = {1.0, 2.0, 3.0}
-- point[2] == 3.0

Constructors

Constructors need compile-time dimension evidence, not arbitrary runtime integers.

import:
	tensor: matrix, tensor3, vector


pure func default_weights() -> (Float[#3], Float[#2, #2]):
	(vector(0.0, 3), matrix(1.0, 2, 2))


pure func filled_cube() -> Int[#2, #2, #2]:
	tensor3(7, 2, 2, 2)

Shape-Preserving Maps

A map changes elements while retaining the tensor's dimensions.

import:
	vector: map


func doubled[#N](values: Int[#N]) -> Int[#N]:
	map(values, pure func(value: Int): value * 2)

Reductions

Reductions return a scalar or, for argmax and argmin, a proven-safe index. ..#N is an integer type proving 0 <= index < N, not a range value. An index with this type can safely select from a vector of length N.

import:
	vector: argmax, dot, mean, sum


pure func summarize(scores: Int[#4]) -> (Int, Float, ..#4):
	(scores.sum(), scores.mean(), scores.argmax())


pure func similarity(a: Float[#3], b: Float[#3]) -> Float:
	a.dot(b)

Compile-Time Bounds

indices yields proven-safe subscripts in a loop. For a runtime index, use get; invalid indices return None.

import:
	tensor: get, indices


pure func indexed_total[#N](values: Int[#N]) -> Int:
	var total: Int = 0
	for i in indices(values):
		total += values[i]
	total


func main(args: List[String]) -> Void:
	values: Int[#3] = {2, 4, 6}
	print(indexed_total(values)) -- prints: 12
	match get(values, 3):
		Some(value): print(value)
		None: print("out of bounds") -- prints: out of bounds

Dot Product

vector.dot requires both operands to have the same element type and dimension.

import:
	vector: dot


func main(args: List[String]) -> Void:
	a: Float[#3] = {1.0, 2.0, 3.0}

	b: Float[#3] = {4.0, 5.0, 6.0}

	score: Float = dot(a, b)
-- score == 32.0

Matrix Basics

a * b multiplies corresponding elements. matrix.multiply performs matrix multiplication; multiply_vector applies a matrix to a vector. Their result types preserve the required dimensions.

m: Float[#2, #2] = {
	{1.0, 0.0},
	{0.0, 1.0},
}
-- m[1, 1] == 1.0

Parallel Transformations

A pure callback builds a shape-preserving ParallelVector pipeline. The scoped view supports mapping, not filtering, indexing, or escape.

import:
	parallel_vector: map
	vector: ParallelVector, parallel


pure func boost(values: Float[#4]) -> Float[#4]:
	values.parallel(pure func(chunk: ParallelVector[Float, #4]):
		chunk.map(pure func(value: Float): value + 1.0)
	)


func main(args: List[String]) -> Void:
	result: Float[#4] = boost({1.0, 2.0, 3.0, 4.0})
	print(result[0]) -- prints: 2
	print(result[3]) -- prints: 5

Example

vectors.brp
import:
	float: sqrt
	matrix: multiply_vector
	vector: dot


pure func distance(a: Float[#3], b: Float[#3]) -> Float:
	delta: Float[#3] = a - b
	sqrt(dot(delta, delta))


func main(args: List[String]) -> Void:
	p: Float[#3] = {1.0, 2.0, 3.0}
	q: Float[#3] = {1.0, 4.0, 3.0}
	transform: Float[#2, #2] = {
		{1.0, 2.0},
		{3.0, 4.0},
	}
	point: Float[#2] = {5.0, 6.0}
	moved: Float[#2] = multiply_vector(transform, point)
	print(distance(p, q)) -- prints: 2
	print(moved[0]) -- prints: 17
	print(moved[1]) -- prints: 39

Try it

terminal
blorp run vectors.brp