@@ -6,11 +6,13 @@
66-- License : BSD3
77-- Maintainer : harendra.kumar@gmail.com
88--
9−-- Streamly, short for stream concurrently, combines the essence of streaming
10−-- and concurrency in functional programming. You can write concurrent as well
11−-- as non-concurrent applications with streamly. Streaming enables writing
12−-- modular, composable and scalable applications with ease and concurrency
13−-- allows you to make them scale and perform well.
9+-- Streamly, short for stream concurrently, combines the essence of
10+-- non-determinism, streaming and concurrency in functional programming.
11+-- Concurrent and non-concurrent applications are almost indistinguisable,
12+-- concurrency capability does not at all impact the performance of
13+-- non-concurrent case.
14+-- Streaming enables writing modular, composable and scalable applications with
15+-- ease and concurrency allows you to make them scale and perform well.
1416-- Streamly enables writing concurrent applications without being aware of
1517-- threads or synchronization. No explicit thread control is needed, where
1618-- applicable the concurrency rate is automatically controlled based on the
@@ -784,7 +786,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
784786-- z \<- 'toList'
785787-- $ 'asyncly' -- Concurrent monadic processing (sqrt below)
786788-- $ do
787−-- x2 \<- 'forEachWith' ('<|') [1..100] $ -- Concurrent @for@ loop
789+-- x2 \<- 'forEachWith' ('<|') [1..100] $ -- Concurrent @"for"@ loop
788790-- \\x -> return $ x * x -- body of the loop
789791-- y2 \<- 'forEachWith' ('<|') [1..100] $
790792-- \\y -> return $ y * y
@@ -940,13 +942,68 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
940942
941943-- $comparison
942944--
943−-- Even though streamly covers all that is provided by the 'async' package or
944−-- most of what is provided by the 'streaming', 'pipes' or 'conduit' packages,
945−-- I would not say that it renders those useless. Streamly is like monad if
946−-- 'async' is applicative and monads and applicatives both have their use
947−-- cases. It can completely repalce 'async', the ZipAsync type is equivalent to
948−-- the functionality provided by 'async'.
949−--
950−-- pipes and conduit are like Arrows and streamly is like monad to them. You
951−-- would use pipes and conduit when you do not need the product style
952−-- composition and the implicit concurrency.
945+-- Streamly unifies non-determinism, streaming, concurrency and FRP
946+-- functionality that is otherwise covered by several disparate packages, and
947+-- it does that with a surprisingly concise API. Here is a list of popular and
948+-- well-known packages in all these areas:
949+--
950+-- @
951+-- +-----------------+----------------+
952+-- | Non-determinism | <https://hackage.haskell.org/package/list-t list-t> |
953+-- | +----------------+
954+-- | | <https://hackage.haskell.org/package/logict logict> |
955+-- +-----------------+----------------+
956+-- | Streaming | <https://hackage.haskell.org/package/streaming streaming> |
957+-- | +----------------+
958+-- | | <https://hackage.haskell.org/package/conduit conduit> |
959+-- | +----------------+
960+-- | | <https://hackage.haskell.org/package/pipes pipes> |
961+-- | +----------------+
962+-- | | <https://hackage.haskell.org/package/simple-conduit simple-conduit> |
963+-- +-----------------+----------------+
964+-- | Concurrency | <https://hackage.haskell.org/package/async async> |
965+-- | +----------------+
966+-- | | <https://hackage.haskell.org/package/transient transient> |
967+-- +-----------------+----------------+
968+-- | FRP | <https://hackage.haskell.org/package/Yampa Yampa> |
969+-- | +----------------+
970+-- | | <https://hackage.haskell.org/package/dunai dunai> |
971+-- | +----------------+
972+-- | | <https://hackage.haskell.org/package/reflex reflex> |
973+-- +-----------------+----------------+
974+-- @
975+--
976+-- Streamly covers all the functionality provided by both the non-determinism
977+-- packages listed above and provides better performance in comparison to
978+-- those. In fact, at the core streamly is a list transformer but it naturally
979+-- integrates the concurrency dimension to the basic list transformer
980+-- functionality.
981+--
982+-- When it comes to streaming, in terms of core concepts, @simple-conduit@ is
983+-- the package that is closest to streamly if we set aside the concurrency
984+-- dimension, both are streaming packages with list transformer like monad
985+-- composition. However, in terms of API it is more like the @streaming@
986+-- package. Streamly can be used to achieve more or less the functionality
987+-- provided by any of the streaming packages listed above. The types and API of
988+-- streamly are much simpler in comparison to conduit and pipes. It is more or
989+-- less like the standard Haskell list APIs.
990+--
991+-- When it comes to concurrency, streamly can do everything that the @async@
992+-- package can do and more. async provides applicative concurrency whereas
993+-- streamly provides both applicative and monadic concurrency. The 'ZipAsync'
994+-- type behaves like the applicative instance of async. This work was
995+-- originally inspired by the concurrency implementation in @transient@ though
996+-- it has no resemblence with that. Streamly provides concurrency as transient
997+-- does but in a sort of dual manner, it can lazily stream the output. In
998+-- comparison to transient streamly has a first class streaming interface and
999+-- is a monad transformer that can be used universally in any Haskell monad
1000+-- transformer stack.
1001+--
1002+-- The non-determinism, concurrency and streaming combination make streamly a
1003+-- strong FRP capable library as well. FRP is fundamentally stream of events
1004+-- that can be processed concurrently. The example in this tutorial as well as
1005+-- the "Streamly.Examples.CirclingSquare" example from Yampa demonstrate the
1006+-- basic FRP capability of streamly. In core concepts streamly is strikingly
1007+-- similar to @dunai@. dunai was designed from a FRP perspective and streamly
1008+-- wa original designed from a concurrency perspective. However, both have
1009+-- similarity at the core.