Skip to content

Frequently asked questions (FAQs)

This section answers some questions that might come to your mind.

Where can I learn more about railway-oriented programming?

Scott Wlaschin's blog post Railway oriented programming comes with lots of examples and illustrations as well as videos and slides from his talks.

Should I replace all raised exceptions with trcks.Result?

No, you should not. Scott Wlaschin's blog post Against Railway-Oriented Programming lists eight scenarios where a result type is not the right tool. Raising an exception, not catching an exception, or returning an optional value are often better choices.

Why does trcks arrange its types, monads, and wrappers as Awaitable > Result > tuple?

trcks provides generic types based on the sequence Awaitable > Result > tuple and its subsequences (e.g. trcks.AwaitableResultTuple, trcks.AwaitableResult, trcks.ResultTuple, and trcks.Result). It also provides matching monads and matching wrapper classes. It does not provide types, monads, or wrapper classes based on permutations such as Result > Awaitable > tuple.

The reason is that the sequence Awaitable > Result > tuple mirrors the behavior of a tuple-returning and exception-raising asynchronous function in conventional Python. Each layer corresponds to one trait of such a function, and the outer-to-inner order matches the order in which the caller unwraps the value:

  1. The function is asynchronous, so the caller awaits it (Awaitable).
  2. Awaiting either yields a value or raises an exception, so trcks models this as success or failure (Result).
  3. In the success case, the function returns a homogeneous tuple, so the caller processes the tuple elements (tuple).

A permutation like Result > Awaitable > tuple would describe a synchronous function that returns either a failure or an awaitable tuple. This does not match the conventional Python pattern, so trcks does not provide it.

Example
>>> import asyncio
>>> from trcks import AwaitableResultTuple, ResultTuple
>>>
>>> # A conventional asynchronous function that returns a tuple
>>> # or raises a ValueError looks like this:
>>> async def read_scores(user_id: int) -> tuple[int, ...]:
...     await asyncio.sleep(0.001)
...     if user_id != 1:
...         raise ValueError("User does not exist")
...     return (90, 85, 100)
>>>
>>> # The trcks equivalent returns the failure instead of raising it.
>>> # Calling it returns an AwaitableResultTuple.
>>> # And awaiting that returns a ResultTuple:
>>> async def read_scores_rop(user_id: int) -> ResultTuple[str, int]:
...     await asyncio.sleep(0.001)
...     if user_id != 1:
...         return "failure", "User does not exist"
...     return "success", (90, 85, 100)
>>>
>>> async def main() -> None:
...     a_rslt: AwaitableResultTuple[str, int] = read_scores_rop(2)
...     rslt: ResultTuple[str, int] = await a_rslt
...     print(rslt)
>>>
>>> asyncio.run(main())
('failure', 'User does not exist')

Which static type checkers does trcks support?

trcks is compatible with current versions of mypy, pyrefly, and pyright. For setup instructions, see Setting up a compatible static type checker.

Other type checkers may also work.

Which alternatives to trcks are there?

returns supports object-oriented style and functional style (like trcks). It provides the returns.result.Result container (and multiple other containers) for synchronous code and the returns.future.Future and returns.future.FutureResult containers for asynchronous code. Whereas the returns.result.Result container closely resembles trcks.Result, the returns.future.Future container and the returns.future.FutureResult container deviate from collections.abc.Awaitable and trcks.AwaitableResult. Further differences between returns and trcks:

Expression supports object-oriented style ("fluent syntax") and functional style (like trcks). It provides the expression.core.result.Result class (and multiple other container classes) for synchronous code. The expression.core.result.Result class is a close counterpart to trcks.Result and trcks.oop.ResultWrapper. An AsyncResult type based on collections.abc.AsyncGenerator has been merged but not yet released (as of July 2026). Expression works with standard type checkers such as pyright without plugins.

Which libraries have inspired trcks?

trcks is mostly inspired by the Python libraries mentioned in the previous section and by the TypeScript library fp-ts.

Where can I find examples for using trcks?

The repository trcks-example-cyclopts contains an example CLI application that uses trcks along with cyclopts.

The repository trcks-example-fastapi contains an example backend application that uses trcks along with FastAPI.