README.md

# Taskle

A concurrent programming library for Gleam that provides Elixir-like Task module functionality. Taskle allows you to run computations asynchronously using lightweight BEAM processes with a simple, type-safe API.

## Features

- **Simple async/await API** inspired by Elixir's Task module
- **Type-safe concurrency** with full compile-time guarantees
- **Built on BEAM processes** for true concurrency and fault tolerance
- **Timeout support** for all operations
- **Task cancellation** for resource management
- **Parallel processing** utilities for lists
- **Owner-based access control** prevents race conditions

## Installation

Add `taskle` to your Gleam project:

```sh
gleam add taskle
```

## Quick Start

```gleam
import taskle

pub fn main() {
  // Create an asynchronous task
  let task = taskle.async(fn() {
    // Some expensive computation
    expensive_computation()
  })

  // Wait for the result with a timeout (in milliseconds)
  case taskle.await(task, 5000) {
    Ok(result) -> io.println("Got result: " <> result)
    Error(taskle.Timeout) -> io.println("Task timed out")
    Error(taskle.Crashed(reason)) -> io.println("Task crashed: " <> reason)
  }
}
```

## Examples

### Basic Usage

```gleam
import taskle
import gleam/io
import gleam/int

pub fn basic_example() {
  let task = taskle.async(fn() {
    // Simulate some work
    process.sleep(100)
    42
  })

  case taskle.await(task, 1000) {
    Ok(result) -> io.println("Result: " <> int.to_string(result))
    Error(_) -> io.println("Task failed")
  }
}
```

### Parallel Processing

```gleam
import taskle
import gleam/list
import gleam/int

pub fn parallel_example() {
  let numbers = list.range(1, 10)

  case taskle.parallel_map(numbers, fn(n) {
    // Simulate expensive computation
    process.sleep(100)
    n * n
  }, 5000) {
    Ok(squares) -> {
      io.println("Squares: " <> string.inspect(squares))
    }
    Error(err) -> {
      io.println("Parallel processing failed")
    }
  }
}
```

### Task Cancellation

```gleam
import taskle

pub fn cancellation_example() {
  let long_task = taskle.async(fn() {
    process.sleep(30_000)  // 30 seconds
    "finally done"
  })

  // Cancel after 1 second
  process.sleep(1000)
  case taskle.cancel(long_task) {
    Ok(Nil) -> io.println("Task cancelled successfully")
    Error(_) -> io.println("Failed to cancel task")
  }
}
```

### Error Handling Example

```gleam
import taskle

pub fn error_handling_example() {
  let risky_task = taskle.async(fn() {
    case random_boolean() {
      True -> "success"
      False -> panic as "something went wrong"
    }
  })

  case taskle.await(risky_task, 5000) {
    Ok(result) -> io.println("Success: " <> result)
    Error(taskle.Crashed(reason)) -> {
      io.println("Task crashed: " <> reason)
    }
    Error(taskle.Timeout) -> {
      io.println("Task took too long")
    }
    Error(taskle.NotOwner) -> {
      io.println("Ownership error")
    }
  }
}
```

## Best Practices

1. **Always set appropriate timeouts** to prevent hanging operations
2. **Handle all error cases** explicitly for robust applications
3. **Use `cancel()` for cleanup** when tasks are no longer needed
4. **Consider `start()`** for fire-and-forget operations
5. **Keep task functions pure** when possible for easier testing and reasoning

## Performance Considerations

- BEAM processes are lightweight but not free - avoid creating excessive numbers of short-lived tasks
- For CPU-bound work, consider the number of available cores when deciding parallelism level
- Network-bound operations benefit greatly from concurrent execution
- Use `parallel_map` for batch processing rather than creating tasks manually

## Comparison with Other Languages

Taskle provides similar functionality to:

- **Elixir**: `Task.async/1` and `Task.await/2`
- **JavaScript**: `Promise` and `async/await`
- **Go**: Goroutines with channels
- **Rust**: `tokio::spawn` and `.await`

The key difference is that Taskle leverages BEAM's actor model for true parallelism and fault tolerance.

## Contributing

Contributions are welcome! Please ensure:

- All tests pass: `gleam test`
- Code is formatted: `gleam format`
- New features include tests and documentation

## License

This project is licensed under the Apache License 2.0.