Skip to content

Comparison with Other Libraries

This page compares rustico with other similar libraries in the Python ecosystem.

Feature Comparison

Library Ok/Err do-notation Async Decorators Type Guards Tracebacks Type Hints Monads Rust-like Philosophy Size
rustico CUPID, explicit Small
result Partial Simplicity Tiny
returns Partial Partial Functional Large
poltergeist Minimalism Tiny
rusty-errors Partial Rust-inspired Small

Legend:

  • do-notation: Generator-based early-exit chaining
  • Async: Native async/await support
  • Decorators: Built-in function wrapping decorators
  • Type Guards: is_ok, is_err for static analysis
  • Tracebacks: Captures exception tracebacks in Err
  • Monads: Supports chaining, mapping, flatMap operations
  • Rust-like: API and philosophy inspired by Rust

Detailed Comparison

rustico (This Library)

  • Strengths: Full-featured, async-first, excellent TypeScript-like developer experience
  • Philosophy: CUPID principle - Composable, Unix-like, Predictable, Idiomatic, Declarative
  • Best for: New projects, async workflows, teams wanting explicit error handling
  • Unique features: Traceback capture, do-notation, dual-mode decorators

result

  • Strengths: Simple, lightweight, battle-tested
  • Philosophy: Keep it simple and close to Rust's API
  • Best for: Simple sync applications, minimal dependencies
  • Limitations: No async support, no decorators, basic feature set

returns

  • Strengths: Rich functional programming features, extensive ecosystem
  • Philosophy: Bring functional programming concepts to Python
  • Best for: FP enthusiasts, complex data transformation pipelines
  • Unique features: Maybe, IO, containers, railway-oriented programming
  • Limitations: Learning curve, heavy dependency

poltergeist

  • Strengths: Extremely minimal, zero dependencies
  • Philosophy: Minimalism above all
  • Best for: Embedded systems, minimal footprint requirements
  • Limitations: Very basic feature set, no advanced operations

rusty-errors

  • Strengths: Close to Rust's Result API
  • Philosophy: Direct Rust port
  • Best for: Rust developers transitioning to Python
  • Limitations: Limited Python-specific features, no async

Code Comparison

Basic Usage

rustico

from rustico import Ok, Err, as_result

@as_result(ValueError)
def parse_int(s: str) -> int:
    return int(s)

result = parse_int("123")
if result.is_ok():
    print(result.unwrap())  # 123
else:
    print(f"Error: {result.unwrap_err()}")

result

from result import Ok, Err, Result

def parse_int(s: str) -> Result[int, ValueError]:
    try:
        return Ok(int(s))
    except ValueError as e:
        return Err(e)

result = parse_int("123")
if result.is_ok():
    print(result.unwrap())  # 123
else:
    print(f"Error: {result.unwrap_err()}")

returns

from returns.result import Success, Failure, Result
from returns.functions import raise_exception

def parse_int(s: str) -> Result[int, ValueError]:
    try:
        return Success(int(s))
    except ValueError as e:
        return Failure(e)

result = parse_int("123")
result.map(print)  # 123
result.alt(raise_exception)

Chaining Operations

rustico

from rustico import Ok, Err, do

@do
def process():
    x = yield parse_int("10")
    y = yield parse_int("20")
    return x + y

result = process()
print(result)  # Ok(30)

result

from result import Ok, Err

def process():
    x_result = parse_int("10")
    if x_result.is_err():
        return x_result

    y_result = parse_int("20")
    if y_result.is_err():
        return y_result

    return Ok(x_result.unwrap() + y_result.unwrap())

result = process()
print(result)  # Ok(30)

returns

from returns.result import Success, Failure
from returns.functions import raise_exception

def process():
    return parse_int("10").bind(
        lambda x: parse_int("20").map(
            lambda y: x + y
        )
    )

result = process()
print(result)  # Success(30)

Why Choose rustico?

  • Balanced Approach: Not too minimal, not too complex
  • Async-First: Built with modern async Python in mind
  • Developer Experience: Excellent type hints and IDE integration
  • Explicit Error Handling: Makes error cases impossible to ignore
  • Traceback Capture: Preserves stack traces for better debugging
  • Pattern Matching: First-class support for Python 3.10+ pattern matching
  • Composable: Easy to chain operations with do-notation
  • Rust-Inspired: Familiar API for Rust developers

Choose rustico if you want a modern, well-balanced Result type implementation that works well with both synchronous and asynchronous code, provides excellent developer experience, and makes error handling explicit and composable.