Getting started
Add a .hb file to a C# project, open the Prelude, and call a compiled formula.
Hilbert is used from an ordinary .NET project. You put .hb files next to your C# files; at build
time the hilbert compiler reads every one of them and writes a C# class per file into
Generated/Hilbert/. Your code calls those classes like any other.
Availability. Hilbert is currently distributed as source, as the modules/MLambda.Hilbert
submodule of the MLambda Genesis workbench — there is no NuGet package yet. The repository is not
buildable on its own clone; build it inside a Genesis checkout as shown below.
1. Get the source
git clone --recurse-submodules https://github.com/mlambda-net/MLambda.Genesis.git
dotnet build MLambda.Genesis/modules/MLambda.Hilbert/MLambda.Hilbert.slnx
An existing Genesis checkout only needs git submodule update --init modules/MLambda.Hilbert.
2. Wire a project
A project that contains .hb files needs two things: a reference to the runtime (the objects the
generated code is written over) and an import of the build targets (the step that runs the
compiler). The compiler itself is a build-time tool and never a run-time dependency.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>Shop.Analytics</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MLambda.Hilbert\src\MLambda.Hilbert.Runtime\MLambda.Hilbert.Runtime.csproj" />
</ItemGroup>
<Import Project="..\MLambda.Hilbert\src\MLambda.Hilbert.Compiler\MLambda.Hilbert.targets" />
</Project>
Adjust the relative paths to where your project sits. The targets understand three optional properties:
| Property | Default | Meaning |
|---|---|---|
HilbertNamespace |
$(RootNamespace) |
Namespace of the generated classes. |
HilbertGeneratedDir |
Generated/Hilbert |
Where the .g.cs files are written. |
HilbertMaxDepth |
1000000 |
How many turns a recursive definition may take before it is reported as a fault. |
Every .hb file under the project directory is an input, and a changed Prelude re-runs the step.
3. Write a formula
Create Angles.hb:
-- Angles.hb — definitions are mathematics; fn is what a program calls.
def radians(d) ≔ d · π / 180
def degrees(r) ≔ r · 180 / π
fn toRadians(a) ↦ radians(a)
fn toDegrees(a) ↦ degrees(a)
fn sum(x, y) ↦ x + y
radians and degrees are definitions: they are inlined wherever they are used and folded by the
compiler, so no π / 180 is computed at run time. toRadians, toDegrees and sum are doorways:
each fn becomes a public static method of a class named after the file.
4. Call it from C#
using Shop.Analytics;
Console.WriteLine(Angles.ToRadians(180)); // 3.141592653589793
Console.WriteLine(Angles.ToDegrees(Math.PI / 2)); // 90
Console.WriteLine(Angles.Sum(1, 2)); // 3
var v = Angles.Sum(new[] { 1d, 2d }, new[] { 2d, 5d }); // [3, 7]
var w = Angles.Sum(10, new[] { 1d, 2d }); // [11, 12] — a real broadcasts
One line of Hilbert produced overloads for double, Complex, Vector, Matrix and Tensor, and
every mix of a real with a shaped value. The outputs above were produced by compiling and running this
exact file.
5. Open the Prelude
The Prelude is Hilbert’s standard library. A module is brought into a document with open:
open Prelude.Statistics
fn average(x) ↦ mean(x)
fn deviation(x) ↦ std(x)
fn midpoint(x) ↦ median(x)
var avg = Summaries.Average(new[] { 1d, 2d, 3d, 4d }); // 2.5
One name is one formula. A document may not declare a name that any module it opens already
declares. fn median(x) ↦ median(x) is refused with HB0001 'median' is already declared in
Statistics.hb — give your doorway its own name, as midpoint above.
What to read next
- The language — every construct, with the Unicode and ASCII spellings.
- Calling from C# — overloads, executors, templates and the tensor types.
- What is a tensor? and Einstein’s summation — the ideas the Prelude is built on.
- The Prelude — every module and every definition.