You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+65-21Lines changed: 65 additions & 21 deletions
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
# TaskSeq<!-- omit in toc -->
6
6
7
-
An implementation of [`IAsyncEnumerable<'T>`][3] as a computation expression: `taskSeq { ... }` with an accompanying `TaskSeq` module, that allows seamless use of asynchronous sequences similar to F#'s native `seq` and `task` CE's.
7
+
An implementation of [`IAsyncEnumerable<'T>`][3] as a computation expression: `taskSeq { ... }` with an accompanying `TaskSeq` module and functions, that allow seamless use of asynchronous sequences similar to F#'s native `seq` and `task` CE's.
8
8
9
9
* Latest stable version: [0.3.0 is on NuGet][nuget].
10
10
* Latest prerelease version: [0.4.0-alpha.1 is on NuGet][nuget].
@@ -52,7 +52,7 @@ See [release notes.txt](release-notes.txt) for the version history of `TaskSeq`.
52
52
53
53
## Overview
54
54
55
-
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][3] given by a call to [`GetAsyncEnumerator()`][6].
55
+
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous, sequential enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][3] given by a call to [`GetAsyncEnumerator()`][6].
56
56
57
57
Since the introduction of `task` in F# the call for a native implementation of _task sequences_ has grown, in particular because proper iteration over an `IAsyncEnumerable` has proven challenging, especially if one wants to avoid mutable variables. This library is an answer to that call and applies the same _resumable state machine_ approach with `taskSeq`.
58
58
@@ -92,7 +92,7 @@ F# Interactive (FSI):
92
92
> #r "nuget: FSharp.Control.TaskSeq"
93
93
94
94
// or with specific version
95
-
> #r "nuget: FSharp.Control.TaskSeq, 0.2.2"
95
+
> #r "nuget: FSharp.Control.TaskSeq, 0.4.0"
96
96
```
97
97
98
98
Paket:
@@ -111,7 +111,7 @@ As package reference in `fsproj` or `csproj` file:
|**Cancellation**| See [#133][], until 0.3.0: use `GetAsyncEnumerator(cancelToken)`| Implicit token flows to all subtasks per `async` semantics |
198
198
|**Performance**| Very high, negligible allocations | Slower, more allocations, due to using `async` and cont style |
199
-
|**Parallelism**|Possible with ChildTask; support will follow | Supported explicitly |
199
+
|**Parallelism**|Unclear, interface is meant for _sequential/async_ processing| Supported by extension functions|
200
200
201
201
<sup>¹⁾ <aid="tsnote1"></a>_Both `AsyncSeq` and `TaskSeq` use a type called `IAsyncEnumerable<'T>`, but only `TaskSeq` uses the type from the BCL Generic Collections. `AsyncSeq` supports .NET Framework 4.6.x and NetStandard 2.0 as well, which do not have this type in the BCL._</sup>
202
202
203
203
## Status & planning
204
204
205
-
This project has stable features currently, but before we go full "version one", we'd like to complete the surface area. This section covers the status of that, with a full list of implemented functions below. Here's the shortlist:
206
-
207
-
-[x] Stabilize and battle-test `taskSeq` resumable code. **DONE**
208
-
-[x] A growing set of module functions `TaskSeq`, see below for progress. **DONE & IN PROGRESS**
209
-
-[x] Packaging and publishing on Nuget, **DONE, PUBLISHED SINCE: 7 November 2022**. See https://www.nuget.org/packages/FSharp.Control.TaskSeq
210
-
-[x] Add `Async` variants for functions taking HOF arguments. **DONE**
211
-
-[ ] Add generated docs to <https://fsprojects.github.io>
212
-
-[ ] Expand surface area based on `AsyncSeq`. **ONGOING**
205
+
The `TaskSeq` project already has a wide array of functions and functionalities, see overview below. The current status is: *STABLE*. However, certain features we'd really like to add:
206
+
207
+
-[x] Take existing `taskSeq` resumable code from F# and fix it. **DONE**
208
+
-[x] Add almost all functions from `Seq` that could apply to `TaskSeq` (full overview below). **MOSTLY DONE, STILL TODO**
209
+
-[ ] Add remaining relevant functions from `Seq`. **PLANNED FOR 0.4.x**
-[ ] Move documentation to <https://fsprojects.github.io>
213
236
214
237
### Implementation progress
215
238
216
-
As of 9 November 2022: [Nuget package available][21]. In this phase, we will frequently update the package, see [release notes.txt](release-notes.txt). Current version:
239
+
* As of 9 November 2022: [Nuget package available][21]. In this phase, we will frequently update the package, see [release notes.txt](release-notes.txt). Current version:
@@ -264,15 +293,15 @@ This is what has been implemented so far, is planned or skipped:
264
293
||`fold2`|`fold2`|`fold2Async`||
265
294
|🚫|`foldBack`|||[note #2](#note2"Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.")|
266
295
|🚫|`foldBack2`|||[note #2](#note2"Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.")|
|❓|`groupBy`|`groupBy`|`groupByAsync`|[note #1](#note1"These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.")|
@@ -310,15 +339,14 @@ This is what has been implemented so far, is planned or skipped:
310
339
|🚫|`readOnly`|||[note #3](#note3"The motivation for 'readOnly' in 'Seq' is that a cast from a mutable array or list to a 'seq<_>' is valid and can be cast back, leading to a mutable sequence. Since 'TaskSeq' doesn't implement 'IEnumerable<_>', such casts are not possible.")|
311
340
||`reduce`|`reduce`|`reduceAsync`||
312
341
|🚫|`reduceBack`|||[note #2](#note2"Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.")|
|❓|`rev`|||[note #1](#note1"These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.")|
317
346
||`scan`|`scan`|`scanAsync`||
318
347
|🚫|`scanBack`|||[note #2](#note2"Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.")|
|❓|`sort`|||[note #1](#note1"These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.")|
@@ -352,7 +380,7 @@ This is what has been implemented so far, is planned or skipped:
0 commit comments