future

Package Version Hex Docs

gleam add future@1

Usage

Creating a future

import future

pub fn to_run(x: Int) -> Result(Int, Nil) {
  Ok(x + x)
}

pub fn main() {
  /// To create a future you must provide a function that takes a single argument and returns a Result
  /// The first argument is the argument passed to the future
  /// Nil is valid as an argument an as wrapped by the returned Result
  let fut = future.new(to_run, 1)

  case future.status(fut) {
    /// The future is still running
    future.Running -> todo
    /// The future has completed and returned a result
    future.Completed(result) ->
      case result {
        /// We can now access the result of the future
        Ok(x) -> todo
        /// The functon doesn't ever return an error so we can just add a guard
        Error(x) -> panic as "An error occured!"
      }
    /// Failures are triggered by two things:
    /// - An external exception was thrown
    /// - Gleam called a panic
    /// If an external exception was thrown then the reason will be a stringified version of the exception
    /// If Gleam called a panic then the reason will be the message passed to the panic
    future.Failed(reason) -> panic as reason
    /// The future is no longer in memory and it's status cannot be used
    future.Released -> panic as "The future has been released"
  }
  {
    use value <- future.then(fut)
    /// The future has been completed and the result is available
    /// We can now access the result of the future
    /// This will return a new future that won't start executing until the prior future has completed
    todo
  }
  {
    use message <- future.add_failure_handler(fut)
    /// The future has failed for the provided reason
    /// We can now access the reason for the failure
    /// This will return nothing
    todo
  }
  {
    use state <- future.after(fut)
    /// The future has completed and a final status is available
    /// This will return nothing
    todo
  }

  /// You should always release the future when you are done with it as erlang will keep it in memory forever otherwise
  /// If you don't want to manually release memory look towards `auto_release`, it releases the future as soon as it's complete. This still allows for chaining futures with `then` (assuming the prior future doesn't exit immediately) but ensures the future is released as soon as possible.
  fut |> future.release
}

Resolving a future immediately

import future

pub fn main() {
  /// The result will be immediately available via status
  /// It will also never be marked as running
  let fut = future.from_result(Ok(1)) // This can be an Error too!
  /// Do still make sure to release the future
  fut |> future.release
}
import future

pub fn main() {
  /// The failure message will be immediately available via status
  /// It will also never be marked as running
  let fut = future.from_failure("example")
  /// Do still make sure to release the future
  fut |> future.release
}

Manually controlling a future

import future
import future/manual

pub fn main() {
  /// Create a future that only completes when you call a function
  let #(resolve, reject, fail, fut) = manual.new()

  /// Only the first function to be called will be the result of the future
  /// Any further calls will be ignored
  resolve("hi") // Will complete the future with Ok("hi")
  reject("bye") // Will complete the future with Error("bye")
  fail("oh no") // Will fail the future with Failed("oh no")

  /// Release the future when you are done with it
  fut |> future.release
}

Using a delay

import future
import future/delay

pub fn main() {
  /// Creates a future that resolves after the provided duration
  /// This is designed for use with `after` or `then` to delay the execution of some code
  let fut = delay.of(1000)
  /// Do still make sure to release the future
  fut |> future.release
}

Supported runtimes

RuntimeSupported
Erlang
Node
Deno
Bun

Contributing

PRs are welcome with or without prior discussion.

License

This project is licensed under the Apache License, Version 2.0.

See LICENSE for more information.

Additional information

If you’re unsure about anything, contact me directly via BradBot_1#2042

Further documentation can be found at https://hexdocs.pm/future.

Search Document