diff --git a/README.md b/README.md index 2a88b5d..05a0976 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,78 @@ # DimWit - Tensor programming with wit -> Programming is the art of telling another human being what one wants the computer to do. -> -> Donald Knuth +
|
+ |
+
+ “Programming is the art of telling another human being what one wants the computer to do.” Vision: A system for writing numerical and machine learning programs that puts human understanding first. While programming, the compiler should help us to keep concepts separate and sharpen our thinking about the problem. +▶ Watch the ScalaDays 2026 talk. + |
+
-
-
| DimWit | JAX |
|---|---|
| -We want to create a system for writing numerical and machine learning programs that puts human understanding first. While programming, the compiler should help us to keep concepts separate and sharpen our thinking about the problem. +```scala +// The axis names are the shared vocabulary +trait Batch derives Label +trait Feature derives Label +trait Output derives Label -## Why? +// f has a strict signature: mapping a feature vector to an output vector +def f(x: Tensor1[Feature, Float32]): Tensor1[Output, Float32] = ... -AI coding agents and modern numerical libraries, such as Jax, Pytorch or Tensorflow, make it ever easier to write numerical and machine learning programs. Yet understanding remains as difficult as ever. Untyped code, -opaque tensor operations and a focus on performance instead of clarity often obscure the concepts underlying the code. +// Tensor types carry meaning and are tracked by the compiler +val X: Tensor2[Batch, Feature, Float32] = ... +val Y: Tensor2[Batch, Output, Float32] = + X.vmap(Axis[Batch])(f) // the axis by name, not position +``` -With *DimWit* we want to change this by -- allowing to express concepts clearly and on a high level -- leveraging the type system to enable the compiler to help us keep - concepts separate and check correctness. + | +-## How? +```python -DimWit uses the power of the Scala 3 type system to encode tensor dimensions as types. It combines this with a high-level API inspired by -JAX and einops, and efficient implementations of tensor operations using JAX as a backend. -## Example -```scala -import dimwit.* -// Labels are simply Scala types -trait Batch derives Label -trait Feature derives Label -// Create a 2D tensor with shape (3, 2), labeled with Batch and Feature -val t = Tensor( - Shape(Axis[Batch] -> 3, Axis[Feature] -> 2), -).fromArray( - Array( - 1.0f, 2.0f, - 3.0f, 4.0f, - 5.0f, 6.0f - ) -) - -// Function to normalize a single feature vector -def normalize(x: Tensor1[Feature, Float32]) : Tensor1[Feature, Float32] = - (x -! x.mean) /! x.std - -// Apply the normalization function across the Batch dimension -val normalized: Tensor2[Batch, Feature, Float32] = - t.vmap(Axis[Batch])(normalize) + +def f(x: Tensor) -> Tensor: ... + + +X: Tensor = ... +Y: Tensor = ( + jax.vmap(f, in_axes=0)(X)) ``` + | +
|
+ |
+
+ “Programming is the art of telling another human being what one wants the computer to do.” Vision: A system for writing numerical and machine learning programs that puts human understanding first. While programming, the compiler should help us to keep concepts separate and sharpen our thinking about the problem. +▶ Watch the ScalaDays 2026 talk. + |
+
-
-
| DimWit | JAX |
|---|---|
| -We want to create a system for writing numerical and machine learning programs that puts human understanding first. While programming, the compiler should help us to keep concepts separate and sharpen our thinking about the problem. +```scala +// The axis names are the shared vocabulary +trait Batch derives Label +trait Feature derives Label +trait Output derives Label -## Why? +// f has a strict signature: mapping a feature vector to an output vector +def f(x: Tensor1[Feature, Float32]): Tensor1[Output, Float32] = ... -AI coding agents and modern numerical libraries, such as Jax, Pytorch or Tensorflow, make it ever easier to write numerical and machine learning programs. Yet understanding remains as difficult as ever. Untyped code, -opaque tensor operations and a focus on performance instead of clarity often obscure the concepts underlying the code. +// Tensor types carry meaning and are tracked by the compiler +val X: Tensor2[Batch, Feature, Float32] = ... +val Y: Tensor2[Batch, Output, Float32] = + X.vmap(Axis[Batch])(f) // the axis by name, not position +``` -With *DimWit* we want to change this by -- allowing to express concepts clearly and on a high level -- leveraging the type system to enable the compiler to help us keep - concepts separate and check correctness. + | +-## How? +```python -DimWit uses the power of the Scala 3 type system to encode tensor dimensions as types. It combines this with a high-level API inspired by -JAX and einops, and efficient implementations of tensor operations using JAX as a backend. -## Example -```scala mdoc:silent + + + +def f(x: Tensor) -> Tensor: ... + + +X: Tensor = ... +Y: Tensor = ( + jax.vmap(f, in_axes=0)(X)) +``` + + | +