An open API service indexing awesome lists of open source software.

https://github.com/fs-fio/fio

πŸͺ» A Type-Safe, Purely Functional Effect System for Asynchronous and Concurrent F#
https://github.com/fs-fio/fio

concurrency concurrent concurrent-programming effect-system effect-systems fiber fibers fsharp functional-programing green-threads parallel-computing parallel-programming programming-library runtime-system threads

Last synced: 3 months ago
JSON representation

πŸͺ» A Type-Safe, Purely Functional Effect System for Asynchronous and Concurrent F#

Awesome Lists containing this project

README

          

[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![NuGet][nuget-shield]][nuget-url]





FIO Logo

πŸͺ» A Type-Safe, Purely Functional Effect System for Asynchronous and Concurrent F#




View Project Post
Β·
Report Bug
Β·
Request Feature


Table of Contents



  1. About FIO


  2. Getting Started



  3. Benchmarks



  4. Performance


  5. Roadmap


  6. Contributing


  7. License

  8. Contact

  9. Acknowledgments

## About FIO

**FIO** is a type-safe, purely functional effect system for [**F#**](https://fsharp.org/), designed for building **highly concurrent** and **asynchronous** applications. It provides a lightweight [**DSL**](https://martinfowler.com/dsl.html) for writing composable programs using **functional effects**.

Inspired by [**ZIO**](https://zio.dev/) and [**Cats Effect**](https://typelevel.org/cats-effect/), **FIO** features:

- An **IO monad** for managing side effects
- **Fibers** (green threads) for scalable concurrency
- A focus on **purity**, **type safety**, and **performance**

**FIO** was developed as part of a master’s thesis in Computer Science at [**DTU**](https://www.dtu.dk/english).

[**Read the thesis**](https://iyyel.io/assets/doc/masters_thesis_daniel_larsen.pdf) (some parts may be outdated).

> **Note:** FIO is under active development. Contributions, feedback, and questions are very welcome!
> Feel free to report bugs, request features or [**reach out**](mailto:me@iyyel.io).

(back to top)

## Getting Started

Getting started with **FIO** is simple:

1. Install [**.NET**](https://dotnet.microsoft.com/en-us/)
2. Use an editor like [**VS Code**](https://code.visualstudio.com/), [**Visual Studio**](https://visualstudio.microsoft.com/downloads/), or [**Rider**](https://www.jetbrains.com/rider/download/) (or even vim)
3. Clone this repository
4. Open it in your editor
5. Explore the [**FSharp.FIO.Examples**](https://github.com/fs-fio/FIO/tree/main/examples/FSharp.FIO.Examples) project or create your own F# file

### Usage

You can use **FIO** in two ways:
- Directly by creating and running effects manually (examples in [**FSharp.FIO.Examples**](https://github.com/fs-fio/FIO/tree/main/examples/FSharp.FIO.Examples))
- Via `FIOApp`, which simplifies setup and runtime management (examples in [**FSharp.FIO.Examples.App**](https://github.com/fs-fio/FIO/tree/main/examples/FSharp.FIO.Examples.App))

#### Direct Usage

Create a new F# file and open the DSL, IO and Concurrent runtime modules:

```fsharp
module DirectUsage

open FSharp.FIO.DSL
open FSharp.FIO.Lib.IO
open FSharp.FIO.Runtime.Concurrent

[]
let main _ =
let askForName = fio {
do! FConsole.PrintLine "Hello! What is your name?"
let! name = FConsole.ReadLine ()
do! FConsole.PrintLine $"Hello, %s{name}! Welcome to FIO! πŸͺ»πŸ’œ"
}

Runtime().Run askForName
|> fun fiber -> fiber.Task ()
|> Async.AwaitTask
|> Async.RunSynchronously
|> printfn "%A"
0
```

Run it with:

```
$ dotnet run
```

And you'll see the following output:

```
Hello! What is your name?
Daniel
Hello, Daniel, welcome to FIO! πŸͺ»πŸ’œ
Ok ()
```

#### Using FIOApp (Recommended)

Wrap your effect in a `FIOApp` to simplify boilerplate. Open the App module:

```fsharp
module FIOAppUsage

open FSharp.FIO.DSL
open FSharp.FIO.Lib.IO
open FSharp.FIO.App

type WelcomeApp() =
inherit FIOApp ()

override _.effect = fio {
do! FConsole.PrintLine "Hello! What is your name?"
let! name = FConsole.ReadLine ()
do! FConsole.PrintLine $"Hello, %s{name}! Welcome to FIO! πŸͺ»πŸ’œ"
}

WelcomeApp().Run()
```

Same execution as before:

```
$ dotnet run
```

and same output as well:

```
Hello! What is your name?
Daniel
Hello, Daniel, welcome to FIO! πŸͺ»πŸ’œ
Ok ()
```

#### Alternative: DSL-Only Style

Prefer DSL chaining? Use bind (>>=) directly:

```fsharp
module DSLOnly

open FSharp.FIO.DSL
open FSharp.FIO.Lib.IO

let askForName =
FConsole.PrintLine "Hello! What is your name?" >>= fun _ ->
FConsole.ReadLine () >>= fun name ->
FConsole.PrintLine $"Hello, %s{name}, welcome to FIO! πŸͺ»πŸ’œ"
```

## Benchmarks

This repository includes five benchmarks, each designed to evaluate a specific aspect of concurrent computation. All benchmarks are adapted from the [**Savina – An Actor Benchmark Suite**](http://soft.vub.ac.be/AGERE14/papers/ageresplash2014_submission_19.pdf).

### Benchmark Overview

- `Pingpong` – Message sending and retrieval between two actors
- `Threadring` – Message passing with frequent fiber context switching
- `Big` – Many-to-many message passing with high channel contention
- `Bang` – Many-to-one messaging, stressing a single receiver
- `Fork` – Measures fiber spawning overhead

### Running Benchmarks

The benchmarks accept a variety of command-line options:

```
USAGE: FSharp.FIO.Benchmarks [--help]
[--direct-runtime]
[--cooperative-runtime ]
[--concurrent-runtime ]
[--runs ]
[--actor-increment ]
[--round-increment ]
[--pingpong ]
[--threadring ]
[--big ]
[--bang ]
[--fork ]
[--save ]
[--savepath ]

OPTIONS:

--direct-runtime specify Direct runtime
--cooperative-runtime
specify Cooperative runtime with ewc, ews and bwc
--concurrent-runtime
specify Concurrent runtime with ewc, ews and bwc
--runs specify number of runs for each benchmark
--actor-increment
specify the value of actor increment and the number of times
--round-increment
specify the value of round increment and the number of times
--pingpong
specify number of rounds for Pingpong benchmark
--threadring
specify number of actors and rounds for Threadring benchmark
--big
specify number of actors and rounds for Big benchmark
--bang
specify number of actors and rounds for Bang benchmark
--fork specify number of actors for Fork benchmark
--save should save benchmark results to csv file
--savepath
specify absolute path to save the benchmark results csv file
--help display this list of options.
```

### Example

To run each benchmark 30 times using the concurrent runtime (39 evaluation workers, 200 evaluation steps, 1 blocking worker):

```bash
--concurrent-runtime 39 200 1 --runs 30 --pingpong 150000 --threadring 10000 10 --big 250 10 --bang 10000 10 --fork 20000
```

### Experimental Flags

**FIO** also supports optional compile-time flags:

- `DETECT_DEADLOCK` – Enables a simple thread that attempts to detect deadlocks during execution

- `MONITOR` – Starts a monitoring thread that prints internal runtime structure state during execution

> **Note:** These features are experimental and may behave unpredictably.

## Performance

The following plots illustrate the **execution time** (measured in milliseconds) and **scalability** of the available runtime systems across benchmarks.

The runtimes differ in how they manage fibers and blocked operations:

- **Direct** – .NET tasks with waiting for blocked fibers
- **Cooperative** – Fibers with linear-time handling of blocked fibers
- **Concurrent** – Fibers with constant-time handling of blocked fibers

### Execution Time

The boxplots show the measured execution time for each benchmark with the shown benchmark and runtime configurations.

Boxplot

### Scalability

The lineplots show for each benchmark, how each runtime scales when the amount of fibers increases.

Lineplot

## Roadmap

See the [**open issues**](https://github.com/fio-fsharp/fio/issues) for a full list of proposed features (and known issues).

(back to top)

## Contributing

Contributions are welcome and appreciated!

Got an idea or improvement? Feel free to:
- Star the repository
- Open an issue (tag it with `enhancement`)
- Fork the project and submit a pull request

### Quick Start

1. Fork the repository
2. Create a branch: `git checkout -b feature/AmazingFeature`
3. Commit your changes: `git commit -m 'Add AmazingFeature'`
4. Push the branch: `git push origin feature/AmazingFeature`
5. Open a pull request

### Top contributors


Contributors Image

(back to top)

## License

Distributed under the MIT License See [**LICENSE.md**](LICENSE.md) for more information.

(back to top)

## Contact

Daniel "iyyel" Larsen ([**iyyel.io**](https://iyyel.io))

(back to top)

## Acknowledgments

Alceste Scalas ([**people.compute.dtu.dk**](https://people.compute.dtu.dk/alcsc/))

(back to top)

[contributors-shield]: https://img.shields.io/github/contributors/fio-fsharp/fio.svg?style=for-the-badge
[contributors-url]: https://github.com/fio-fsharp/fio/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/fio-fsharp/fio.svg?style=for-the-badge
[forks-url]: https://github.com/fio-fsharp/fio/network/members
[stars-shield]: https://img.shields.io/github/stars/fio-fsharp/fio.svg?style=for-the-badge
[stars-url]: https://github.com/fio-fsharp/fio/stargazers
[issues-shield]: https://img.shields.io/github/issues/fio-fsharp/fio.svg?style=for-the-badge
[issues-url]: https://github.com/fio-fsharp/fio/issues
[license-shield]: https://img.shields.io/github/license/fio-fsharp/fio.svg?style=for-the-badge
[license-url]: https://github.com/fio-fsharp/fio/blob/main/LICENSE.md
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
[linkedin-url]: https://linkedin.com/in/iyyel
[product-screenshot]: images/screenshot.png
[nuget-shield]: https://img.shields.io/nuget/v/FSharp.FIO.svg?style=for-the-badge
[nuget-url]: https://www.nuget.org/packages/FSharp.FIO/0.0.30-alpha
[FSharp]: https://img.shields.io/badge/F%23-378BBA?style=for-the-badge&logo=.NET&logoColor=white
[FSharp-url]: https://fsharp.org/
[.NET]: https://img.shields.io/badge/.NET-5C2D91?style=for-the-badge&logo=.NET&logoColor=white
[.NET-url]: https://dotnet.microsoft.com/en-us/