<commit_before># Pipeline

Easily compose NSOperations linearly.

**This is a work-in-progress and might not ever be any more than an experiment.**

## A Trivial Example

```swift
let n = 15
Pipeline(.Background) {
    PipelineOperation { fulfill, reject in fulfill(fibonacci(n)) }
}.success { (input: Int) in
    "\(n)th Fibonacci number: \(input)"
}.success(.Main) { (input: String) -> PipelineOperation<Void> in
    return printOperation(input)
}.start()
```

## Why

I watched <NAME>'s [impressive 2015 WWDC presentation](https://developer.apple.com/videos/wwdc/2015/?id=226) on NSOperations and looked at the demo project and thought it was _really cool_ what could be done on top of the stock classes, but I wasn't convinced of the object-orientedness and how that might make it more difficult to use in specific situations. Apple themselves suggest using the highest-level API available until you hit performance bottlenecks, and yet for some reason I don't think NSOperations are most people's first choice. The API is the highest-level provided, but it can also require a lot of code to use (subclassing) and the encapsulation of both the operation and the data makes it difficult to compose operations linearly without sharing some state. 

I've used PromiseKit and SwiftTask before, and they're both great at what they do. PromiseKit uses GCD but doesn't allow cancellation (not wrongly either, I think), and SwiftTask has some thread-safety considerations but doesn't enqueue or dispatch any work itself. So some of the power of NSOperations (cancellation, its state machine, queue priority, etc.) ends up missing or re-implemented with these libraries. I wanted to see what a high-level API similar to these looked and worked like when built on top of NSOperation. Can NSOperation be used for quick, local as well as app-wide composition? I don't know if I'm really solving these problems or just hand-waving while wrapping them up in a slightly different paradigm, so it's an experiment. :smile:

## Definitions

### Pipeline

Encapsulates a queue and enqueuing operations onto it. Has a default queue priority and allows overriding that priority when adding operations. Also allows specifying that an operation should be run on the main queue.

### Pipeline Operation

A NSOperation subclass that conforms to the Pipelinable protocol, which simply means that it has a `Result<T, NSError>` output value. It can be fulfilled with a value, rejected with an error, or cancelled.

## To Do

- [ ] Add cancellation ability
- [ ] Clarify queue priority and QOS in pipeline API
- [ ] Allow providing a NSOperationQueue when initializing a PipelineQueue<commit_msg>Remove the why<commit_after># Pipeline

**This is a work-in-progress and might not ever be any more than an experiment.**

## A Trivial Example

```swift
let n = 15
Pipeline(.Background) {
    PipelineOperation { fulfill, reject in fulfill(fibonacci(n)) }
}.success { (input: Int) in
    "\(n)th Fibonacci number: \(input)"
}.success(.Main) { (input: String) -> PipelineOperation<Void> in
    return printOperation(input)
}.start()
```

## Definitions

### Pipeline

Encapsulates a queue and enqueuing operations onto it. Has a default queue priority and allows overriding that priority when adding operations. Also allows specifying that an operation should be run on the main queue.

### Pipeline Operation

A NSOperation subclass that conforms to the Pipelinable protocol, which simply means that it has a `Result<T, NSError>` output value. It can be fulfilled with a value, rejected with an error, or cancelled.

## To Do

- [ ] Add cancellation ability
- [ ] Clarify queue priority and QOS in pipeline API
- [ ] Allow providing a NSOperationQueue when initializing a PipelineQueue
{'fraction_non_alphanumeric': 0.06975505857294995, 'fraction_numerical': 0.003993610223642172, 'mean_word_length': 4.5576923076923075, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 10, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5116760', 'n_tokens_mistral': 1011, 'n_tokens_neox': 945, 'n_words': 518}