From 4d8922cab9ccd703a324c60110f7433e7abc1125 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 17:37:11 +0000 Subject: [PATCH 1/6] Update verision, make Nil/Cons internal --- RELEASE_NOTES.md | 3 ++- src/FSharp.Control.AsyncSeq/AsyncSeq.fs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fe82d5e..3a89fb6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,6 @@ -### 1.12.2 - 27.03.2015 +### 1.13 - 27.03.2015 * Renamed to FSharp.Control.AsyncSeq +* Remove surface area ### 1.12.1 - 27.03.2015 * Added Async.bindChoice, Async.ParallelIgnore, AsyncSeq.zipWithAsync, AsyncSeq.zappAsync, AsyncSeq.threadStateAsync, AsyncSeq.merge, AsyncSeq.traverseOptionAsync, AsyncSeq.traverseChoiceAsync diff --git a/src/FSharp.Control.AsyncSeq/AsyncSeq.fs b/src/FSharp.Control.AsyncSeq/AsyncSeq.fs index 17d7a26..836d034 100644 --- a/src/FSharp.Control.AsyncSeq/AsyncSeq.fs +++ b/src/FSharp.Control.AsyncSeq/AsyncSeq.fs @@ -19,7 +19,8 @@ type AsyncSeq<'T> = Async> /// The interanl type that represents a value returned as a result of /// evaluating a step of an asynchronous sequence -and AsyncSeqInner<'T> = +and AsyncSeqInner<'T> = + internal | Nil | Cons of 'T * AsyncSeq<'T> From 586a029f434bc13b6a83846d2eafda6abb5530fa Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 17:40:11 +0000 Subject: [PATCH 2/6] Update release notes --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3a89fb6..3800018 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,7 @@ ### 1.13 - 27.03.2015 * Renamed to FSharp.Control.AsyncSeq * Remove surface area +* Hide Nil/Cons from representation of AsyncSeq ### 1.12.1 - 27.03.2015 * Added Async.bindChoice, Async.ParallelIgnore, AsyncSeq.zipWithAsync, AsyncSeq.zappAsync, AsyncSeq.threadStateAsync, AsyncSeq.merge, AsyncSeq.traverseOptionAsync, AsyncSeq.traverseChoiceAsync From c81c452257ef75c9210632754000073cdbc0459a Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 17:48:19 +0000 Subject: [PATCH 3/6] fix doc links --- docs/content/index.md | 2 +- docs/tools/templates/template.cshtml | 2 +- src/FSharp.Control.AsyncSeq/AssemblyInfo.fs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/content/index.md b/docs/content/index.md index 94feab4..24be09d 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -22,7 +22,7 @@ This includes additional brief samples on using most of the functions. [Terminology](terminology.html) a reference for some of the terminology around F# async. -[FSharp.Control.AsyncSeq](library/fsharp-control-AsyncSeq.html) contains narrative and code samples explaining asynchronous sequences. +[FSharp.Control.AsyncSeq](library/AsyncSeq.html) contains narrative and code samples explaining asynchronous sequences. Contributing and copyright -------------------------- diff --git a/docs/tools/templates/template.cshtml b/docs/tools/templates/template.cshtml index 6d1857b..ad9e7af 100644 --- a/docs/tools/templates/template.cshtml +++ b/docs/tools/templates/template.cshtml @@ -46,7 +46,7 @@
  • Terminology
  • -
  • AsyncSeq
  • +
  • AsyncSeq
  • API Reference
  • diff --git a/src/FSharp.Control.AsyncSeq/AssemblyInfo.fs b/src/FSharp.Control.AsyncSeq/AssemblyInfo.fs index a232492..d3cc097 100644 --- a/src/FSharp.Control.AsyncSeq/AssemblyInfo.fs +++ b/src/FSharp.Control.AsyncSeq/AssemblyInfo.fs @@ -4,9 +4,9 @@ open System.Reflection [] [] [] -[] -[] +[] +[] do () module internal AssemblyVersionInformation = - let [] Version = "1.12.2" + let [] Version = "1.13" From b147d914196263ec2637791de78e7efbf8b985a0 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 18:01:08 +0000 Subject: [PATCH 4/6] fix doc terminology --- docs/content/library/AsyncSeq.fsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/content/library/AsyncSeq.fsx b/docs/content/library/AsyncSeq.fsx index a304d60..3e4f831 100644 --- a/docs/content/library/AsyncSeq.fsx +++ b/docs/content/library/AsyncSeq.fsx @@ -3,10 +3,10 @@ # F# Async: FSharp.Control.AsyncSeq An AsyncSeq is a sequence in which individual elements are retrieved using an `Async` computation. -It is similar to `seq<'a>` in that subsequent elements are pulled lazily. Structurally it is +It is similar to `seq<'a>` in that subsequent elements are pulled asynchronously. Structurally it is similar to `list<'a>` with the difference being that each head and tail node or empty node is wrapped -in `Async`. `AsyncSeq` also bears similarity to `IObservable<'a>` with the former being pull-based and the -latter push-based. Analogs for most operations defined for `Seq`, `List` and `IObservable` are also defined for +in `Async`. `AsyncSeq` also bears similarity to `IObservable<'a>` with the former being based on an "asynchronous pull" and the +latter based on a "synchronous push". Analogs for most operations defined for `Seq`, `List` and `IObservable` are also defined for `AsyncSeq`. The power of `AsyncSeq` lies in that many of these operations also have analogs based on `Async` allowing composition of complex asynchronous workflows. @@ -144,9 +144,9 @@ in a blocking manner. ### Comparison with IObservable<'a> Both `IObservable<'a>` and `AsyncSeq<'a>` represent collections of items and both provide similar operations -for transformation and composition. The central difference between the two is that the former is push-based -and the latter is pull-based. Consumers of an `IObservable<'a>` *subscribe* to receive notifications about -new items or the end of the sequence. By contrast, consumers of an `AsyncSeq<'a>` *retrieve* subsequent items on their own +for transformation and composition. The central difference between the two is that the former used a *synchronous push* +and the latter uses an *asynchronous pull*. Consumers of an `IObservable<'a>` *subscribe* to receive notifications about +new items or the end of the sequence. By contrast, consumers of an `AsyncSeq<'a>` *asynchronously retrieve* subsequent items on their own terms. Some domains are more naturally modeled with one or the other, however it is less clear which is a more suitable tool for a specific task. In many cases, a combination of the two provides the optimal solution and restricting yourself to one, while simplifying the programming model, can lead one to view all problems as a nail. @@ -237,15 +237,15 @@ let storedTeetsObs' : IObservable = (** Overall, both solutions are succinct and composable and deciding which one to use can ultimately be a matter of preference. -Some things to consider are the push vs. pull semantics. On the one hand, tweets are pushed based - the consumer has no control +Some things to consider are the "synchronous push" vs. "asynchronous pull" semantics. On the one hand, tweets are pushed based - the consumer has no control over their generation. On the other hand, the program at hand will process the tweets on its own terms regardless of how quickly they are being generated. Moreover, the underlying Twitter API will likely utilize a request-reply protocol to retrieve batches of -tweets from persistent storage. As such, the distinction between push vs. pull becomes less interesting. If the underlying source +tweets from persistent storage. As such, the distinction between "synchronous push" vs. "asynchronous pull" becomes less interesting. If the underlying source is truly push-based, then one can buffer its output and consume it using an asynchronous sequence. If the underlying source is pull-based, then one can turn it into an observable sequence by first pulling, then pushing. Note however that in a true real-time reactive system, notifications must be pushed immediately without delay. -Upon closer inspection, the consumption approaches between the two models aren't all too different. While `AsyncSeq` is pull based, +Upon closer inspection, the consumption approaches between the two models aren't all too different. While `AsyncSeq` is based on an asynchronous-pull operation, it is usually consumed using an operator such as `AsyncSeq.iterAsync` as shown above. This is a function of type `('a -> Async) -> AsyncSeq<'a> -> Async` where the first argument is a function `'a -> Async` which performs some work on an item of the sequence and is applied repeatedly to subsequent items. In a sense, `iterAsync` *pushes* values to this From 5bd8c11d10e0b0caa0ba1634c9e2a9e7a161f00c Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 18:05:24 +0000 Subject: [PATCH 5/6] fix doc terminology --- docs/content/library/AsyncSeq.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/library/AsyncSeq.fsx b/docs/content/library/AsyncSeq.fsx index 3e4f831..342de74 100644 --- a/docs/content/library/AsyncSeq.fsx +++ b/docs/content/library/AsyncSeq.fsx @@ -3,7 +3,7 @@ # F# Async: FSharp.Control.AsyncSeq An AsyncSeq is a sequence in which individual elements are retrieved using an `Async` computation. -It is similar to `seq<'a>` in that subsequent elements are pulled asynchronously. Structurally it is +It is similar to `seq<'a>` in that subsequent elements are pulled on-demand. Structurally it is similar to `list<'a>` with the difference being that each head and tail node or empty node is wrapped in `Async`. `AsyncSeq` also bears similarity to `IObservable<'a>` with the former being based on an "asynchronous pull" and the latter based on a "synchronous push". Analogs for most operations defined for `Seq`, `List` and `IObservable` are also defined for From 52016db4f4f6fab17d3e15b98a2d9226c927d746 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 27 Mar 2015 18:07:27 +0000 Subject: [PATCH 6/6] fix doc terminology --- docs/content/library/AsyncSeq.fsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/content/library/AsyncSeq.fsx b/docs/content/library/AsyncSeq.fsx index 342de74..29d7c87 100644 --- a/docs/content/library/AsyncSeq.fsx +++ b/docs/content/library/AsyncSeq.fsx @@ -144,8 +144,9 @@ in a blocking manner. ### Comparison with IObservable<'a> Both `IObservable<'a>` and `AsyncSeq<'a>` represent collections of items and both provide similar operations -for transformation and composition. The central difference between the two is that the former used a *synchronous push* -and the latter uses an *asynchronous pull*. Consumers of an `IObservable<'a>` *subscribe* to receive notifications about +for transformation and composition. The central difference between the two is that the former uses a *synchronous push* +to a subscriber and the latter uses an *asynchronous pull* by a consumer. +Consumers of an `IObservable<'a>` *subscribe* to receive notifications about new items or the end of the sequence. By contrast, consumers of an `AsyncSeq<'a>` *asynchronously retrieve* subsequent items on their own terms. Some domains are more naturally modeled with one or the other, however it is less clear which is a more suitable tool for a specific task. In many cases, a combination of the two provides the optimal solution and