neoCLR

THE RAVEN PROGRAMMING LANGUAGE

Values, functions
and explicit outcomes.

Raven is a typed, general-purpose language for .NET. It brings functions, pattern matching, classes and interfaces into one language, and is the first language being adapted to neoCLR.

In active development. Raven has its own language and toolchain. The neoCLR target is an experimental integration with a bounded runtime API; support on .NET does not automatically mean support on neoCLR.

Start with a function.

func Normalize(value: int) -> Result<int, OverflowError> {
    let amount = Math.Abs(value)?
    WriteLine("Continued")
    return Result<int, OverflowError>.Ok(amount)
}

func introduces a function and let an immutable local binding. Types can be inferred where the expression makes them clear. Here ? continues with a successful value or returns the error to the caller; the Result return type makes that outcome visible.

This example uses neoCLR’s Math API, where an overflow is a Result. The same language can consume different library contracts on another target.

Explore Option and Result →

Use patterns to name what you received.

func PrintOptional(value: Option<int>) {
    match value {
        Some(let found) => WriteLine(found)
        None => WriteLine("Absent")
    }
}

func PrintSingle(value: Result<int, SingleError>) {
    match value {
        Ok(let found) => WriteLine(found)
        Error(let error) => WriteLine(error.ToString())
    }
}

Patterns expose a case and bind its payload. There is no need for a special method to extract Some’s value. Raven also supports classes, interfaces and object-oriented code when identity, lifetime or polymorphism is part of the problem.

See patterns with the sealed MemberInfo hierarchy →

Make mutation explicit.

var shared = 7
let read: Func<int> = () => shared
let write: Func<int, System.Void> = value => {
    shared = value
}
write(42)
WriteLine(read())
WriteLine(shared)

var marks a mutable binding. These callbacks capture the same variable: writing 42 changes what the reader observes. On neoCLR, System.Void can be a generic result type, so one Func family also describes callbacks with no payload. The Raven spelling unit and its value () map to System.Void in this target.

For properties, val expresses read-only access. Explicit mutability helps readers distinguish a stable local binding from state that may change.

One language, distinct runtime contracts.

Raven normally targets .NET and can use its libraries. The Raven compiler and Raven Language Server run on .NET; the VS Code extension uses that server for editor features. neoCLR itself and programs running on it do not depend on .NET. In the neoCLR integration, Raven emits CLI metadata and IL; a bounded importer translates supported programs for execution on neoCLR’s independent runtime.

This gives us a source language for applications and for the Raven-authored System.Runtime library. It also makes language and runtime gaps visible through real programs. It is not a promise that arbitrary .NET libraries or every Raven feature already run on neoCLR.

Try Raven in a neoCLR project.

Start with a .rvnproj project in VS Code or the terminal. Our setup guide covers downloads, prerequisites, the project file, build/run tasks and expected output.

Try neoCLR with Raven →

For the language’s ordinary .NET target, visit Raven’s language website. The target and available libraries differ from this experiment.

Develop the language through use.

The neoCLR work exercises runtime contracts, metadata and library ergonomics. General compiler improvements belong in Raven’s ordinary development; neoCLR policies remain isolated until they are ready. Both projects are open to feedback, and their APIs can change.

Explore neoCLR’s proposals →