Native to the CLR
Compiles through Mono.Cecil to ordinary IL. E# types are indistinguishable from C# types to
a consumer — reference the .dll and call them. Interop →
The E# programming language is a general-purpose language that compiles to standard .NET
assemblies — the same Common Language Runtime (CLR) that runs C# and F#. A .es file becomes
a .dll that any C# project can reference without knowing it wasn’t C#. The file extension is .es.
It is not ECMAScript, and it is not a dialect of C# — it’s its own language that happens to share
the .NET runtime.
namespace Demo
// `data` is a value type: copied on assignment, compared by its fields,// no heap and no identity unless you ask for them.data Money { amount: int, currency: string }
// A `choice` is a tagged union — the set of things that can happen, as data.choice ParseError { empty badNumber(text: string)}
// Errors are values. `Result<T, E>` and `?`, not exceptions.func parse(s: string) -> Result<Money, ParseError> { if s.Length == 0 { return error(.empty) } var n = 0 if !int.TryParse(s, out n) { return error(.badNumber(s)) } // BCL interop is direct return ok(Money { amount: n, currency: "USD" })}
// A free function whose first parameter is `Money` *attaches* to it as a method.func describe(m: Money) -> string = "{m.amount} {m.currency}"E# came from wanting a particular language the CLR didn’t have: a type system that reads like
Go but goes further — generics, classes when you need them, and ideas borrowed from Rust (tagged
unions you match exhaustively, errors as values, the -> return syntax). Concurrency shaped by
Go and Swift. An object model that sits between Go and C#: more structure than Go, less ceremony
than C#.
Because being a first-class CLR citizen was a goal from the start, E# also does something .NET
never really had — .es and .cs files fuse into a single assembly, so you can drop it into
a corner of an existing C# codebase and keep going. That’s the JVM’s in-project polyglot story,
finally on the CLR, and it was an early focus because it falls straight out of being native to
the runtime.
The aim isn’t more features than C#; it’s fewer, composed well: value types by default, errors as values, uncolored async, methods that attach to types instead of being trapped inside them.
Native to the CLR
Compiles through Mono.Cecil to ordinary IL. E# types are indistinguishable from C# types to
a consumer — reference the .dll and call them. Interop →
Value-first
data is value-semantic; ref data is the opt-in object world. The CLR form (struct or
class) is the compiler’s call. Types →
Errors as values
Result<T, E> and ? propagation for in-language flow; try/catch only at the BCL
boundary. Errors →
Uncolored async
Any await promotes its function — no async keyword. Uncolored by default; semi-colored when
you want it, since the return type picks the machinery. Concurrency →
E# is general-purpose — it covers the same ground as any other CLR language, with no single
intended niche. Because .es and .cs compile into a single assembly, it can be added to an
existing C# project incrementally, a file at a time, as readily as it stands on its own.
It is pre-alpha. The IL compiler is the source of truth and runs every emitted assembly
through ILVerify; the language is real and tested, but the surface is still moving. The
corpus is a large set of real .es programs drawn from the language’s own test suite
and samples — passing test cases, showcases, and integration tests — each one compiled cleanly (or
rejected with its expected diagnostic) and either producing its asserted output or standing as a real,
well-formed program. It’s the most honest picture of what compiles today.