expected 0.4.0

Implementation of expected idiom (error handling with ok and err)

To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:


Latest version Dub downloads Actions Status codecov license

Implementation of the Expected idiom.

See the Andrei Alexandrescu’s talk (Systematic Error Handling in C++ and its slides.

Or more recent "Expect the Expected" by Andrei Alexandrescu for further background.

It is also inspired by C++'s proposed std::expected and Rust's Result.

Similar work is expectations by Paul Backus.


  • lightweight, no other external dependencies
  • works with pure, @safe, @nogc, nothrow, and immutable
  • provides methods: ok, err, consume, expect, expectErr, andThen, orElse, map, mapError, mapOrElse
  • type inference for ease of use with ok and err
  • allows to use same types for T and E
  • allows to define Expected without value (void for T) - can be disabled with custom Hook
  • provides facility to change the Expected behavior by custom Hook implementation using the Design by introspection paradigm.
  • can enforce result check (with a cost)
  • can behave like a normal Exception handled code by changing the used Hook implementation
  • range interface


View online on Github Pages

expected uses adrdox to generate it's documentation. To build your own copy, run the following command from the root of the expected repository:

path/to/adrdox/doc2 --genSearchIndex --genSource -o generated-docs source

Example usage

auto foo(int i) {
    if (i == 0) return err!int("oops");
    return ok(42 / i);

auto bar(int i) {
    if (i == 0) throw new Exception("err");
    return i-1;

// basic checks
assert(foo(2).value == 21);

assert(foo(0).error == "oops");

// void result
assert(ok()); // no error -> success
// assert(err("foo").hasValue); // doesn't have hasValue and value properties

// expected from throwing function
assert(consume!bar(1) == 0);
assert(consume!bar(0).error.msg == "err");

// orElse
assert(foo(2).orElse!(() => 0) == 21);
assert(foo(0).orElse(100) == 100);

// andThen
assert(foo(2).andThen(foo(6)) == 7);
assert(foo(0).andThen(foo(6)).error == "oops");

// map
assert(foo(2).map!(a => a*2).map!(a => a - 2) == 40);
assert(foo(0).map!(a => a*2).map!(a => a - 2).error == "oops");

// mapError
assert(foo(0).mapError!(e => "OOPS").error == "OOPS");
assert(foo(2).mapError!(e => "OOPS") == 21);

// mapOrElse
assert(foo(2).mapOrElse!(v => v*2, e => 0) == 42);
assert(foo(0).mapOrElse!(v => v*2, e => 0) == 0);

See documentation for more usage examples.


If you're using dub, add the expected package to your project as a dependency.

Alternatively, since it's a single file self-contained implementation, you can simply copy expected.d to your project source directory and compile as usual.

Compilers compatibility

Build is tested against:

  • dmd-latest
  • dmd-2.095.1
  • dmd-2.094.2
  • dmd-2.091.1
  • ldc-latest
  • ldc-1.27.1
  • ldc-1.25.1
  • ldc-1.24.0
  • Tomáš Chaloupka
0.4.0 2023-May-20
0.3.4 2021-Nov-14
0.3.3 2021-Nov-13
0.3.2 2021-Nov-09
0.3.1 2021-Oct-11
Show all 14 versions
Download Stats:
  • 0 downloads today

  • 32 downloads this week

  • 182 downloads this month

  • 14234 downloads total

Short URL: