Advertise with Googlier.com
Dave Sexton's Blogon C# and Rx, mostly
https://davesexton.com/blog/
http://www.rssboard.org/rss-specificationBlogEngine.NET 3.0.0.0en-UShttps://davesexton.com/blog/opml.axdhttp://www.dotnetblogengine.net/syndication.axdDave SextonDave Sexton's Blog0.0000000.000000Lambda Enigma is Coming Soon To Steam!<h2><a href="https://store.steampowered.com/app/2818900/Lambda_Enigma/">Lambda Enigma: Steam Store</a></h2> <p>Please add it to your Steam wishlist, or play in <em>Early Access</em> on <strong><font color="#0000ff">March 3rd, 2025</font></strong> to help support development!</p> <p>Let me know your feedback in the Steam discussions area.</p>
https://davesexton.com/blog/post/Lambda-Enigma-is-Coming-Soon-To-Steam!.aspx
https://davesexton.com/blog/post/Lambda-Enigma-is-Coming-Soon-To-Steam!.aspx#commenthttps://davesexton.com/blog/post.aspx?id=91d32e50-db7d-4aba-919f-4aa52e9c8d10Thu, 27 Feb 2025 06:26:00 +0000davehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=91d32e50-db7d-4aba-919f-4aa52e9c8d100https://davesexton.com/blog/trackback.axd?id=91d32e50-db7d-4aba-919f-4aa52e9c8d10https://davesexton.com/blog/post/Lambda-Enigma-is-Coming-Soon-To-Steam!.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=91d32e50-db7d-4aba-919f-4aa52e9c8d10λ Enigma<p><span style='display: inline !important; float: none; background-color: transparent; color: rgb(36, 41, 46); font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 600; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;'>A picture puzzle has a frame. And it has pieces. The pieces are part of a larger picture. The player <u>composes</u> the pieces together into an arrangement that fits within the frame and correctly forms the intended picture.</span></p><p><img style="width: 157px; margin: 8px; float: right;" src="https://raw.githubusercontent.com/RxDave/lambdaenigma.com/master/PuzzlePieceLogoEmbossed.png">Software engineering is about abstraction and composition. We abstract by breaking down larger problems into smaller problems, <span style='display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;'>hiding any unnecessary details</span>. We represent each smaller problem as a function and <span style='display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;'>compose them together to build the larger application, which solves the bigger problem.</span></p><p>Building an application is a puzzle. If the puzzle is finding the correct solution to the larger problem, then the functions that we compose to build the application are its pieces.</p><p>The puzzle frame is the sum of all of the constraints of the application. Your chosen platform and language, performance and memory goals, coding standards, reusability, business requirements, etc.</p><p>The shapes of the pieces correspond to the arities and data types of our functions. Not every piece of a puzzle is composable with any other piece. Only specific pieces fit together.</p><p>Some pieces fit together because they have corresponding shapes, but they form the wrong picture. A watering can where a rose bud should be, or a bumble bee flying around in the mud. Likewise, many functions fit together because they have the same arity and data types, but these compositions compute incorrect output.</p><h2><a style="font-size: 20pt" href="http://lambdaenigma.com">lambdaenigma.com</a><br></h2><span style="background-color: transparent; box-sizing: border-box; color: rgb(51, 51, 51); display: inline; float: none; font-family: &quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"></span><p><span style='display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;'>Over the last few months I've been working very hard on a new idea of mine: A puzzle game for programmers, based on the simple idea of functional composition.</span></p><p>One of my goals of this little experiment is for the game to be playable solo or competitively, whichever you'd prefer. Some of the puzzles are "community" puzzles, which means that the first person to solve them opens up the next puzzle for everyone. Furthermore, the first person to solve a community puzzle gets to enter their name and a hyperlink that is permanently associated with that community puzzle, for all to see.</p><p>I'm still testing and <span style='display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;'>putting on the finishing touches, but once I decide on a go-live date the homepage will be updated with a countdown timer. I'll also announce it on <a href="http://twitter.com/IDaveSexton">Twitter @IDaveSexton</a>.</span></p><span style='text-align: left; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; font-variant: normal; word-spacing: 0px; display: inline !important; white-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: transparent;'><p>For bug reports, please use the issue tracker in my GitHub repo:</p></span><p><a href="https://github.com/RxDave/lambdaenigma.com ">https://github.com/RxDave/lambdaenigma.com </a><br></p><p></p>
https://davesexton.com/blog/post/enigma.aspx
https://davesexton.com/blog/post/enigma.aspx#commenthttps://davesexton.com/blog/post.aspx?id=a3527996-c347-44a5-bbef-c3e8d02053f4Tue, 23 Oct 2018 20:35:00 +0000davehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=a3527996-c347-44a5-bbef-c3e8d02053f42https://davesexton.com/blog/trackback.axd?id=a3527996-c347-44a5-bbef-c3e8d02053f4https://davesexton.com/blog/post/enigma.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=a3527996-c347-44a5-bbef-c3e8d02053f4Monads, and Comonads, and LINQ! Oh, my!<p>Programming through the lens of mathematics offers new ways to solve old problems and old ways to solve new problems. Mathematics is full of surprising relations and dualities.</p> <p>In this blog post, we’ll journey through an alternate reality in which an OOP language like C# becomes more abstract and expressive by adopting some functional programming concepts, rooted in a branch of mathematics called <a href="https://en.wikipedia.org/wiki/Category_theory">Category Theory</a>.</p> <h1>Over The Rainbow</h1> <p>Our journey begins with a few familiar types in a probably unfamiliar categorization.</p> <table class="hideemptycells" cellpadding="2" width="484"><tbody> <tr> <td style="border: currentcolor; border-image: none;" width="109"></td> <td width="191"> <p align="center"><b>Sync</b></p> </td> <td width="182"> <p align="center"><b>Async</b></p> </td> </tr> <tr> <td width="109"> <p align="center"><b>Monad</b></p> </td> <td width="191"> <p align="center">IEnumerable<T> </p> </td> <td width="182"> <p align="center">IObservable<T></p> </td> </tr> <tr> <td width="109"> <p align="center"><b>Comonad</b></p> </td> <td width="191"> <p align="center">Lazy<T> </p> </td> <td width="182"> <p align="center">Task<T> </p> </td> </tr> </tbody></table> <p>Don’t worry if you don’t understand these concepts yet, we’ll meet them again later...</p> <blockquote> <p><b>IEnumerable<T></b> is the <em>list </em>monad.</p> <p><b>IObservable<T></b> is the <em>continuation</em> monad.</p> <p><b>Task<T></b> is the <em>continuation</em> comonad.</p> <p><b>Lazy<T></b> is the <em>singleton </em>comonad (for lack of a better name).</p> </blockquote> <p>These types appear to have different purposes, yet there is actually a pattern hiding in there somewhere. The pattern can be stated in structural terms as follows.</p> <blockquote> <p>Monads have <em>bind </em>and <em>unit </em>functions.</p> <p>Comonads have <em>cobind </em>and <em>extract </em>functions.</p> </blockquote> <table class="hideemptycells" cellpadding="2" width="807"><tbody> <tr> <td style="border: currentcolor; border-image: none;" width="167"></td> <td width="283"> <p align="center"><b>Bind</b></p> </td> <td width="355"> <p align="center"><b>Unit</b></p> </td> </tr> <tr> <td width="167"> <p align="center"><b>IEnumerable<T></b></p> </td> <td width="283"> <p align="center">SelectMany; a.k.a., flatMap</p> </td> <td width="355"> <p align="center">Constructors of Array, List<T>, etc.</p> </td> </tr> <tr> <td width="167"> <p align="center"><b>IObservable<T></b></p> </td> <td width="283"> <p align="center">SelectMany; a.k.a., flatMap</p> </td> <td width="355"> <p align="center">Observable.Return; a.k.a., just</p> </td> </tr> </tbody></table> <br /> <table class="hideemptycells" cellpadding="2" width="806"><tbody> <tr> <td style="border: currentcolor; border-image: none;" width="167"></td> <td width="283"> <p align="center"><b>Cobind</b></p> </td> <td width="354"> <p align="center"><b>Extract</b></p> </td> </tr> <tr> <td width="167"> <p align="center"><strong>Task<T></strong></p> </td> <td width="283"> <p align="center">ContinueWith; a.k.a., then</p> </td> <td width="354"> <p align="center">get_Result</p> <p align="center">(a property named Result)</p> </td> </tr> <tr> <td width="167"> <p align="center"><strong>Lazy<T></strong></p> </td> <td width="283"> <p align="center">?</p> </td> <td width="354"> <p align="center">get_Value</p> <p align="center">(a property named Value)</p> </td> </tr> </tbody></table> <p>You may have noticed that <strong>Lazy<T></strong> is incomplete. Can we define a <i>cobind </i>function for <b>Lazy<T></b>? What would it look like? What would it do?</p> <p>And what’s the relationship between monads and comonads? Is there a pattern?</p> <p>Perhaps if we were to examine these monadic and comonadic types through a lens of abstraction, then we could identify the pattern and figure out how to implement <em>cobind </em>for <strong>Lazy<T></strong>.</p> <h1>“Professor Marvel Never Guesses”</h1> <p>Let's start by examining the <i>bind </i>function for <b>IEnumerable</b><b><T></b>. Here’s its signature:</p> <div class="syntaxhighlighter"> <table><tbody> <tr> <td class="code"> <div class="container"> <pre class="csharpcode">public static IEnumerable<R> SelectMany<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> selector)<br /></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>So the <i>bind </i>function takes an instance of the monadic type for which it's defined, in this case <b>IEnumerable</b><b></b><b><T></b>, and a function that projects the element type, <b>T</b>, into another instance of the monadic type, <b>IEnumerable</b><b></b><b><R></b>.</p>
<p>Its purpose may not be clear yet, so we’ll just try and implement it by heeding Erik Meijer’s advice: “let the types guide you”.</p>
<p>Well, we have a <em>selector </em>function that accepts a <strong>T</strong>, but we don’t have an instance of <strong>T </strong>yet. Since the <i>source</i> is a sequence, it seems that we must invoke the <i>selector </i>function for each <b>T</b> that it contains. So let's start there. We’ll do <strong>foreach </strong>over <em>source </em>and apply <em>selector </em>to each value.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IEnumerable<R> SelectMany<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> selector)</div><div>{</div><div> foreach (var value in source)</div><div> {</div><div> var results = selector(value);</div><div><br /></div><div> // ...</div><div> }</div><div>}</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Great, we're done with the <strong>Select</strong> (a.k.a., <strong>map</strong>) part. Now let’s check the return value.</p>
<p>The selector returns an <b>IEnumerable<R> </b>for a given <b>T</b>, and we need to return a single <strong>IEnumerable<R></strong>. We can’t simply return the <strong>IEnumerable<R> </strong>for the first <strong>T</strong>, because we must return them all. But how do we convert many <strong>IEnumerable<R> </strong>into a single <strong>IEnumerable<R></strong>?</p>
<p>How about we iterate each of the sequences and <i>yield </i>all of the results?</p>
<p>(An <b>Iterator Block </b>makes this easy in C# – it spares us from having to implement <strong>IEnumerable<T> </strong>and <strong>IEnumerator<T> </strong>ourselves.)</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IEnumerable<R> SelectMany<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> selector)</div><div>{</div><div> foreach (var value in source)</div><div> foreach (var innerValue in selector(value))</div><div> yield return innerValue;</div><div>}</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>And now we're done with the <strong>Many </strong>(a.k.a., <strong>flat</strong>) part.</p>
<p>We've just implemented the <em>bind </em>function in the <em>list </em>monad by iterating over the source sequence, mapping each element into a nested sequence, and flattening all of the nested sequences into the output sequence. The name <i>flatMap </i>makes perfect sense! The name <strong>SelectMany </strong>makes sense too, although it’s not a typical naming convention.<sup><a href="#MCL_1">1</a></sup></p>
<p>The significance of this implementation may not be clear yet, but one thing is certain: it was easy to derive this implementation by following the types.</p>
<h1>It’s A Twister! It’s A Twister!</h1>
<p>Shouldn’t all monads have similar signatures for their <b>SelectMany</b> implementations?</p>
<p>Let's look at <i>bind </i>for <strong>IObservable<T></strong>. And for comparison, <strong>IEnumerable<T></strong> as well.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IObservable<R> SelectMany<T, R>(this IObservable<T> source, Func<T, IObservable<R>> selector)</div><div><br /></div><div>public static IEnumerable<R> SelectMany<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Okay, so there's clearly a pattern here. It’s the same exact signature, just with different generic types.</p>
<p>How can we implement <i>bind </i>for <b>IObservable<T></b>?</p>
<p>Since the <i>source</i> is a sequence, it seems that we must invoke the <i>selector </i>function for each <b>T</b> that it contains. And there's only one way to get <b>T</b>'s out of an observable: <b>Subscribe</b></p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IObservable<R> SelectMany<T, R>(this IObservable<T> source, Func<T, IObservable<R>> selector)</div><div> => source.Subscribe(value =></div><div> {</div><div> var results = selector(value);</div><div><br /></div><div> // ...</div><div> });</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>We're done with the <strong>Select</strong> (a.k.a., <strong>map</strong>) part. Now let’s check the return value.</p>
<p>The <em>selector </em>returns an <b>IObservable</b><b><R> </b>for a given <b>T</b>, and we need to return a single <strong>IObservable<R></strong>. Again, we’re in a situation similar to <strong>IEnumerable<T></strong> where we have many instances of the monadic type yet the return type requires a single instance.</p>
<p>To convert many <strong>IObservable<T></strong> into a single <strong>IObservable<T></strong>, how about we <strong>Subscribe</strong> to all of the sequences and push all of their values to the observer? It’s a similar concept to the inner <em>foreach </em>that flattens the <strong>IEnumerable<T></strong>.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IObservable<R> SelectMany<T, R>(this IObservable<T> source, Func<T, IObservable<R>> selector)</div><div> => source.Subscribe(value => selector(value).Subscribe( ? ));</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Uh oh, from where do we get an observer to pass to <b>Subscribe</b>? And how do we return an <b>IObservable<R> </b>from this expression? <b>Subscribe </b>returns <b>IDisposable</b>, so that's not helpful.</p>
<p>What we need is an implementation of <strong>IObservable<T></strong> that we can return from <strong>SelectMany</strong>, so that when <b>Subscribe </b>is called with an <b>IObserver<T></b>, that observer is available to our expression. Then we can pass the observer to the projected observables' subscriptions.</p>
<p>If this seems backwards, it’s because it is. The reactive <strong>IObservable<T></strong> interface is dual to the interactive <strong>IEnumerable<T> </strong>interface. They are structural opposites, so we must think oppositely when solving structural problems like this one.</p>
<p><strong>IEnumerable<T> </strong>is synchronous because the caller of <strong>IEnumerator<T></strong>.<strong>MoveNext </strong>blocks while the next value is computed. <strong>IObservable<T> </strong>is asynchronous because after <strong>Subscribe </strong>is called with an <strong>IObserver<T></strong>, the caller is not necessarily blocked and may continue executing. <strong>OnNext </strong>is called when values are computed in the future.</p>
<p>Using the same observer to subscribe to each of the projected sequences is similar to yielding from all of the projected enumerables in our <b>IEnumerable<T></b> implementation above; however, we don't have a language integrated feature like <b>Iterator Blocks</b>, so we’ll have to use Rx's <b>Observable.Create </b>function instead. The <strong>Observable.Create </strong>function takes a function that has an <strong>IObserver<T> </strong>argument, which we’ll use to make the inner subscriptions.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static IObservable<R> SelectMany<T, R>(this IObservable<T> source, Func<T, IObservable<R>> selector)</div><div> => Observable.Create<R>(observer => source.Subscribe(value => selector(value).Subscribe(observer)));</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>And now we’re done with the <strong>Many </strong>(a.k.a., <strong>flat</strong>) part.</p>
<blockquote>
<p><strong>Note: </strong>I’ve avoided addressing the following issues in the code example above for the sake of simplicity – the focus here is on the essence of the monadic operations, not the implementation details of <a href="https://davesexton.com/blog/post/Checklist-for-Creating-Rx-Operators.aspx">how to properly implement operators</a>.</p>
<ol>
<li>This implementation violates one of Rx's contracts: Serialized notifications per observer (§4.2 in the <a href="https://github.com/Reactive-Extensions/Rx.NET/blob/develop/Rx.NET/Documentation/Rx%20Design%20Guidelines.pdf" target="_blank">Rx Design Guidelines</a>). If any of the inner observables push notifications on different threads, then a downstream observer may receive overlapping notifications, which is very bad. I'm not including a proper implementation in this blog post, but we can imagine that synchronizing calls to <b>OnNext </b>within a <i>lock</i> would suffice.</li>
<li>This implementation fails to properly support cancellation since we’re ignoring the <strong>IDisposable </strong>object that <strong>Subscribe</strong> returns. A proper implementation must hold the disposable for each inner observable, until it terminates. Furthermore, the inner disposables must be tied to the lifetime of the outer disposable, such that if the outer disposable is disposed, then all of the inner subscriptions are cancelled as well.</li>
<li>This implementation fails to properly handle <strong>OnError </strong>and <strong>OnCompleted </strong>notifications from the <em>source</em> observable. Furthermore, it improperly handles <strong>OnCompleted </strong>notifications from the inner observables by completing the sequence as soon as one of the inner observables completes, rather than completing when all observables, including the <em>source</em>, have completed.</li>
</ol>
</blockquote>
<p>The implementation of <em>bind </em>for <strong>IObservable<T></strong>, like <em>bind</em> for <strong>IEnumerable<T></strong>, is a flattening and a mapping; however, due to the natural asynchrony of the <strong>IObservable<T></strong> interface, <em>bind </em>provides an asynchronous <em>merging </em>rather than a synchronous flattening.</p>
<p>In other words, the <b>SelectMany </b>operator for <strong>IObservable<T> </strong>is actually <strong>Select</strong> + <strong>Merge</strong>, whereas <strong>SelectMany </strong>for <strong>IEnumerable<T> </strong>is actually <strong>Select </strong>+ <strong>Concat</strong>.</p>
<p>The <em>bind </em>operator for <strong>IEnumerable<T> </strong>accepts a sequence as input. For each value, an inner sequence is projected and iterated. Due to the synchronous nature of <strong>IEnumerable<T></strong>, only one inner sequence can be iterated at a time. The <em>bind </em>operator will not yield any values from subsequent projections until it has completely iterated over the current inner sequence.</p>
<p>Conversely, the <em>bind </em>operator for <strong>IObservable<T> </strong>merges all inner subscriptions together, such that when any inner subscription produces a value, it’s immediately pushed downstream.</p>
<p>In both implementations of <em>bind</em>, the inner sequences are being flattened down into a single output sequence.</p>
<h1>We’re Not In Kansas Anymore</h1>
<p>Language Integrated Query (LINQ) introduces the <em>monad</em> as a first-class citizen in C#. <strong>Query Comprehension Syntax</strong> is a syntax for monads.<sup><a href="#MCL_2">2</a></sup></p>
<p>They are monads because, other than satisfying the <a href="https://wiki.haskell.org/Monad_laws">monad laws</a>, each monad is a generic type with a specific purpose, paired with a <i>bind </i>function that implements <strong>sequential composition</strong> over that type, while preserving its purpose.</p>
<p>We can understand how <em>bind</em> represents <strong>sequential composition</strong> by following this logic:</p>
<ol>
<li>The <em>bind </em>function <font face="Courier New">SelectMany(M<T> source, Func<T, M<R>> selector)</font>has two parameters.</li>
<li>The <em>source </em>parameter is of the type <strong>M<T></strong>. Think of <strong>M</strong> as the monadic type, which contains values of type <strong>T</strong>. Monadic types are generic types. (This is what is meant by “amplification” or “embellishment”.)</li>
<li>The <em>selector </em>function projects a value of type <strong>T</strong> into <strong>M<R></strong>, which is the monadic type <strong>M </strong>containing values of type <strong>R</strong><strong>.</strong></li>
<li><strong>M<T></strong> represents a computation of values of type <strong>T</strong>. More precisely, <strong>M<T> </strong>represents an <strong>antecedent computation</strong>, because a value of <strong>T </strong>must be computed before it can be passed to <em>selector</em>.</li>
<li>The <em>selector </em>function represents a <strong>subsequent computation</strong>, because it accepts a value of type <strong>T </strong>and returns <strong>M<R></strong>. And just like <strong>M<T></strong>, <strong>M<R> </strong>represents a computation of values of type <strong>R</strong>.</li>
<li>Both <strong>M<T> </strong>and <strong>M<R></strong> are of the monadic type <strong>M</strong>, although they may contain different types. <strong>M<R> </strong>can be used as the <em>source </em>parameter in a subsequent <em>bind </em>operation.</li>
<li>The <em>bind </em>operator can be chained together across may projections over the monadic type <strong>M</strong>, such that <strong>M<T> </strong>goes to <strong>M<R></strong> goes to <strong>M<Q></strong>, and so on. Each projection through <em>bind</em> is a linear step in a larger computation.</li>
<li>Therefore, the <em>bind</em> function <strong>sequentially composes</strong> antecedent computations with subsequent computations, while preserving the purpose of the monadic type.</li>
<li>However, the cardinality of <strong>M</strong> may be greater than 1, depending on the actual type of <strong>M</strong>. Containing more than one <strong>T </strong>means having more than one <strong>M<R></strong> because each <strong>T </strong>will be projected into an instance of <strong>M<R>.</strong></li>
<li>The <em>bind </em>operator flattens <strong>M<M<R>></strong> into a single <strong>M<R></strong> to ensure that its result is a single container of the monadic type <strong>M</strong>. Flattening preserves sequential composition regardless of the cardinality of <strong>M</strong>.</li>
</ol>
<p>For example, <b>IEnumerable<T></b> represents a lazily-computed, synchronous sequence of values of type <b>T</b>. That’s its purpose, which <strong>SelectMany </strong>must preserve. As the <em>source </em>for <strong>SelectMany</strong>, <strong>IEnumerable<T> </strong>represents an <strong>antecedent computation </strong>of values of type <strong>T</strong>, because each <strong>T </strong>must be computed before it can be projected. <strong>SelectMany</strong> iterates the <em>source</em>, invoking the <em>selector </em>function for each value of type <strong>T</strong>, and projecting it into <strong>IEnumerable<R></strong>. <strong>IEnumerable<R></strong> represents a <strong>subsequent computation</strong>, because it can be subsequently iterated to generate values of type <strong>R</strong>. To continue the computation sequentially, <strong>IEnumerable<R> </strong>can be used as the <em>source </em>for another call to <strong>SelectMany</strong>. Therefore, <strong>SelectMany </strong>implements <strong>sequential composition</strong>.</p>
<p><strong>IObservable<T></strong> represents a lazily-computed, asynchronous sequence of values of type <b>T</b>. It’s similar to <strong>IEnumerable<T></strong>, except asynchronous. And how do we consume an asynchronous sequence? Not by <em>foreach</em>, but by passing in a <em>continuation </em>(<strong>IObserver<T></strong>). The <strong>SelectMany </strong>operator for <strong>IObservable<T></strong> subscribes to the <em>source </em>with its own <strong>IObserver<T></strong>. Sequential composition is implemented by awaiting values pushed into the <strong>IObserver<T> </strong>and then pushing them as input into a subsequent computation, represented by <strong>IObservable<R></strong>. As far as sequential composition goes, it doesn’t actually matter that <strong>IObservable<T></strong> is asynchronous, because going from <strong>T </strong>to <strong>R</strong> remains sequential.</p>
<p><strong>IObservable<T></strong> is asynchronous because in order to get data out of it, you must pass in a function (a <em>continuation</em>) to be invoked later. It’s the so-called, “continuation passing style”, or CPS for short. Thus, <strong>IObservable<T></strong> is the continuation monad.</p>
<p>The <em>bind </em>operator enables us to write sequential composition in a declarative style. <strong>SelectMany </strong>sequentially composes two parts of our query, while hiding the imperative- or CPS-style mechanisms that are required to read values from the monadic type. We can think of a monadic type as a container of values, and <em>bind </em>lets us compose them without having to explicitly specify how to extract their values. We don’t have to use <strong>foreach</strong> for enumerables or call <strong>Subscribe </strong>for observables, until we want to leave the monad. That’s why we use <strong>foreach </strong>and <strong>Subscribe </strong>only at the ends of our LINQ queries.</p>
<p>This pattern works with more than just sequences. There are many types of monads; e.g., the “Maybe” monad implements null propagation, as <a href="https://blogs.msdn.microsoft.com/wesdyer/2008/01/10/the-marvels-of-monads/">Wes Dyer describes here, while introducing monads</a>. There’s a State monad that represents mutability in a pure functional language like Haskell, an I/O monad that represents input and output, also in Haskell, there’s the Reader monad for computing within an environment, similar to having global or static fields (you guessed it: Haskell), among others.</p>
<p>Monads provide a declarative programming model, but note the relation to imperative-style code. Two consecutive <em>from </em>clauses in a LINQ query is compiled into a single call to <strong>SelectMany</strong>. It’s like having a semicolon at the end of each line. The first <em>from </em>expression is evaluated, and then the second <em>from </em>expression is evaluated, with the value of the previous expression still in scope.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>from x in Xs //;</div><div>from y in getYs(x) //;</div><div>select (x, y)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>This query looks similar to our implementation of <strong>SelectMany </strong>for <strong>IEnumerable<T></strong>, which consisted of nested <strong>foreach</strong> loops! And in fact it works exactly the same, because this query simply compiles into a call to <strong>SelectMany</strong>.</p>
<p>A query is a single <em>expression</em> pieced together by applying a sequence of <em>operators</em>, rather than a series of statements that are pieced together by a sequence of semicolons. It’s the composability of the monad that enables us to write a query as a single expression, and it’s the expression syntax that makes the declarative programming style appear similar to the imperative style.</p>
<p>This style of programming is declarative because we can use operators like <strong>where</strong>, <strong>join </strong>and <strong>group by </strong>without sacrificing the readability of the program with all of those <strong>foreach </strong>loops that we’d need to write if we weren’t using the <em>list monad</em>, or all of those <em>continuations</em> that we’d need to write if we weren’t using the <em>continuation monad</em>.</p>
<p>Essentially, monads enable us to declare <strong>what</strong> we want the program to do rather than <strong>how</strong> the program should do it. The “how” part is hidden by the monad, and it differs between monads.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>from x in Xs</div><div>where x != null</div><div>from y in getYs(x)</div><div>join z in Zs on y.P equals z.P</div><div>select (x, y, z)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Is the above an interactive query over <strong>IEnumerable<T> </strong>or a reactive query over <strong>IObservable<T></strong>?</p>
<p>Or maybe it’s a hybrid? Perhaps <strong>Xs </strong>is an <strong>IObservable<T> </strong>and <strong>getYs </strong>returns an <strong>IEnumerable<T></strong>?</p>
<p>Each is a valid possibility. There’s no way of knowing by looking at the query alone!</p>
<p>The monadic pattern is a generalization on composition with embellishments, so it’s no surprise that queries over different types can look the same; however, some operators don’t make sense in some monads. For example, Rx defines the <strong>Sample(TimeSpan) </strong>operator for <strong>IObservable<T></strong> to sample elements by time, which only makes sense because <strong>IObservable<T> </strong>is asynchronous. Sampling by time doesn’t make sense in <strong>IEnumerable<T></strong> because it’s synchronous; however, enumerables do have the ability to sample elements by data; i.e., the <strong>Where </strong>operator. We can also sample elements by data in <strong>IObservable<T></strong>, thus Rx provides a similar <strong>Where </strong>operator.</p>
<blockquote>
<p>Essentially, a monad consists of an embellishing type and a function, <em>bind</em>, that preserves the embellishment through sequential composition.</p>
<p>A monad must also have a <em>unit </em>function, which enters the monad. For example, Rx provides <strong>Observable.Return </strong>(a.k.a., <strong>just</strong>).<sup><a href="#MCL_3">3</a></sup></p>
<p>Technically, a monad must also satisfy some simple <a href="https://wiki.haskell.org/Monad_laws">mathematical laws</a>: left identity, right identity and associativity. I won’t go into them here.</p>
</blockquote>
<p>Perhaps what makes monads seem mysterious and confusing is how such a simplistic functional trick can be so powerful as to warrant an entirely new syntax in languages like Haskell and C#. Are monads confusing because they mysteriously turn complex imperative-style code into a neat declarative-style code that looks eerily similar to imperative style? I’m confused even writing that question.</p>
<p>A comprehension syntax isn’t technically required, it just makes monads nicer to use! C# doesn’t have keywords for every useful operator, so most of the queries we write are in the form of fluent-method call syntax, whereby we chain operators together using dot notation and pass lambda expressions as function arguments.</p>
<p>For example, here’s the same query again written in fluent-method call syntax: </p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>Xs.Where(x => x != null)</div><div> .SelectMany(x => getYs(x).Select(y => (x: x, y: y)))</div><div> .Join(Zs, xy => xy.y.P, z => z.P, (xy, z) => (x: xy.x, y: xy.y, z: z));</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>It’s not great, although it’s probably how most languages use monads. Regardless, both syntaxes (comprehensions and fluent-method call) form declarative expressions. The comprehension syntax is often nicer though because it hides all of those lambdas and automatically broadens the scope of query variables; e.g., in the query comprehension written earlier, <em>x </em>is still in scope after <em>join</em>. The C# compiler accomplishes this simply by changing the type of <strong>T </strong>to a compiler-generated type that carries all of the variables in scope. We must do the same trick ourselves when writing in the fluent-method call syntax if we want to keep earlier values in scope. We typically do that by projecting anonymous types or tuples throughout our query, as I’ve done in the example above.</p>
<p>One last interesting thing to note about monads…</p>
<p>Because of its declarative nature, applying <em>bind</em> forms a lazily-evaluated <em>expression</em>, just like monads in lazily-evaluated functional programming languages. <strong>SelectMany </strong>and other operators<strong> </strong>do not cause any side effects when they are applied. They simply return a new instance of the monad, so that we may continue applying operators to build our computation. When we are ready for side effects, then we leave the monad and the computation may begin. How it begins depends on the purpose of the monadic type.</p>
<p><strong>IEnumerable<T></strong> requires code to pull each value through the composition, thus we use <em>foreach</em>.</p>
<p><strong>IObservable<T></strong> pushes values through the composition, once we’ve called <strong>Subscribe</strong>.</p>
<p>And that’s the mysterious monad. You can get deeper into the concept of monads in Category Theory, but I think that the essence of why they’re useful to us as programmers is described above.</p>
<p>All good, but monads are only half the story!</p>
<h1>If I Only Had a Codomain</h1>
<p>According to my chart at the beginning of this post, <strong>Task<T> </strong>is a comonad. Why?</p>
<p>If you don’t believe me, then we’ll try and disprove that claim by implementing <em>bind </em>for <strong>Task<T></strong>. If we can implement <em>bind</em>, then it’s probably a monad, right?</p>
<p>We already know how the signature for <em>bind </em>must look based on the pattern that we’ve identified above for enumerables and observables. They each have similar signatures. To go from the enumerable bind to the observable bind we must only do a monadic type replacement. So let’s grab the bind signature for <strong>IEnumerable<T> </strong>or <strong>IObservable<T> </strong>and simply replace the monadic type with <strong>Task</strong><strong><T></strong>:</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Task<R> SelectMany<T, R>(this Task<T> source, Func<T, Task<R>> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Looks good, no problems so far.</p>
<p>Since the <em>source</em> is a <strong>Task<T></strong>, it seems that we must invoke the <i>selector </i>function with the <b>T</b> that it contains.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Task<R> SelectMany<T, R>(this Task<T> source, Func<T, Task<R>> selector)</div><div> => selector(source.Result);</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Okay, that compiles, but it’s totally incorrect! Reading the <strong>Result </strong>property may block, and blocking isn’t <em>preserving the purpose </em>of <strong>Task<T></strong>. The purpose of <strong>Task<T></strong> is to represent the asynchronous computation of <strong>T</strong>. The <strong>SelectMany </strong>function must allow us to sequentially compose asynchronous computations, which means that we must be able to project a <strong>Task<T></strong> into a <strong>Task<R></strong> without blocking to read <strong>T</strong>. Essentially, <strong>SelectMany </strong>must return a lazily-evaluated expression, just like the implementations for <strong>IEnumerable<T></strong> and <strong>IObservabe<T></strong>.</p>
<p>Great, so how do we get the <strong>T </strong>out of the <strong>Task<T> </strong>asynchronously?</p>
<p>For the C# devs out there, our instinct is to define <strong>SelectMany </strong>as an <em>async </em>method and then <strong>await </strong><em>source</em>. And that may seem appropriate, but clearly <strong>await </strong>must be doing something under the covers in order to get the <strong>T </strong>from the <strong>Task<T></strong> without blocking. How does it do it? Whatever the C# compiler is doing for <strong>await</strong>, we must be able to do ourselves…</p>
<p>Well, the only way to get the result asynchronously is to pass a continuation to <strong>ContinueWith </strong>(a.k.a., <strong>then</strong>). But what is this strange method anyway? Let’s take a look at its signature (one overload in particular<sup><a href="#MCL_4">4</a></sup>).</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Task<R> ContinueWith<T, R>(this Task<T> source, Func<Task<T>, R> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Hmm, now that method looks familiar. Is it <em>bind</em>? Not quite. Here’s <em>bind </em>again: </p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Task<R> SelectMany<T, R>(this Task<T> source, Func<T, Task<R>> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>The type arguments in the <em>selector </em>function are reversed! Well, they are sort of reversed. The <strong>T </strong>and <strong>R </strong>type arguments remain in the same positions, but the generic <strong>Task </strong>type is in the opposite position. The <em>selector </em>function for <strong>ContinueWith</strong> has a <strong>Task </strong>parameter, rather than returning a <strong>Task</strong>.</p>
<p>So what is the selector in <strong>ContinueWith </strong>supposed to do?</p>
<p>Instead of being given a value and returning a new, embellished value, it’s given an embellished value and it has to return a new, unembellished value. In other words, it has to extract the value from the comonadic type inside the projection! This makes sense if we think of comonads (and monads) as containers in general.</p>
<p>And that’s how to safely (i.e., in a non-blocking manner) <em>extract </em>a value from <strong>Task<T></strong>. We must read the <strong>Result </strong>property only from within the <em>selector </em>(continuation) supplied to <strong>ContinueWith</strong>, in order to preserve the purpose of <strong>Task<T></strong>.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Task<R> SelectMany<T, R>(this Task<T> source, Func<T, Task<R>> selector)</div><div> => source.ContinueWith(task => selector(task.Result)).Unwrap();</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p><strong>Unwrap </strong>is also required, because <em>selector</em> returns <strong>Task<R></strong>, yet the <em>selector</em> in <strong>ContinueWith </strong>requires an <strong>R</strong>. So we make <strong>R </strong>a <strong>Task<R></strong>, thus <strong>ContinueWith </strong>returns <strong>Task<Task<R>>.</strong> <strong>SelectMany </strong>requires <strong>Task<R></strong>, so we must apply <strong>Unwrap </strong>one time to ditch the outer <strong>Task</strong>.</p>
<p>Recall that <em>bind </em>is a <em>flattening </em>projection (flat map; it’s like going from <strong>IEnumerable<IEnumerable<T>></strong> to <strong>IEnumerable<T></strong>), whereas here we’re using <strong>ContinueWith </strong>to compose over an <em>extending </em>projection (<strong>Task<R></strong> becomes <strong>Task<Task<R>></strong>). The concepts of <em>flattening </em>and <em>extending </em>are opposites. The <em>bind</em> and <em>cobind </em>functions are opposites; therefore, <strong>ContinueWith </strong>is <em>cobind.</em></p>
<p>Here, <strong>Unwrap </strong>is merely the <em>flattening </em>of our <em>bind </em>implementation. It’s how we convert our <em>cobind’s </em>extending projection into <em>bind’s </em>flattening projection.</p>
<p>The <strong>Task<T>.Result </strong>property (technically, the <strong>get_Result </strong>method) is the <em>extract </em>function of the <strong>Task<T></strong> comonad. The <em>extract </em>function is to <em>comonad </em>as the <em>unit </em>function is to <em>monad</em>. The <em>unit </em>function gets us into the monad, <em>extract </em>gets us out of the comonad. They are opposites!</p>
<p>And now we see why <strong>Task<T></strong> is a <em>comonad</em>, and not a <em>monad. </em>Another way of looking at: we can only implement <em>bind</em> in terms of <em>cobind</em>; i.e., we can’t implement <strong>SelectMany </strong>for <strong>Task<T> </strong>without calling <strong>ContinueWith</strong>.</p>
<p>Other than the comonadic laws (analogous to the <a href="https://wiki.haskell.org/Monad_laws">monad laws</a>), comonads are a triple consisting of a generic type, a <em>cobind </em>function and an <em>extract </em>function. Comonads are the opposite of monads, which are a triple consisting of a generic type, a <em>bind </em>function and a <em>unit </em>function.</p>
<p>As you can see from the code above, it’s fairly easy to convert from co<em>bind </em>to <em>bind</em>. Therefore, we can convert comonads into monads. We can also convert monads into comonads, although I’m not showing it here, but you can imagine that one indicator of a type being monadic rather than comonadic is that when implementing <em>cobind,</em> you’d discover that you must implement it in terms of <em>bind</em>. Try it for yourself.</p>
<p>A major reason that we don’t use <strong>Task<T></strong> as a monad is because its comonadic form lends itself naturally to a really useful compiler trick: <em>coroutines</em>. A <em>coroutine </em>is syntactic sugar that allows us to write imperative-style code for continuations, hiding the messy details of the underlying state machine that the compiler must generate. In C#, it’s known as <a href="https://msdn.microsoft.com/en-us/library/mt674882.aspx">async methods</a>. The <strong>await</strong> keyword essentially compiles into a call to <strong>ContinueWith</strong>.</p>
<p>Although we can’t use this compiler trick with monads directly, we can convert a monad into a comonad, and that’s exactly what Rx’s <strong>ToTask</strong> extension method does. But even better than that, Rx offers an extension method that implements C#’s awaitable pattern for <strong>IObservable<T></strong>, thus we can directly <strong>await </strong>an <strong>IObservable<T> </strong>to safely (i.e., in a non-blocking manner) <em>extract </em>the final value of the sequence. This works well for singleton observables, especially for aggregations like <strong>Sum </strong>and <strong>ToList</strong>.</p>
<p>Because C# has great support for <strong>async </strong>methods, it’s often recommended to use <strong>Task<T></strong> rather than <strong>IObservable<T> </strong>when your computation only has a single result; however, it appears that for a future release of Rx, Bart De Smet has implemented the new awaitable pattern in C# 7. We’ll be able to define <strong>async </strong>methods that directly return an observable rather than a <strong>Task<T></strong>. This is certainly not a replacement for <strong>Task<T></strong> in all async methods, but it may come in handy. To return an observable from an <strong>async </strong>method, we’ll have to use a new interface, <strong>ITaskObservable<T></strong>, which derives from <strong>IObservable<T></strong>. It’s just a small grammatical difference, perhaps. One neat thing about <strong>ITaskObservable<T></strong> is that it has singleton semantics; i.e., it only calls <strong>OnNext </strong>once, similar to the fact that <strong>Task<T> </strong>can only contain a single <strong>Result</strong>.</p>
<h1>Along The Yellow Brick Road…</h1>
<p>At the beginning of our journey we had asked the following questions: </p>
<blockquote>
<p>“Can we create a <i>cobind </i>function for <b>Lazy<T></b>? What would it look like? What would it do?”</p>
</blockquote>
<p>Along the way we’ve met <strong>IEnumerable<T></strong>, <strong>IObservable<T> </strong>and <strong>Task<T></strong>. Now we know how to proceed.</p>
<p>We’ll take the signature for <strong>Task<T>’s</strong> <em>cobind </em>function and replace all <strong>Task<T></strong> with <strong>Lazy<T>.</strong></p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Lazy<R> ContinueWith<T, R>(this Lazy<T> source, Func<Lazy<T>, R> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>We have a <strong>Lazy<T></strong> and a function that requires a <strong>Lazy<T></strong>, so should we apply it? (#WWEMD<sup><a href="#MCL_5">5</a></sup>)</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Lazy<R> ContinueWith<T, R>(this Lazy<T> source, Func<Lazy<T>, R> selector)</div><div> => selector(source);</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Sure, but what about the return value now? We have an <strong>R </strong>but we require a <strong>Lazy<R></strong>.</p>
<p>That’s simple. Let’s make the whole expression lazy by wrapping it in a new <strong>Lazy<R></strong>. That makes sense because we must <em>preserve the purpose </em>of <strong>Lazy<T></strong>, which is lazy initialization, right?</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Lazy<R> ContinueWith<T, R>(this Lazy<T> source, Func<Lazy<T>, R> selector)</div><div> => new Lazy<R>(() => selector(source));</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>When reading <strong>Lazy<R>.<strong>Value</strong></strong>, the <em>selector </em>will first extract the value of <strong>Lazy<T>, </strong>and with it compute <strong>R</strong>. In effect, <strong>Lazy<T></strong> isn’t evaluated until we attempt to evaluate <strong>Lazy<R></strong>, because <strong>Lazy<R> </strong>depends on <strong>Lazy<T></strong>.</p>
<p>Thus, laziness is preserved through composition.</p>
<p>How might our code look when using this <strong>ContinueWith </strong>implementation for <strong>Lazy<T></strong>?</p>
<p>Let’s first define a simple function named <strong>Create</strong> to take advantage of type inference. It’s just a bit more declarative than having to construct a <strong>Lazy<T></strong> ourselves and specify <strong>T </strong>explicitly.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static class Lazy</div><div>{</div><div> public static Lazy<T> Create<T>(Func<T> valueFactory)</div><div> => new Lazy<T>(valueFactory);
}</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Here’s a simple program that composes two lazy computations: </p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>var i = Lazy.Create(() => </div><div>{</div><div> Console.WriteLine("Initializing ‘i’");</div><div> return 42;</div><div>});</div><div><br />var d = i.ContinueWith(lazy => lazy.Value * 2);</div><div><br /></div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Notice that the construction of <strong>Lazy<T></strong> assigned to <em>d </em>is hidden by the <em>cobind </em>function. This is the declarative style of programming, and it appears the same in comonads as in monads.</p>
<p>Using <em>i </em>and <em>d </em>as defined above, what does the following console program print?</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>Console.WriteLine(i.IsValueCreated);</div><div>Console.WriteLine(d.IsValueCreated);
Console.WriteLine(d.Value);</div><div><br /></div><div>Console.WriteLine(i.IsValueCreated);</div><div>Console.WriteLine(d.IsValueCreated);
</div><div>
Console.WriteLine(i.Value);</div><div><br /></div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Scroll down to see the output…</p>
<p>.</p>
<p>.</p>
<p>.</p>
<p>.</p>
<p>.</p>
<p>.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>False<br />False</div><div>Initializing ‘i’<br />84<br />True
True<br />42</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Notice that <em>i.IsValueCreated</em> returns <em>False </em>at first, even though <em>d </em>is defined in terms of <em>i</em>.<em> </em>Invoking the <strong>ContinueWith </strong>function doesn’t cause any side effects, just like how applying <strong>SelectMany </strong>doesn’t cause any side effects for monads. We can build up a computation with <em>cobind </em>and evaluate it later; i.e., lazy evaluation.</p>
<p>When the program reads <em>d.Value</em>, then <em>i.Value </em>is initialized. Afterwards, <em>i.IsValueCreated </em>returns <em>True</em>, even though the program hasn’t read <em>i.Value </em>directly yet. That’s because <em>d </em>reads <em>i.Value </em>in its continuation, so evaluating <em>d </em>requires <em>i </em>to be evaluated as well. Evaluating the outermost <strong>Lazy<T> </strong>propagates the act of <em>evaluation </em>up to the source.</p>
<p>Finally, when the program reads <em>i.Value </em>at the end, notice that it’s not reinitialized. <strong>Lazy<T> </strong>caches the result of its factory function.</p>
<h1>We’re Off To See The Wizard</h1>
<p>Where does laziness come from? Is it something in the water?</p>
<p>No, it’s something in the <em>function</em>.</p>
<p>A function provides an identifiable name for a sequence of <em>statements </em>in the imperative style. Imperative style programming languages are eager, in that when a program encounters a statement, it’s evaluated immediately. That’s what <em>imperative </em>means. Therefore, laziness is achieved simply by wrapping statements in a function. A function may be evaluated at any time by invoking it, by name or delegate.</p>
<blockquote>
<p>A statement evaluates eagerly.</p>
<p>A statement in a function evaluates lazily.</p>
</blockquote>
<p>A lambda expression represents an anonymous function with a body consisting of a single statement. We bind a lambda expression to a named variable or parameter, and that becomes its name for the purpose of invoking it. A lambda expression isn’t evaluated at the site at which it’s defined, but at the site at which it’s invoked. Therefore, lambda expressions are lazily-evaluated. They are functions.</p>
<p>In a pure functional language like Haskell, a function consists of expressions, and expressions are interchangeable with values.<sup><a href="#MCL_6">6</a></sup> Replacing an expression with its value cannot be done safely in imperative-style languages because an expression may have side effects, and you’d expect those side effects to occur each time that the expression is evaluated. Evaluating a Haskell program is similar to reducing a mathematical expression into its simplest form, yet expressions in Haskell are, perhaps surprisingly, <a href="https://wiki.haskell.org/Lazy_evaluation">lazily evaluated</a>. Evaluation is deferred until an expression’s value is actually needed by the program. And once an expression has been evaluated, its value may replace every instance of that expression in the program. Perhaps expressions in Haskell are similar to <strong>Lazy<T> </strong>in C#?</p>
<p>So how is <strong>Lazy<T></strong> related to a function?</p>
<p>Well, the <strong>Lazy<T></strong> constructor turns a parameterless <em>function </em>into a type</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public Lazy(Func<T> valueFactory)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>that has a property</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public T Value { get; }</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>which is technically a parameterless function</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public T get_Value()</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>that has the same exact signature as <em>valueFactory</em>, the <strong>Func<T> </strong>that was used to construct the <strong>Lazy<T> </strong>instance in the first place.</p>
<p>So can we shake off the <strong>Lazy<T></strong> type and implement <strong>Func<T></strong> as a comonad?</p>
<p>Let’s try it. We’ll start with the signature of <strong>ContinueWith</strong> by simply replacing all <strong>Lazy<T></strong> with <strong>Func<T></strong>.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Func<R> ContinueWith<T, R>(this Func<T> source, Func<Func<T>, R> selector)</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>That’s wonderfully weird and magical looking. And for our next trick, the types will guide us…</p>
<p>We have a <strong>Func<T></strong>,<strong> </strong>and we have a function that takes a <strong>Func<T></strong> as its argument.</p>
<blockquote>
<p><strong>Note: </strong>A function with a function parameter is known as a <strong>higher order</strong> function. In this case, we’ve got two higher order functions: <strong>ContinueWith </strong>and <strong>selector</strong>.</p>
<p>Functions are given data as arguments.</p>
<p>Higher order functions are given functions as data.</p>
</blockquote>
<p>Let’s pass our <em>source </em>function to <em>selector</em>.</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Func<R> ContinueWith<T, R>(this Func<T> source, Func<Func<T>, R> selector)</div><div> => selector(source);</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Just like <strong>ContinueWith </strong>for <strong>Lazy<T></strong>, we notice that our return types don’t match. The <em>selector </em>function returns <strong>R</strong>, but we need a <strong>Func<R></strong>.</p>
<p>We must wrap the entire expression in another function!</p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Func<R> ContinueWith<T, R>(this Func<T> source, Func<Func<T>, R> selector)</div><div> => () => selector(source);</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Well, that was easy. It looks the same as the implementation for <strong>Lazy<T></strong>, but without a <strong>Lazy<R> </strong>wrapper. The outer function provides the laziness.</p>
<p>For comparison, here’s the <strong>Lazy<T> </strong>definition from above: </p>
<div class="syntaxhighlighter">
<table><tbody>
<tr>
<td class="code">
<div class="container">
<pre class="csharpcode"><div>public static Lazy<R> ContinueWith<T, R>(this Lazy<T> source, Func<Lazy<T>, R> selector)</div><div> => new Lazy<R>(() => selector(source));</div></pre>
</div>
</td>
</tr>
</tbody></table>
</div>
<p>Is the <strong>Func<T> </strong>comonad the same as the <strong>Lazy<T> </strong>comonad?</p>
<p>No, because <strong>Func<T></strong> will always compute a value when you invoke it, whereas <strong>Lazy<T> </strong>only computes its value once. Furthermore, <strong>Func<T></strong> may return a different value each time that it’s invoked (in a side-effecting language like C#, this is common.)</p>
<p>Therefore, <strong>Func<T> </strong>is lazy, but it may also cause side effects each time that you invoke it, whereas <strong>Lazy<T></strong> may only cause side effects once.</p>
<p>Should we use the <strong>Func<T></strong> comonad at all?</p>
<p>Probably not. It offers no real advantage compared to composing lambda expressions, although it does hide the closure (for better or worse). Perhaps <strong>Func<T> </strong>is the <em>closure </em>comonad? A blog post for another day.</p>
<h1>Meet The Lazy Wizard</h1>
<p>The laziness of <strong>Lazy<T></strong> is related to the idea that applying <em>co/bind </em>forms a lazily-evaluated expression.</p>
<p>We can declare computations over <strong>IEnumerable<T></strong> and <strong>IObservable<T></strong> that are lazy; i.e., there are no computational side effects until we iterate or subscribe, respectively. And likewise for <strong>Task<T></strong>, we can compose together many <strong>ContinueWith </strong>calls without causing any side effects; that is, until the <strong>Task<T></strong> completes. There’s obviously a race condition here, but the point is that <strong>ContinueWith </strong>doesn’t block. <strong>ContinueWith </strong>forms a lazily-evaluated computation, although it’s possible that <strong>Task<T>.<strong>Result </strong></strong>was already computed before <strong>ContinueWith</strong> was applied, which may result in the continuation executing synchronously.<sup><a href="#MCL_7">7</a></sup></p>
<p>And so it goes for <strong>Lazy<T></strong>. The purpose of <strong>Lazy<T> </strong>is simply <em>lazy evaluation</em>. That’s what <strong>ContinueWith</strong><em> </em>needs to preserve across compositions; although, it’s possible that the lazy value may have already been computed by the time the program attempts to extract it. Just like <strong>Task<T>.Result</strong>, once it’s computed, we can keep reading <strong>Lazy<T>.Value </strong>over and over again without recomputing it. We can even build new computations on top. In the case of <strong>Lazy<T></strong>, a new computation over a pre-computed value would simply reuse the pre-computed value as the source for the new computation, without having to reevaluate the original source; i.e., <a href="https://en.wikipedia.org/wiki/Memoization">memoization</a> of a parameterless function. This is illustrated in the code example above with the explicit call to <em>i.Value </em>at the end of the program: the side effect of writing to the console upon initializing <em>i.Value </em>had already occurred earlier in the program, and it’s not repeated again at the end.</p>
<p>All of these co/monadic types are lazy, but they also differ in behavior when it comes to laziness. The laziness of <strong>Lazy<T> </strong>and <strong>Task<T></strong> isn’t permanent, it’s a one-time use. The laziness of <strong>IObservable<T> </strong>and <strong>IEnumerable<T> </strong>is potentially repeatable.</p>
<p>To put it another way: <strong>Lazy<T></strong> and <strong>Task<T> </strong>cache their value to avoid duplicating side effects, whereas <strong>IObservable<T> </strong>and <strong>IEnumerable<T> </strong>may cause side effects each time that they are “invoked”. I smell a pattern.</p>
<h1>Pulling Back The Curtain</h1>
<p>Lurking in the shadows, as usual, are <em>side effects</em>. Being able to control side effects is a major benefit of having these co/monadic constructs in C#.</p>
<p>The point of <strong>Lazy<T></strong> is to ensure that any side effects only occur once, when computing a single value of <strong>T</strong>. That’s why <strong>Lazy<T> </strong>is often used to represent a static singleton in C#. If computing the value causes side effects, then we don’t want to compute the value until it’s actually needed by the program. And once it’s been computed, we don’t want to repeat the computation. Of course, there are other reasons to have singletons, but using a <em>static readonly </em>field without <strong>Lazy<T> </strong>is generally good enough for most singletons. It’s only when we want to defer side effects that we use <strong>Lazy<T></strong> instead.</p>
<p>A synchronous sequence of values is similar to <strong>Lazy<T> </strong>but with a larger cardinality: <strong>Lazy<T> </strong>only has a single <strong>Value</strong>, whereas <strong>IEnumerable<T></strong> has many. But there’s another significant difference: <strong>IEnumerable<T></strong> doesn’t necessarily cache its results. Each time that you iterate, you may get different values. Furthermore, an enumerable query is a computation that may have its own side effects regardless of whether the source <strong>IEnumerable<T></strong> caches its results or not, but those side effects aren’t realized until you iterate it.</p>
<p><strong>Task<T></strong> represents an asynchronous function that eventually computes a <strong>Result</strong>. We use <strong>Task<T></strong> to avoid duplicating the side effects of an asynchronous computation. Once it completes, subsequent reads of the <strong>Result </strong>property will always return the same value, thus side effects won’t occur again. If we actually want to repeat the side effects, then we must invoke the async function again, which will return a new instance of <strong>Task<T></strong>.</p>
<p>An asynchronous sequence of values is similar to <strong>Task<T> </strong>but with a larger cardinality: <strong>Task<T> </strong>only has a single <strong>Result</strong>, whereas <strong>IObservable<T></strong> has many. But there’s another significant difference: <strong>IObservable<T></strong> doesn’t necessarily cache its results. Each time that you <strong>Subscribe</strong>, you may get different notifications. Furthermore, an observable query is a computation that may have its own side effects regardless of whether the source <strong>IObservable<T></strong> caches its notifications or not, but those side effects aren’t realized until you <strong>Subscribe</strong>.</p>
<p>Side effects are related to <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">temperature</a>:</p>
<blockquote>
<p><em>Cold </em>means that side effects may occur.</p>
<p><em>Hot </em>means that side effects do not occur.</p>
</blockquote>
<p>So how does the laziness of co/monads relate to temperature?</p>
<p>Let’s consider the properties of the <em>types</em> of the co/monads separately from their <em>co/bind </em>implementations.</p>
<p>The <strong>Func<T></strong> <em>type </em>may return a different value each time that it’s invoked, and that’s the <em>cold </em>programming model. Therefore, functions are <em>cold</em>.</p>
<p>The <strong>Func<T></strong> <em>comonad</em> described above defers side effects until the outer-most function is invoked. That’s also the <em>cold</em> programming model, and essentially its purpose. The <strong>Func<T> </strong>comonad composes functions lazily. But it’s also pointless, given that <strong>Func<T> </strong>is already <em>cold</em>. The <strong>Func<T> </strong>comonad simply adds an unnecessary layer of <em>cold </em>indirection.</p>
<p>The <strong>Lazy<T> </strong><em>type </em>is initially <em>cold</em>, because it defers side effects until its <strong>Value </strong>property is read, yet it becomes <em>hot </em>for subsequent reads of the <strong>Value </strong>property. In other words, the first time that <strong>Value </strong>is read it may cause side effects, but subsequent reads definitely will not. (There’s also a race condition if <strong>Value </strong>may be read by multiple threads simultaneously, but that's similar to <strong>Task<T>.Result</strong>, so let’s address the race condition in our analysis of <strong>Task<T> </strong>that follows.)</p>
<p>The <strong>Lazy<T> </strong><em>comonad </em>is initially <em>cold</em>, because <em>cobind </em>defers side effects until the outer-most <strong>Value </strong>property is read, yet it becomes <em>hot </em>for subsequent reads of the outer-most <strong>Value </strong>property.</p>
<p>The <strong>Task<T> </strong><em>type </em>is initially <em>cold</em>, because it can be constructed by passing in a function and it defers side effects until its <strong><a href="https://msdn.microsoft.com/en-us/library/dd270682(v=vs.110).aspx">Start</a></strong> method is called; however, it can only be executed once. Calling <strong>Start</strong> again throws an exception. Furthermore, the <strong>Task<T>.Result </strong>property is always <em>hot</em>; therefore, <strong>Task<T></strong> transitions to <em>hot </em>when <strong>Start </strong>is called.</p>
<p>However, it’s rare to acquire a <strong>Task<T></strong> that hasn’t already been started. Typically we use <strong>Task.Run</strong>, <strong>Task.Factory.StartNew</strong>,<strong> </strong>or invoke some BCL or user-defined function that returns a <strong>Task<T></strong>. In these cases, <strong>Start </strong>has already been invoked, thus the computation may have already begun even before the caller acquires a reference to the <strong>Task<T></strong>. The caller can’t invoke <strong>Start </strong>again, and reading the <strong>Result </strong>property never causes side effects, thus our typical usage of <strong>Task<T></strong> is <em>hot</em>, yet the <strong>Task<T> </strong><em>type </em>itself is technically <em>cold.</em> In other words, notice that we typically acquire an instance of <strong>Task<T> </strong>by invoking a function that returns it. Functions are <em>cold</em>, as stated previously. Therefore, each time that we invoke a function that performs an asynchronous computation, it may return a new instance of <strong>Task<T> </strong>to represent its <strong>Result</strong>, which is always <em>hot</em>. Invoking the function is essentially like invoking the <strong>Start </strong>method yourself. In that case, <strong>Task<T></strong> is <em>hot </em>because it has already been started by the function that returned it, yet the <strong>Task<T> </strong><em>type </em>itself is technically <em>cold </em>because it must be started at some point.</p>
<p>Alternatively, there’s another way to get an instance of <strong>Task<T></strong> (a.k.a., “future”): use a <strong>TaskCompletionSource<T> </strong>(a.k.a., “promise”). <strong>TaskCompletionSource<T></strong> replaces the need to call <strong>Start </strong>by essentially making the <strong>Result </strong>property assignable. The <strong>Task<T> </strong>that it returns is <em>hot </em>because it’s constructed without a function (via an internal constructor), thus it has no computation to be deferred. A consumer of the <strong>Task<T></strong> is unable to call <strong>Start</strong>, thus it’s unable to cause side effects, and so this usage of <strong>Task<T> </strong>is <em>hot</em>. This doesn’t change the fact that the <strong>Task<T> </strong><em>type </em>itself is <em>cold</em>, at least as far as its public API is concerned. The <em>promise </em>mechanism is useful because it decouples the two features of a <em>future:</em> It separates its ability to defer a computation from its ability to compute asynchronously; i.e., <strong>TaskCompletionSource<T> </strong>makes <strong>Task<T> </strong><em>hot </em>without having to begin a computation by calling <strong>Start</strong>. Instead, the computation occurs externally and terminates when <strong>Result </strong>is assigned (or the task faults, or it’s canceled – but we’ll ignore these states for the purposes of this analysis).</p>
<p>The <strong>Task<T></strong> <em>comonad</em> is initially <em>cold</em>, because <em>cobind </em>defers side effects until the <strong>Task<T></strong> completes. It’s <em>cold </em>because the continuation is a function, and functions are <em>cold</em>. However, it becomes <em>hot </em>once the <strong>Task<T> </strong>completes. If you apply <strong>ContinueWith </strong>after the <strong>Task<T> </strong>has completed, then it may execute the continuation synchronously. There’s a race condition.</p>
<p>Therefore, the <strong>Lazy<T> </strong>and <strong>Task<T></strong> <em>types </em>have the same temperature and similar behavior; i.e., they are both initially <em>cold </em>and then transition to <em>hot </em>by caching their value, which avoids duplicating side effects. <strong>Lazy<T>.Value</strong> blocks until its computation has completed; likewise, <strong>Task<T>.Result</strong> blocks until its computation has completed. The difference between them is that <strong>Lazy<T> </strong>computes its <strong>Value </strong>synchronously, and <strong>Task<T></strong> computes its <strong>Result </strong>asynchronously. This means that to extract the <strong>Value </strong>from <strong>Lazy<T></strong>, a program must block. To extract the <strong>Result </strong>from <strong>Task<T></strong>,<strong> </strong>a program can do other things while <strong>Result </strong>is being computed. Since the only purpose of <strong>Lazy<T> </strong>is to defer its computation of <strong>Value</strong>, it doesn’t make sense to have a method like <strong>Run</strong>; it would simply block until <strong>Value </strong>has been computed, thus defeating the purpose of <strong>Lazy<T></strong>. Since the purpose of <strong>Task<T></strong> is asynchrony, in addition to deferring its computation of <strong>Result</strong>, it’s actually useful to hide its <em>coldness </em>behind a function that returns a <em>hot</em> <strong>Task<T></strong>.</p>
<p>As comonads, both <strong>Lazy<T> </strong>and <strong>Task<T></strong> are initially <em>cold</em>, yet they become <em>hot </em>once their value has been computed. In the case of <strong>Lazy<T></strong>, <em>cobind </em>is synchronous (it blocks until <strong>Value </strong>is computed), whereas for <strong>Task<T></strong>, <em>cobind </em>is asynchronous (it doesn’t block, although it may execute the continuation synchronously when <strong>Result </strong>has already been computed and the <a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcontinuationoptions(v=vs.110).aspx">ExecuteSynchronously</a> flag was set). In either case, the transition from <em>cold </em>to <em>hot </em>means that there’s a race condition.</p>
<blockquote>
<p>Therefore, comonads and their comonadic types are <em>cold</em>, which is the definition of deferred execution. In addition, comonads that transition from <em>cold </em>to <em>hot </em>have a race condition.</p>
</blockquote>
<p>The <strong>IEnumerable<T> </strong><em>type </em>is either <em>cold</em>, as in C# Iterator Blocks, or it’s <em>hot</em>, as in pre-computed lists and dictionaries.</p>
<p>The <strong>IEnumerable<T> </strong><em>monad </em>is <em>cold</em>, because <em>bind </em>defers side effects until the enumerable that it returns is iterated. This is true even if the <strong>IEnumerable<T></strong> that is the source of the computation is <em>hot</em>. Although no side effects will occur when iterating a <em>hot </em>enumerable such as a <strong>List<T></strong>, the computation itself (a.k.a., the query) may cause side effects when it’s iterated, and it can only cause side effects when it’s iterated.</p>
<p>The <strong>IObservable<T> </strong><em>type </em>is either <em>cold</em>, as in Rx generators like <strong>Return</strong>, <strong>Range</strong>, <strong>Generate</strong>, <strong>Timer</strong>, <strong>Interval </strong>and <strong>Create</strong>, or it’s <em>hot</em>, as in <strong>Subject<T></strong>, <em>events </em>and <em>hot </em><strong>Task<T> </strong>conversions.</p>
<p>The <strong>IObservable<T> </strong><em>monad</em> is <em>cold</em>, because <em>bind </em>defers side effects until an observer subscribes to the observable that it returns. This is true even if the<strong> IObservable<T></strong> that is the source of the computation is <em>hot</em>. Although no side effects will occur when subscribing to a <em>hot </em>observable such as a <strong>Subject<T></strong>, the computation itself (a.k.a., the query) may cause side effects when an observer subscribes, and it can only cause side effects when an observer subscribes. Furthermore, due to the asynchrony of <strong>IObservable<T></strong>, some interesting and useful combinations of <em>cold </em>and <em>hot </em>temperatures are also possible. (See <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">Hot and Cold Observables</a> for details.)</p>
<p>Therefore, the <strong>IEnumerable<T> </strong>and <strong>IObservable<T> </strong><em>types </em>can either be <em>cold </em>or <em>hot</em>, and they have similar behaviors; i.e., they both represent sequences, which may or may not cause side effects when computing their elements. The difference between them is asynchrony. <strong>IEnumerable<T></strong> computes its elements synchronously. <strong>IObservable<T> </strong>computes its elements asynchronously. This means that to pull the next value from an <strong>IEnumerable<T></strong>, a program must block. To be pushed values from an <strong>IObservable<T></strong>, a program calls <strong>Subscribe </strong>and can immediately do other things. In either case, iterating an <strong>IEnumerable<T> </strong>or subscribing to an <strong>IObservable<T> </strong>doesn’t necessarily cause side effects. It depends on the implementation; e.g., <strong>List<T> </strong>does not cause side effects, so it’s <em>hot</em>. An <strong>Iterator Block </strong>may cause side effects, to it’s <em>cold</em>. <strong>Observable.FromEventPattern </strong>returns an observable that wraps an event, which is <em>hot</em>. <strong>Observable.Range </strong>generates notifications each time that you subscribe, so it’s <em>cold</em>.</p>
<p>As monads, both <strong>IEnumerable<T> </strong>and <strong>IObservable<T> </strong>are initially <em>cold</em>. Applying <em>bind </em>on an <strong>IEnumerable<T> </strong>or <strong>IObservable<T></strong> won’t cause any side effects until it’s iterated or subscribed, respectively. However, depending upon the implementation, they may or may not transition to <em>hot</em>.</p>
<blockquote>
<p>Therefore, monads are <em>cold </em>regardless of the temperature of their types, which is the definition of deferred execution. In addition, monads that transition from <em>cold </em>to <em>hot </em>have a race condition.</p>
</blockquote>
<p>Monads and comonads have identical temperatures with regard to composition – they are both <em>cold</em>. Therefore, consecutively applying co/monadic operators is free of side effects. Co/bind implements deferred execution, such that side effects won’t occur until you leave the co/monad.</p>
<h1>There’s No Place Like Home</h1>
<p>We use monads and comonads to control side effects. It’s the purpose of the property of <em>laziness </em>in <em>co/bind</em>. Co/monads allow us to write queries declaratively, without causing side effects. We control when side effects may occur by reading/invoking/iterating/subscribing at a later time.</p>
<p><strong>Lazy<T> </strong>is a comonad with the purpose of causing side effects only once, attached to a blocking computation. The <strong>Func<T> </strong>comonad is even closer to the metal in that it represents repeatable side effects; although, perhaps it’s not very useful as a comonad.</p>
<p><strong>Task<T> </strong>is a comonad with the purpose of causing side effects only once, attached to an asynchronous computation. However, the laziness of <strong>Task<T> </strong>is subtle. Due to a race condition that is common in the <strong>Task<T></strong> implementation of cobind, we must either live with side effects possibly occurring immediately (although asynchronously in general), or we can build our computation on a <em>promise </em>(<strong>TaskCompletionSource</strong>) and glue it to the <em>future </em>(<strong>Task<T></strong>)<strong> </strong>when the program is ready for side effects. One really nice way of doing that is to define a coroutine; a.k.a., an <strong>async </strong>method in C#. An <strong>async </strong>method let’s you <strong>await </strong>a <strong>Task</strong> within the imperative style of programming, meaning that typical control flow constructs are allowed without having to resort to implementing a complex state machine over CPS (because the compiler does it for you). Upon the first <strong>await</strong>, if the <strong>Task </strong>didn’t complete synchronously, then a <em>promise </em>is returned to the caller of the <strong>async </strong>method and the remainder of the computation from that point is referenced in a continuation that is attached to the <strong>Task </strong>via <em>cobind</em>. Side effects of the downstream computation can be controlled easily by simply holding the <strong>Task </strong>rather than applying <strong>await</strong>. The program can apply <strong>await </strong>at any time in the future to continue the computation with its <strong>Result</strong>. The race condition, in this case, is irrelevant.</p>
<p><strong>IEnumerable<T></strong> is a monad with the purpose of causing repeatable side effects, attached to a blocking computation.</p>
<p><strong>IObservable<T></strong> is a monad with the purpose of causing repeatable side effects, attached to an asynchronous computation.</p>
<p>Even though a sequence may be <em>hot</em> or <em>cold</em>, applying the <em>bind </em>operator (or any operator) itself doesn’t cause any side effects, until the sequence is iterated/subscribed. Furthermore, an operator may cause side effects each time that its return value is iterated/subscribed. The monadic <em>bind </em>function is about repeatable side effects, regardless of the temperature of its monadic type.</p>
<p>In conclusion:</p>
<blockquote>
<p>Comonads represent lazy computations of single values, are initially <em>cold, </em>and transition to <em>hot </em>when the computation completes.</p>
<p>Monads represent lazy computations over zero or more values, depending on the type. They are initially <em>cold</em>, and may transition from <em>cold </em>to <em>hot</em>, depending on the type.</p>
</blockquote>
<p>And why is any of this important?</p>
<p>Because a language like C# is full of side effects. Being able to introduce side effects so easily is often what makes C# really useful, but it’s also what makes many C# programs really confusing and buggy.</p>
<p>Controlling side effects in a declarative manner makes programs much easier to reason about, and to prove correctness. Although, some parts of a program are just much easier to write using imperative side effects.</p>
<p>Therefore, the careful combination of declarative and imperative styles within the same program is often the best choice. Functions generally help with the former, as in the procedural programming style. Monads also help with the former, computing over sequences in a declarative style. Comonads (via coroutines) generally help with the latter, when single-valued asynchronous computations are required.</p>
<p>These techniques are becoming even more important as modern programs increasingly depend on concurrency.</p>
<h2>References</h2>
<ul>
<li>The original Rx team’s videos and Erik Meijer’s papers – just search for this stuff online, it’s all great. </li>
<li><a href="https://bartoszmilewski.com">Bartosz Milewski’s Blog</a> and his <a href="https://www.youtube.com/user/DrBartosz/videos">YouTube channel</a> on Category Theory </li>
<li><a href="https://blogs.msdn.microsoft.com/wesdyer/2008/01/10/the-marvels-of-monads/">Wes Dyer’s Blog – The Marvels of Monads</a> </li>
<li><a href="https://ericlippert.com/category/monads">Eric Lippert’s Blog – Monads</a></li>
</ul>
<h2>Notes</h2>
<ol>
<li><a name="MCL_1"></a>The name of <b>SelectMany</b> is similar to the name of the <b>Select</b> operator, which is the same as the <b>SELECT</b> operator in SQL. Likewise, the <b>Where</b> operator in LINQ is named the same as the <b>WHERE</b> operator in SQL, and so on. When LINQ was invented, apparently the designers had chosen SQL-like names for the operators to make developers more comfortable. Most developers were used to SQL, but didn't have a clue about monads. And this naming convention works of course because <a href="http://queue.acm.org/detail.cfm?id=2338507">SQL is a monadic comprehension syntax</a>!</li>
<li><a name="MCL_2"></a>The C# compiler actually looks for a special signature of a method named <b>SelectMany</b> rather than the one shown above. It must have an intermediate selector parameter in addition to the result selector. It's just a performance optimization and so I won’t elaborate on it here. </li>
<li><a name="MCL_3"></a>Rx actually provides several generators, including <strong>Range</strong>, <strong>Generate</strong>, <strong>Timer</strong>, <strong>Interval </strong>and <strong>Create</strong>. There are many ways to enter the continuation monad. Likewise, there are many ways to enter the list monad, <strong>IEnumerable<T></strong>, because there are many types that implement <strong>IEnumerable<T>.</strong> And C# offers another option: <em>Iterator Blocks</em>. </li>
<li><a name="MCL_4"></a>The FCL implementation of <b>ContinueWith</b> is defined as an instance method. Here, I’ve rewritten it as an extension method and renamed its parameters, for parity with the <b>SelectMany</b> method. Other than those insignificant changes, it remains identical to the definition in the FCL. </li>
<li><a name="MCL_5"></a>What Would Erik Meijer Do?   <a title="https://twitter.com/headinthebox/status/543919077752729600" href="https://twitter.com/headinthebox/status/543919077752729600">https://twitter.com/headinthebox/status/543919077752729600</a> </li>
<li><a name="MCL_6"></a><a title="https://wiki.haskell.org/Referential_transparency" href="https://wiki.haskell.org/Referential_transparency">https://wiki.haskell.org/Referential_transparency</a> </li>
<li><a name="MCL_7"></a>The TPL doesn’t invoke continuations synchronously unless you opt-in, and even then it’s not guaranteed. For the most part, the TPL is designed to introduce concurrency. This is in contrast to the design of Rx, which is free-threaded and rarely introduces concurrency. Operators introduce concurrency when you explicitly specify a concurrency-introducing scheduler, although operators that involve some kind of timing may default to a concurrency-introducing scheduler if you don’t pass in one; e.g., <strong>Throttle</strong>, <strong>Sample</strong>, <strong>Buffer</strong>, etc. This is because Rx is primarily about taming concurrency, not introducing it.</li>
</ol>
https://davesexton.com/blog/post/monads-and-comonads-and-linq-oh-my.aspx
https://davesexton.com/blog/post/monads-and-comonads-and-linq-oh-my.aspx#commenthttps://davesexton.com/blog/post.aspx?id=69a4dfbc-7152-48f0-9bcf-3c90ed3ae06fWed, 19 Apr 2017 23:19:00 +0000AsyncC#PatternsRxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=69a4dfbc-7152-48f0-9bcf-3c90ed3ae06f3https://davesexton.com/blog/trackback.axd?id=69a4dfbc-7152-48f0-9bcf-3c90ed3ae06fhttps://davesexton.com/blog/post/monads-and-comonads-and-linq-oh-my.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=69a4dfbc-7152-48f0-9bcf-3c90ed3ae06fReactive Reactive! Read all about it!<p>Like the late 1800's American newspaper boy used to shout, in this blog post we'll be taking a look at something "extra" in Rx.</p> <h1>Reactive Reactive</h1> <p>Nope, it's not a typo.</p> <p>It’s like <em>acceleration</em> to <em>speed</em>, or <em>C#</em> to <em>IL</em>, or <em>higher-order functions</em> to <em>functions</em>.</p> <p>Sometimes fast isn't fast enough. Sometimes abstract isn't abstract enough. Sometimes functions aren't... functiony enough?</p> <p>Sometimes Rx operators aren’t <em>reactive</em> enough.</p> <p>Many operators in Rx force us to supply static arguments, resulting in an operator's static behavior. By <em>static</em> I mean upfront, immutable, unvarying values; e.g., typically scalar primitives like <strong>Int32</strong>, <strong>TimeSpan</strong> and <strong>DateTimeOffset</strong>. Furthermore, stateful operators with static parameters prevent us from varying behavior without a potential loss of data.</p> <p>Here's a simple example of a stateful operator with a scalar parameter. Let's say that we have an observable and we want to skip the first 5 notifications:</p> <pre class="brush: csharp;">var xs = observable.Skip(5);</pre>
<p>That's great, but what if we don't know how many notifications we want to skip yet? Or what if we want to change that value later while the observable is active?</p>
<p><strong>Defer</strong> doesn't work if we want to subscribe <em>now</em>.</p>
<p>We could attempt to change the value, without causing side effects, by writing some complicated dance within the <strong>Publish</strong> operator involving subscriptions, disposing, recreating the query and resubscribing; however, we'll lose the state within the operator that tells us how many values have already been skipped. We could keep track of the number that have already been skipped ourselves, but then what's the point of the <strong>Skip</strong> operator?</p>
<p>Ok, easy solution, we define a new overload:</p>
<pre class="brush: csharp;">public static IObservable<T> Skip<T>(this IObservable<T> source, IObservable<int> count);</pre>
<p>Now we can change the count at any time without resubscribing and without losing any state. We'll simply push in a new value through <em>count</em> whenever we want to change it.</p>
<p>Subscribe now, decide later.</p>
<p>Maybe we'll never push in a value and so everything will be skipped. Maybe we'll push in a value of 10 before the first 10 notifications have been skipped, thus only the first 10 notifications will be skipped. Maybe we change our minds and push in a value of 5, but it's too late – we've already skipped the first 7 notifications, thus only the first 7 notifications are skipped. At this point, the operator unsubscribes from <em>count</em>.<sup><a href="#ReactiveReactive_1">1</a></sup></p>
<p>But wait, are the values in <em>count</em> even necessary anymore? It seems overly complicated. Can't we just generalize our solution in terms of <em>time</em>?</p>
<pre class="brush: csharp;">public static IObservable<T> SkipUntil<T, U>(this IObservable<T> source, IObservable<U> other);</pre>
<p>In other words, instead of an <em>observable count</em>, we'll simply use an <em>observable</em>. <strong>T</strong> is ignored. When the <em>observable</em> signals or terminates, the operator stops skipping.</p>
<p>This "reactive reactive" pattern is already in use by several operators in Rx, such as <strong>SkipUntil </strong>and <strong>TakeUntil</strong> as of Rx 1.0, and some overloads of <strong>Window</strong>, <strong>Buffer</strong>, <strong>Throttle</strong>, <strong>Sample</strong>, <strong>Delay </strong>and <strong>Timeout</strong> as of Rx 2.0, but upon further inspection it seems that Rx is potentially missing a lot of similar opportunities.</p>
<p><strong>Reactive Overloads for Static Parameters</strong>
<br><a href="https://github.com/Reactive-Extensions/Rx.NET/issues/18">https://github.com/Reactive-Extensions/Rx.NET/issues/18</a></p>
<h2>Merge – A Case Study</h2>
<p>In one such example, we can see how data loss is a critical problem. The <em>Merge(maxConcurrency)</em> operator is very powerful, but its behavior is static. While inner observables are pushed in, <strong>Merge</strong> subscribes to them until maximum concurrency is reached, at which point any observables received are enqueued for later. Often these observables capture non-recoverable application state. To change the maximum level of concurrency in response to the changing capabilities of the environment requires disposing of the subscription to <strong>Merge</strong>'s observable, reforming the query with a new static argument and resubscribing; however, in the process any observables enqueued by <strong>Merge</strong> are lost, and their captured application state is lost along with them.</p>
<p><strong>Merge with Dynamic Maximum Concurrency</strong>
<br><a href="https://github.com/Reactive-Extensions/Rx.NET/issues/48">https://github.com/Reactive-Extensions/Rx.NET/issues/48</a>
<br><a title="https://social.msdn.microsoft.com/Forums/en-US/62743ffd-befd-474a-8f0a-19dbaec7a926/design-question-throttling-hits-on-external-systems" href="https://social.msdn.microsoft.com/Forums/en-US/62743ffd-befd-474a-8f0a-19dbaec7a926/design-question-throttling-hits-on-external-systems">https://social.msdn.microsoft.com/Forums/en-US/62743ffd-befd-474a-8f0a-19dbaec7a926/design-question-throttling-hits-on-external-systems</a></p>
<h1>Conclusion</h1>
<p>By providing a full suite of <em>reactive/reactive</em> overloads for Rx operators, developers would be enabled to write queries that adjust the behavior of operators dynamically based upon dynamic application state, user input and/or heuristics about the runtime environment to improve the performance of their applications, without losing data and without the costs of having to repeatedly solve similar problems themselves.</p>
<p> </p>
<ol>
<li><a name="ReactiveReactive_1"></a>One could also imagine the next logical scenario in which we raise the value back to 10, thus perhaps the first 7 notifications and the 9th and 10th notifications are skipped, but the 8th notification makes it through. Although these semantics are interesting, they're not the semantics of the <strong>Skip</strong> operator. <strong>Skip </strong>is all about skipping consecutive notifications from the beginning of the sequence. I'm not saying that these semantics aren't useful, it just seems more like the behavior of the <strong>Sample</strong> operator to me and surely a similar analysis applies to that operator. </li>
</ol>
https://davesexton.com/blog/post/Reactive-Reactive-Read-all-about-it.aspx
https://davesexton.com/blog/post/Reactive-Reactive-Read-all-about-it.aspx#commenthttps://davesexton.com/blog/post.aspx?id=d9b0f3a3-3387-48f4-b5bb-486cc2819b79Fri, 10 Oct 2014 17:23:00 +0000Rxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=d9b0f3a3-3387-48f4-b5bb-486cc2819b790https://davesexton.com/blog/trackback.axd?id=d9b0f3a3-3387-48f4-b5bb-486cc2819b79https://davesexton.com/blog/post/Reactive-Reactive-Read-all-about-it.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=d9b0f3a3-3387-48f4-b5bb-486cc2819b79I'm On Twitter<p>Just thought I'd mention that I'm attempting to be a bit less antisocial.</p><p><a href="https://twitter.com/IDaveSexton" target="_blank">Follow me on Twitter @IDaveSexton</a></p><p>Recently, I noticed that I've been getting traffic to my website from Twitter and so I've finally decided to see what it's all about. I have to say that I'm actually enjoying the experience of subscribing to interesting people and reading my customized stream each day.</p><p>Still, though, I'd rather be coding.</p>
https://davesexton.com/blog/post/i-m-on-twitter.aspx
https://davesexton.com/blog/post/i-m-on-twitter.aspx#commenthttps://davesexton.com/blog/post.aspx?id=57bec76f-01b8-4a80-b67e-143f103f49f2Sun, 28 Sep 2014 07:10:00 +0000davehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=57bec76f-01b8-4a80-b67e-143f103f49f20https://davesexton.com/blog/trackback.axd?id=57bec76f-01b8-4a80-b67e-143f103f49f2https://davesexton.com/blog/post/i-m-on-twitter.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=57bec76f-01b8-4a80-b67e-143f103f49f2Reactive Extensions: The Power of T<p>The <strong>T </strong>in <strong>IObservable<T></strong> is more powerful than you may realize.</p><h1>Structural T</h1><blockquote class="bar" style="margin-right: 0px;" dir="ltr"><p><strong>T</strong> carries <em>data,</em> its most obvious purpose.</p></blockquote><p><strong>T</strong> can be any type, such as <strong>Int32</strong>, <strong>String</strong> or <strong>MyAmazingObject</strong>.</p><p><strong>T </strong>can be <em>void</em>, as in <a href="http://msdn.microsoft.com/en-us/library/system.reactive.unit.aspx" target="_blank">System.Reactive.Unit</a>.</p><p><strong>T </strong>can be <em>anonymous</em>, as in: <em><a href="http://msdn.microsoft.com/en-us/library/bb397696.aspx">new { Value = "T", Awesome = true }</a></em></p><p><strong>T </strong>can be a <em>choice</em>, as in <a href="https://rxx.codeplex.com/discussions/401272" target="_blank">Either<TLeft, TRight></a>, which also seems to fix so-called <a href="http://stackoverflow.com/questions/22332407/how-to-avoid-glitches-in-rx/25779152#25779152" target="_blank">"glitches"</a>.</p><p><strong>T</strong> can be a <em>group of T</em>, as in <em>IObservable<</em><a href="http://msdn.microsoft.com/en-us/library/hh229876.aspx" target="_blank">IGroupedObservable<K,T></a>>; e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.groupby.aspx" target="_blank">GroupBy</a>.</p><p><strong>T </strong>might be there or it might not, as in <a href="https://rxx.codeplex.com/SourceControl/changeset/view/74914#Main/Source/Rxx/System/Maybe{T}.cs" target="_blank">Maybe<T></a>.</p><h1>Meta T</h1><blockquote class="bar" style="margin-right: 0px;" dir="ltr"><p><strong>T</strong> carries <em>notification</em>. Observables notify observers by pushing <strong>T</strong>.</p></blockquote><p><strong>T </strong>can be notification <em>reified</em>, as in<strong> </strong><a href="http://msdn.microsoft.com/en-us/library/hh229462.aspx" target="_blank">Notification<T></a>.</p><p><strong>T</strong> can be <em>collection change notifications</em>, as in <a href="https://rxx.codeplex.com/SourceControl/changeset/view/74914#Main/Source/Rxx/System/Reactive/CollectionNotification.cs" target="_blank">CollectionNotification<T></a>.</p><p><strong>T</strong> can be <em>directed mutations</em>, as in <a href="https://rxx.codeplex.com/SourceControl/changeset/view/74914#Main/Source/Rxx/System/Reactive/CollectionModification.cs" target="_blank">CollectionModification<T></a>.</p><h1>Temporal T</h1><blockquote class="bar" style="margin-right: 0px;" dir="ltr"><p><strong>T</strong> carries <em>time</em>. Observables push <strong>T</strong> asynchronously (though <a href="http://go.microsoft.com/fwlink/?LinkID=205219" target="_blank">sequentially</a>-§4.2). Even pushing synchronously takes time though.</p></blockquote><p><strong>T </strong>can be a <em>point in time</em>; implicitly, the time at which it's observed, as in <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.amb.aspx" target="_blank">Amb</a> or <a href="http://msdn.microsoft.com/en-us/library/hh211991.aspx" target="_blank">CombineLatest</a>.</p><p><strong>T </strong>can be time <em>reified</em>, as in <a href="http://msdn.microsoft.com/en-us/library/hh228977.aspx" target="_blank">Timestamped<T></a>, <a href="http://msdn.microsoft.com/en-us/library/hh229834.aspx" target="_blank">TimeInterval<T></a>, <a href="http://msdn.microsoft.com/en-us/library/hh229664.aspx" target="_blank">Recorded<T></a> or simply <a href="http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx" target="_blank">DateTimeOffset</a>.</p><h1>Temporal Window T</h1><blockquote class="bar" style="margin-right: 0px;" dir="ltr"><p><strong>T</strong> carries <em>duration</em>. A <em>window</em> is a duration of time that has a start and maybe an end.</p></blockquote><p><strong>T </strong>can start a <em>window</em>, as in <a href="http://msdn.microsoft.com/en-us/library/hh229750.aspx" target="_blank">Join</a>, <a href="http://msdn.microsoft.com/en-us/library/hh244235.aspx" target="_blank">GroupJoin</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.window.aspx" target="_blank">Window</a> or <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.buffer.aspx" target="_blank">Buffer</a>.</p><p><strong>T </strong>can end a <em>window</em>, as in <strong>Join</strong>, <strong>GroupJoin</strong>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.window.aspx" target="_blank"></a><a href="http://msdn.microsoft.com/en-us/library/hh229909.aspx" target="_blank">Window(closingSelector)</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.window.aspx" target="_blank"></a><a href="http://msdn.microsoft.com/en-us/library/hh229432.aspx" target="_blank">Buffer(closingSelector)</a>, etc.</p><p><strong>T </strong>can be a <em>window</em>, as in <em>IObservable<<strong>IObservable<T></strong>></em>.</p><p><strong>T </strong>can be the <em>end of time</em>, as in that which precedes it, interpreted relative to the time of subscription (e.g., <a href="http://msdn.microsoft.com/en-us/library/hh212050.aspx" target="_blank">Timer</a>), relative to a previous <strong>T</strong> (e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.interval.aspx" target="_blank">Interval</a> or <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.throttle.aspx" target="_blank">Throttle</a>), or relative to some out-of-band time (e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.sample.aspx" target="_blank">Sample</a>).</p><h1>Channel T</h1><blockquote class="bar" style="margin-right: 0px;" dir="ltr"><p><strong>T </strong>can be a <em>channel</em> or <em>callback</em>. <u>Observers</u> invoke <strong>T </strong>to affect an <u>observable</u>.</p></blockquote><p><strong>T </strong>can be a <em>delegate</em>, as in <a href="http://msdn.microsoft.com/en-us/library/system.action.aspx" target="_blank">Action</a> or <a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx" target="_blank">Func<TResult></a>.</p><p><strong>T </strong>can be a <em>subject</em>, as in <em>IObservable<</em><a href="http://msdn.microsoft.com/en-us/library/hh211669.aspx" target="_blank">ISubject<T></a><em>></em>. This establishes a <a href="http://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full-duplex" target="_blank">full duplex</a>, asynchronous communication channel. The observable is a singleton and both ends subscribe to the subject; e.g., <a href="https://rxx.codeplex.com/SourceControl/changeset/view/74914#QbservableProvider/Source/QbservableServer/ChatService.cs" target="_blank">a chat application</a>. (See also <a href="http://davesexton.com/blog/post/LINQ-to-Cloud-IQbservable-Over-the-Wire.aspx">this blog post</a>.)</p><h1>Future T</h1><p><strong>T </strong>can be the <em>promise of a future T</em>, as in <em>IObservable<</em><a href="http://msdn.microsoft.com/en-us/library/vstudio/dd321424.aspx" target="_blank">Task<T></a><em>>; </em>although, it's somewhat redundant since <strong>IObservable<T></strong> is also a promise of a future <strong>T</strong> and it has a wider cardinality [0,∞]. <strong>Task</strong>'s cardinality is strictly [0,1].</p><h1>Conclusion</h1><p><strong>T </strong>carries <em>data</em>, <em>notification</em>, <em>time </em>and <em>duration</em>. It can also have communication channel or promise semantics. Best of all, <strong>T</strong> carries any additional semantics that you choose.</p><p>So the next time that you find yourself stuck trying to figure out which Rx operator is the right one to solve your particular problem, pause and give <strong>T</strong> the attention that it deserves. You may just find that the answer to your problem lies within how you make use of <strong>T</strong>.</p><p>So, have I missed any categorically interesting uses for <strong>T</strong>? How do <em>you</em> use <strong>T</strong>?</p>
https://davesexton.com/blog/post/Rx-The-Power-of-T.aspx
https://davesexton.com/blog/post/Rx-The-Power-of-T.aspx#commenthttps://davesexton.com/blog/post.aspx?id=e7641f34-e8fb-4540-ad43-4dd0cef5d4c3Sat, 13 Sep 2014 03:42:00 +0000PatternsRxRxxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=e7641f34-e8fb-4540-ad43-4dd0cef5d4c30https://davesexton.com/blog/trackback.axd?id=e7641f34-e8fb-4540-ad43-4dd0cef5d4c3https://davesexton.com/blog/post/Rx-The-Power-of-T.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=e7641f34-e8fb-4540-ad43-4dd0cef5d4c3NuGet Package for Sandcastle<p>Did you ever want to build Visual Studio-quality reference documentation from your XML code comments by simply referencing a NuGet package?<br />Well now you can!</p>
<p>The latest release of <a href="https://whitetie.codeplex.com/releases">White Tie</a> includes full support for generating documentation using <a href="https://shfb.codeplex.com">Sandcastle</a>. No configuration necessary. (You must install Sandcastle yourself though - see the details below).</p>
<p>Add a reference to <a href="https://www.nuget.org/packages/WhiteTie/">White Tie's NuGet Package</a> and then simply build your project in <strong>Release</strong> mode to generate reference documentation.</p>
<h1>Details</h1>
<p>If you haven't installed Sandcastle, then White Tie gracefully skips generating documentation. You must install Sandcastle yourself if you want White Tie to generate documentation for your project. Note that you may have to reboot your computer after installing Sandcastle for its changes to take effect. At the very least, you'll have to restart Visual Studio.</p>
<p>White Tie's only requirements are that you must install Microsoft's HTML Help v1 Compiler and Sandcastle's tools. The required steps are highlighted in the following image of the <em>Sandcastle Guided Installer</em>. The other options provided by the installer, such as <em>SHFB Visual Studio Package</em>, are not used by White Tie at all. Of course, you're free to install them anyway if you'd like.</p>
<p>
<img src="https://davesexton.com/blog/image.axd?picture=2014%2f7%2fWhiteTieSandcastleRequirements.png" alt="White Tie's Required Sandcastle Installer Steps" />
</p>
<p>After you've installed Sandcastle, documentation is generated automatically when you build your project in <strong>Release</strong> mode. This is configurable via MSBuild properties, as is almost everything in White Tie (see the following section for details). The result is a compiled help file (.chm) in your project's output folder (typically, <em>bin\Release\</em>). In addition, White Tie packs the compiled help file into the NuGet package that it generates for your project as well.
</p>
<h1>Documentation Configuration<a name="NPFSConfiguration"></a></h1>
<p>The purpose of White Tie is to make packaging and deployment of OSS projects, or any other kind of project, really simple. White Tie uses sensible default configurations across all of its features. However, it's also highly configurable to allow for customizations.
</p>
<p>White Tie offers many configuration options in the form of MSBuild properties and items that control if and how documentation is generated, a NuGet package is generated, static analysis is executed and output is copied to a local deployment directory.
</p>
<p>The configuration options for generating documentation (as of White Tie v1.3.5) are as follows.<br />See the <a href="https://whitetie.codeplex.com/wikipage?title=Configuration">official documentation</a> for details.
</p>
<h2>MSBuild Properties</h2>
<ul>
<li>$(BuildDocumentationEnabled)</li>
<li>$(DocumentationProjectName)</li>
<li>$(DocumentationProductName)</li>
<li>$(DocumentationCompanyName)</li>
<li>$(DocumentationCopyright)</li>
<li>$(DocumentationVersion)</li>
<li>$(DocumentationProjectSummary)</li>
<li>$(DocumentationRootTopicEnabled)</li>
<li>$(DocumentationRootTopicTitle)</li>
<li>$(DocumentationFeedbackEmail)</li>
<li>$(DocumentationFeedbackLinkText)</li>
<li>$(DocumentationHeader)</li>
<li>$(DocumentationFooter)</li>
<li>$(DocumentationStyle)</li>
<li>$(DocumentationLanguage)</li>
</ul>
<h2>MSBuild Items</h2>
<ul>
<li>@(DocumentationContent)</li>
<li>@(DocumentationImage)</li>
<li>@(DocumentationNamespace)</li>
<li>@(DocumentationSource)</li>
<li>@(DocumentationReference)</li>
<li>@(DocumentationFrameworkReference)</li>
</ul>
<h2>Undocumented Sandcastle Configuration Properties and Items<a name="NPFSSandConfig"></a></h2>
<p>Advanced users of Sandcastle may be wondering how to configure Sandcastle's many other options that are missing from the list above.
</p>
<p>Well, in addition to the properties and items listed above, White Tie supports several properties and items that are specific to Sandcastle; however, I've decided to separate these options from the primary group because they aren't general enough for White Tie. In the future, White Tie may support other documentation generators, and perhaps even replace its dependency on Sandcastle entirely. As a result, if you restrict your use to only those configuration options listed above, then in the future you shouldn't have to change anything in order to take advantage of whatever new ways White Tie generates documentation for your project. For example, I can imagine Microsoft offering a very fast and light-weight <a href="http://source.roslyn.codeplex.com">Roslyn documentation generator</a> and in the future I'd like any project depending on White Tie to switch automatically, with little to no changes necessary, by simply upgrading to a newer version of White Tie.
</p>
<p>If you really want to use Sandcastle-specific features anyway, then here they are:
</p>
<ul>
<li>$(_SandcastleCopyrightUrl)</li>
<li>$(_SandcastleVisibleItems) - Default value is "Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, ProtectedInternalAsProtected"</li>
<li>$(_SandcastleMissingTags) - Default value is "IncludeTargets"</li>
<li>$(_SandcastleIntelliSenseOutputEnabled) - Default value is "true"</li>
<li>$(_SandcastleCodeRemoveRegionMarkers) - Default value is "false"</li>
<li>$(_SandcastleHelpFileFormat) - Default value is "HtmlHelp1"</li>
<li>$(_SandcastleSdkLinkTarget) - Default value is "Blank"</li>
<li>$(_SandcastleSyntaxFilters) - Default value is "Standard"</li>
<li>$(_SandcastleHelp2SdkLinkType) - Default value is "Msdn"</li>
<li>$(_SandcastleContentPlacement) - Default value is "AboveNamespaces"</li>
<li>$(_SandcastleNamingMethod) - Default value is "Guid"</li>
<li>$(_SandcastlePreliminary) - Default value is "False"</li>
<li>$(_SandcastleBuildAssemblerVerbosity) - Default value is "OnlyWarningsAndErrors"</li>
<li>$(_SandcastleNamespaceGrouping) - Default value is "True"</li>
<li>$(_SandcastleMaximumGroupParts) - Default value is "2"</li>
<li>$(_SandcastleCatalogName) - Default value is "VisualStudio12"</li>
<li>$(_SHFBApiFilter) - Default value is "<ApiFilter />"</li>
<li>@(SandcastleColorizer) - Default list is "cs;vb"</li>
<li>@(SandcastleComponent) - Default list is empty; however, the <em>Code Block Component</em>, <em>API Token Resolution</em> and <em>IntelliSense Component</em> are included immediately before building, so you cannot remove them.</li>
<li>@(_SandcastleHelpAttribute) - Default list is "DocSet;DocSet;TargetOS". The <strong>Value</strong> metadata of these items are {@HtmlHelpName}, NetFramework and Windows, respectively.</li>
<li>@(_SHFBTransformArguments) - Default list is empty. You may include: logoFile, logoHeight, logoWidth, logoAltText, logoPlacement, logoAlignment, maxVersionParts and defaultLanguage. Set the <strong>Value</strong> metadata to the desired value for each item.</li>
<li>@(_SandcastleContentLayoutFile) - Default list is empty.</li>
<li>@(_SandcastleCodeSnippet) - Default list is empty.</li>
<li>@(_SandcastleTokensFile) - Default list is empty.</li>
<li>@(_SandcastleResourceItems) - Default list is empty.</li>
</ul>
https://davesexton.com/blog/post/NuGet-Package-for-Sandcastle.aspx
https://davesexton.com/blog/post/NuGet-Package-for-Sandcastle.aspx#commenthttps://davesexton.com/blog/post.aspx?id=966a0b6c-9b22-41d9-8259-ad6f7a1e4d40Wed, 16 Jul 2014 04:53:00 +0000Sandcastledavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=966a0b6c-9b22-41d9-8259-ad6f7a1e4d401https://davesexton.com/blog/trackback.axd?id=966a0b6c-9b22-41d9-8259-ad6f7a1e4d40https://davesexton.com/blog/post/NuGet-Package-for-Sandcastle.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=966a0b6c-9b22-41d9-8259-ad6f7a1e4d40OSS For OSS<p style="float: right; padding-left: 10px;"><img style="display: block; margin-left: auto; margin-right: auto;" src="/Images/Blog/_/WhiteTieOnBlack50x50.png" alt="White Tie" border="0" /> <br /> <img style="display: block; margin-left: auto; margin-right: auto;" src="/Images/Blog/_/SettingsSwitcher.png" alt="Visual Studio Settings Switcher" border="0" /></p>
<p>In this post, I'll introduce you to my new OSS project called <a title="White Tie" href="https://whitetie.codeplex.com/">White Tie</a> and I'll describe how it relates to <a title="Rxx" href="https://rxx.codeplex.com">Rxx</a> a bit.</p>
<p>I'll also introduce you to a new feature of another OSS project of mine, <a title="Visual Studio Settings Switcher" href="https://vsswitch.codeplex.com/">Visual Studio Settings Switcher</a>. This new feature allows you to easily share VS settings files with your solution, and OSS contributors to easily take advantage of it.</p>
<p>White Tie and VS Settings Switcher provide a set of features that I've specifically intended to be used by OSS developers, though anyone can benefit from them really.</p>
<p>I know that some of the ideas in these projects are probably not new, but perhaps the way in which I've implemented those ideas as features is new enough, and simple enough, to make them better than competing projects.</p>
<p>Your feedback is welcome.</p>
<h1>White Tie</h1>
<p>I've recently created the <a title="White Tie" href="https://whitetie.codeplex.com/">White Tie</a> project on CodePlex. I like to think of it as "formal buildware for use after 6PM".</p>
<p>White Tie is basically just a couple of unintrusive MSBuild files that are imported by your VS projects. It's primarily intended for OSS developers who use Visual Studio (or MSBuild) to build their projects into NuGet packages, and optionally use Code Contracts, run static analysis and like to copy all build output into a local aggregate directory. There are also work items currently under consideration to build reference documentation via Sandcastle and to enable remote deployment scenarios, for example.</p>
<p>White Tie makes building, packaging and deployment easier by offering sensible, out-of-the-box configuration, though it's also highly customizable by adding particular MSBuild properties and items to your project file. (Read the <a href="https://whitetie.codeplex.com/wikipage?title=Configuration">Configuration</a> documentation for details.)</p>
<p>White Tie is delivered as a <a href="https://www.nuget.org/packages/WhiteTie/">NuGet package</a>, so it's really easy to integrate into your projects. Simply build your project in <strong>Release</strong> mode and a NuGet package will be generated automatically. No configuration is necessary for existing projects, in general, though read the note at the bottom <a href="https://whitetie.codeplex.com#ConfigurationNote">here</a> for details about build errors caused by missing assembly-level attributes in new projects.</p>
<p>One of White Tie's key features is the <strong>NuGetFlavor</strong> item group. By adding project references as <strong>NuGetFlavor</strong> items, rather than as <strong>ProjectReference</strong> items, White Tie will automatically include the referenced projects' output into the primary project's NuGet package.</p>
<p>For example, let's say that you have a primary class library project called <em>Project A</em>, which targets the full .NET Framework 4.5.1. If you add a NuGet reference to White Tie, then whenever <em>Project A</em> is built in <strong>Release</strong> mode (by default), White Tie will generate a NuGet package for <em>Project A</em>. Now let's say that you also have a portable class library project called <em>Project B</em>, which targets a portable profile that includes Windows 8 and Windows Phone 8. <em>Project B</em> is intended to be the same as <em>Project A</em>, only targeting different platforms. You might refer to <em>Project B</em> as a "flavor" of <em>Project A</em>. Now you can simply edit the project file of <em>Project A</em> to add a <strong>NuGetFlavor</strong> item that points to the project file of <em>Project B</em>. Whenever you build <em>Project A</em> in <strong>Release</strong> mode, White Tie ensures that <em>Project B</em> is built as well, and it also includes the portable library built by <em>Project B</em> into the NuGet package that it builds for <em>Project A</em>, and in the correct target framework subfolder.</p>
<p>White Tie offers several more features and configuration options. Take a look at the <a href="https://whitetie.codeplex.com/documentation">documentation</a> to get started, and let me know what you think.</p>
<h2>White Tie's Origins and Future</h2>
<p>White Tie is something that I've been working on for a few years, in one form or another. Much of the work began as part of the <a href="http://rxx.codeplex.com/">Rxx</a> project, such as its support for NuGet, though some features even predate Rxx.</p>
<p>Since Rxx it has evolved into something a bit more useful, though I've only been using it internally for my own OSS projects and business-related products (under the name <em>DaveSexton.Build</em>). I finally decided recently that if I was ever going to "officially" release Rxx again, I'd have to bring its build system and project configurations up-to-date first. White Tie is basically the best of <em>DaveSexton.Build</em>, formalized and revised (or "reimagined", if you prefer advertising jargon) to take advantage of NuGet 2.8 features, including complete support for portable libraries. My transition to White Tie is not yet complete, and there are currently some <a href="https://nuget.codeplex.com/discussions/549922">road blocks</a>, but I'm committed to getting it working fully.</p>
<p>Note that this isn't a guarantee that I'm going to build another NuGet package for Rxx, although it's certainly a large step in the right direction. Not only have I checked in updates to Rxx's source code to include references to White Tie already, but I've also begun to think about and make changes to the portable library configurations that Rxx will target in the future. But even after that, I'm still going to have to comb over all of its APIs before I'll release an "official" package again. I have OCD and I haven't reviewed its source code or work items thoroughly since Rx 2.0 was released, so my confidence level in Rxx is (unreasonably, perhaps) lower than it should be. :)</p>
<h1>Visual Studio Settings Switcher</h1>
<p>I've recently released version 1.2 of the <a title="Visual Studio Settings Switcher" href="https://vsswitch.codeplex.com/">Visual Studio Settings Switcher</a> project on CodePlex, also available in the <a href="http://visualstudiogallery.msdn.microsoft.com/fa71b090-7a6d-49a3-98aa-54d5e3feaa6b">Visual Studio Gallery</a>.</p>
<p>The latest release adds a new feature that I think OSS developers really want: <a href="https://vsswitch.codeplex.com/documentation#SolutionSettings">Solution Settings Files</a></p>
<p>If you have an OSS project, VS Settings Switcher makes it really easy to generate a Visual Studio settings file that you can check into source control along with your solution, for your OSS contributors to use. This settings file is in the typical VS settings file format. It's also XML, which makes it easy to edit in Visual Studio, which you should definitely do before checking it in. I highly recommend removing all of the extraneous settings that nobody wants to be shared in OSS projects, like the positions of your VS tool windows and other environment settings. Typically, you'll want to reduce this file to only a small subset, such as your code formatting settings for your project's programming language.</p>
<p>This feature is also great for those of us that contribute to OSS projects. It makes applying an OSS project's Visual Studio settings a breeze, without any manual intervention required. If a solution has a .vssettings file with the same name and in the same directory, then VS Settings Switcher will automatically apply its settings whenever your open that solution. And when you close that solution or open a different solution later, your original settings are automatically restored.</p>
<p>Spread the word: It's a good idea now to check in a partial .vssettings file with your solution!</p>
https://davesexton.com/blog/post/OSS-For-OSS.aspx
https://davesexton.com/blog/post/OSS-For-OSS.aspx#commenthttps://davesexton.com/blog/post.aspx?id=534d7d01-d438-4c94-9459-2738d20f0ff3Sun, 29 Jun 2014 01:07:00 +0000.NETOpen SourceRxxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=534d7d01-d438-4c94-9459-2738d20f0ff30https://davesexton.com/blog/trackback.axd?id=534d7d01-d438-4c94-9459-2738d20f0ff3https://davesexton.com/blog/post/OSS-For-OSS.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=534d7d01-d438-4c94-9459-2738d20f0ff3Checklist for Creating Rx Operators<p><span style="color: #09480a;"><em>This blog post was originally posted <a href="http://social.msdn.microsoft.com/Forums/en-US/cc89664c-10c8-498f-a5ee-2ef4206b1a3a/checklist-for-creating-rx-operators">here</a> on the Rx forum back in 2012. I've noticed through reference tracking to my blog that it still gets some hits once in a while, so perhaps people are finding it to be useful. I figure it may get more visibility if I copy it to my blog. Note that I've made a few small elisions, corrections, clarifications and additions here, though I've left it essentially the same as the original post.</em></span></p>
<h1>Prerequisites</h1>
<ul>
<li>Know the existing <a href="http://go.microsoft.com/fwlink/?LinkID=205219">Rx Design Guidelines</a> document. You will find references to it throughout this checklist.</li>
<li>Know how to properly use existing Rx operators. This checklist is <span style="text-decoration: underline;"> not</span> about how to properly use existing Rx operators, it's about how to define new operators for use in your business applications, or for inclusion into custom reactive frameworks that are based on the same design principles as Rx.</li>
</ul>
<p>For the purposes of this checklist, an observable operator is any instance, static or extension method that returns <a href="http://msdn.microsoft.com/en-us/library/dd990377.aspx">IObservable<T></a>, including those that are typically considered to be static factory methods or combinators. (§6.3)</p>
<p>Also for the purposes of this checklist, the term <em>observable</em> refers to any local variable, parameter or member that is of the type <strong>IObservable<T></strong> or a delegate to a function that returns an instance of <strong>IObservable<T></strong>.</p>
<h1>Checklist</h1>
<p>Below is a categorized list of factors that I think are important to consider when creating new observable operators, ordered in general from most important to least important. This is not intended to be an exhaustive list, yet. I'll be happy to update it based on your feedback.</p>
<h2>Behavior</h2>
<ol>
<li>Implement your new operator by composing existing Rx operators together, whenever possible; otherwise, just use any overload of <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.create(v=vs.103).aspx"> Observable.Create</a>. Do not implement <strong>IObservable<T></strong> yourself. (§§6.1, 6.2)</li>
<li>Ensure that your operator satisfies the Rx grammar and assume that <strong>IObservable<T> </strong>parameters are well-behaved. (§§4.1, 6.6)<br /> <em>OnNext* (OnCompleted|OnError)?</em></li>
<li>Ensure that your operator serializes notifications and assume that <strong>IObservable<T> </strong> parameters are well-behaved. (§§6.7, 6.8, 4.2)</li>
<li><strong>IObservable<T></strong> is a model for concurrency; therefore, assume that observable parameters execute concurrently when <strong>Subscribe</strong> is called. Ensure that your operator is thread-safe and, when merging or combining the notifications of multiple observable parameters, ensure that your output observable serializes notifications. (§§4.4, 5.9)</li>
<li>Assume that <strong>IObservable<T></strong> parameters are <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">cold</a>. Convert their temperature before subscribing multiple times to avoid duplicating subscription side effects, if your operator does not have <em>retry</em> or <em>repeat</em> semantics. (§5.10)</li>
<li>Protect calls to user code. (§6.4)</li>
<li>Do not catch exceptions thrown by observers; i.e., calls to <strong>OnNext</strong>, <strong>OnError</strong> and <strong>OnCompleted</strong>.</li>
<li>Implement lazy (deferred) execution when generating a <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">cold</a> observable. Check arguments up front, but do not cause any side effects until <strong>Subscribe</strong> is called. This includes scheduling work, iterating enumerable parameters, and mutating external state or parameters. (§6.16)</li>
<li>Implement unsubscription, and do it properly. (§§6.17, 6.18)</li>
<li>Parameterize scheduling when appropriate. (§§6.9, 6.10, 6.11, 5.4)</li>
<li>Avoid deep call stacks caused by recursion. (§6.15)</li>
<li>Watch for reentry when executing user code and assigning the result to a <a href="http://msdn.microsoft.com/en-us/library/system.reactive.disposables.serialdisposable(v=vs.103).aspx">SerialDisposable</a>. Use the <a href="http://rxx.codeplex.com/SourceControl/changeset/view/69461#1055922">double indirection</a> pattern to avoid the effects of race conditions.</li>
</ol>
<h2>Performance and Memory</h2>
<ol>
<li>Do not block. Execute asynchronously instead. (§6.14)</li>
<li>Do not introduce extra asynchrony. Avoid the <strong>ObserveOn</strong> operator, whenever possible. Rely on your notification source, if any, to handle asynchrony itself; alternatively, consider offering parameterized scheduling, especially if you're generating your own notifications. (§§5.5, 6.9, 6.12)</li>
</ol>
<h2>Semantics</h2>
<ol>
<li>Choose a name that is semantically appropriate for the operator based on its business requirement and intended usage rather than behavioral details; e.g., <strong>TakeUntil</strong> is a better name than <strong>SecondStopsFirst</strong>. <strong>GetCustomerOrders</strong> is a better name than <strong>SendOrdersRequest</strong> or <strong>GetServerResponses</strong>.</li>
<li>Do not include implementation details in names except to distinguish between otherwise ambiguous operators and parameters.</li>
<li>Use pluralization to indicate that an observable may generate more than one notification; e.g., <strong>LoadImages</strong>.</li>
<li>Consider naming an extension method returning a <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">hot</a> observable as if it's a property; e.g., <strong>MouseMoves</strong>.</li>
<li>Add an "Observable" suffix to distinguish an operator from existing synchronous and asynchronous methods that have similar names; e.g., <a href="http://rxx.codeplex.com/SourceControl/changeset/view/69461#1100688">Stream.ReadObservable</a>.</li>
</ol>
<h2>Documentation</h2>
<ol>
<li>Specify whether the observable returned by your operator is synchronous, asynchronous or concurrent when <strong>Subscribe</strong> is called.</li>
<li>Specify whether the observable returned by your operator is <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">hot or cold</a>. Be specific about what, if any, side effects may occur when the operator is called and/or when <strong>Subscribe</strong> is called.</li>
</ol>
<h2>Style</h2>
<ol>
<li>Consider whether creating an <a href="http://msdn.microsoft.com/en-us/library/hh191443.aspx">asynchronous method</a>(C# 5; VB 11) is a better fit. This may be true when the generated observable is a singleton (cardinality = 1) and callers aren't necessarily dependent on Rx. Any <strong>Task</strong>-returning operator is easily converted by callers into an observable via the <a href="http://msdn.microsoft.com/en-us/library/hh229584(v=vs.103).aspx">ToObservable</a> method. Note that when complex control flow is required or the operator depends on <strong>Task</strong>-returning methods (e.g., when <em>await</em> is useful) you don't necessarily have to define an <em>async</em> method. Instead, Rx 2.0 Release and Rx 1.1 Experimental define overloads of <strong>Observable.Create</strong> for defining <a href="https://davesexton.com/blog/post/async-iterators.aspx">async iterators</a>.</li>
<li>Avoid using <a href="http://msdn.microsoft.com/en-us/library/system.reactive.subjects.aspx">subjects</a>. It's alright to use them implicitly if necessary; e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publish(v=vs.103).aspx"> Publish</a>. (<a href="https://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx">To Use Subject or Not To Use Subject</a>)</li>
<li>Avoid closing over local variables defined in the outer method body. Sometimes this pattern is useful, but often it's a mistake that causes an otherwise <a href="https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx">cold</a> observable to behave unpredictably because state is shared among multiple calls to <strong>Subscribe</strong>.</li>
</ol>
https://davesexton.com/blog/post/Checklist-for-Creating-Rx-Operators.aspx
https://davesexton.com/blog/post/Checklist-for-Creating-Rx-Operators.aspx#commenthttps://davesexton.com/blog/post.aspx?id=d4dd9a7c-f90f-4fa0-9e3a-25be955fae4bWed, 30 Apr 2014 08:16:00 +0000Rxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=d4dd9a7c-f90f-4fa0-9e3a-25be955fae4b0https://davesexton.com/blog/trackback.axd?id=d4dd9a7c-f90f-4fa0-9e3a-25be955fae4bhttps://davesexton.com/blog/post/Checklist-for-Creating-Rx-Operators.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=d4dd9a7c-f90f-4fa0-9e3a-25be955fae4bHot and Cold Observables<p><span style="color: #09480a;"><em>I've touched on the topic of observable temperature while answering questions on the <a href="http://social.msdn.microsoft.com/Forums/en-US/home?forum=rx">Rx forum</a> and in <a href="https://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx">my previous post on subjects</a>. I tried explaining it more deeply in <a href="http://social.msdn.microsoft.com/Forums/en-US/14a62f80-a010-4e60-b852-c7991a57fb07/its-hard-to-reason-about-publish">this particular discussion</a>, but now I'm finally ready to provide a deep and comprehensive<sup><a href="#HCObCite1">1</a></sup> analysis in this blog post.</em></span></p>
<p>I'll answer the following questions: </p>
<p style="padding-left: 30px;">What <span style="text-decoration: underline;">really</span> makes an observable <em>hot</em> or <em>cold</em>?<br />Why should I care?<br />How can I tell if an observable is <em>hot</em> or <em>cold</em>?<br />How can I change the <em>temperature</em> of an observable?</p>
<p>The analysis that follows is not intended for beginners, though you may find the following section and the <a href="#HCObConclusion">conclusion</a> to be informative. You may also want to <a href="http://channel9.msdn.com/Blogs/J.Van.Gogh/Rx-API-in-depth-Hot-and-Cold-observables">watch this</a> first and look <a href="https://davesexton.com/blog/post/resources-for-learning-rx.aspx">here</a> for additional information.</p>
<h1>Common Sense</h1>
<p>We like to think of <em>hot</em> observables from two different perspectives as follows.</p>
<p>From the perspective of <strong>observers</strong>, there's the potential to miss notifications. <em>Hot</em> observables are "live" sequences, meaning that they are happening whether we observe them or not. The canonical example is a mouse, which of course is free to move regardless of whether you subscribe to an <em>IObservable<MouseMoveEventArgs></em> or not. In general, if I hand you an observable and tell you that it's <em>hot</em>, then as an observer you'd infer that you might have missed notifications that happened before you subscribed. Pretty simple.</p>
<p>From the perspective of <strong>observables</strong>, <em>hot </em>observables broadcast notifications to all observers. The canonical example is converting an event into an observable; e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx">FromEventPattern</a>. If three observers subscribe to <em>IObservable<MouseMoveEventArgs></em>, then each observer will serially<sup><a href="#HCObCite2">2</a></sup> observe the same notifications, as opposed to observing different notifications or concurrent notifications.</p>
<p>We like to think of <em>cold</em> observables from the same perspectives as follows.</p>
<p>From the perspective of <strong>observers</strong>, there's the potential for each observer to get different notifications. <em>Cold</em> observables are "generated" sequences, meaning that they can generate different notifications for every observer. Furthermore, observers may receive notifications asynchronously, with respect to each other. The canonical example is <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.create(v=vs.103).aspx">Create</a>, which can asynchronously generate notifications whenever an observer subscribes.</p>
<p>From the perspective of <strong>observables</strong>, <em>cold</em> observables won't generate notifications until an observer subscribes, and they generate notifications each time that an observer subscribes. The canonical example is <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.range(v=vs.103).aspx">Range</a>, which generates a range of numbers whenever an observer subscribes.</p>
<p>In summary, common sense tells us that:</p>
<p style="padding-left: 30px;"><em>Hot</em> observables are<strong> always running </strong>and they<strong> broadcast </strong>notifications to all observers<strong>.</strong></p>
<p style="padding-left: 30px;"><em>Cold</em> observables <strong>generate </strong>notifications for each observer.</p>
<p>I intend to show that these ideas are more like symptoms rather than definitions. I'll also identify a pattern to reduce them into a primitive concept: side effects. Ultimately, I'd like to ensure that <em>hot</em> and <em>cold</em> are well-defined terms based primarily on the concept of side effects.<sup><a href="#HCObCite3">3</a></sup></p>
<p>Enough skipping rocks over the topic. Let's dive into the watery refraction and expose the peculiarities of our naïve understanding of these concepts.</p>
<h1>Uncommon Sense</h1>
<p>We know that an observable can be either <em>hot</em> or <em>cold</em>, but can they mix? Can an observable be <strong>generated </strong>while <strong>broadcasting</strong>? Can it be <strong>generated </strong>and yet<strong> always running</strong>? Can it be <strong>always running</strong> without <strong>broadcasting</strong>? Can the <em>temperature </em>change dynamically?</p>
<p>That last question is particularly interesting. Can an observable change its <em>temperature </em>after an observer subscribes? E.g., Observer <em>E</em> subscribes first, then <em>F </em>subscribes; <em>E </em>gets a <em>hot</em> observable while <em>F </em>gets a <em>cold</em> observable.</p>
<p>Can an observable change its temperature for the same observer after it subscribes? E.g., Observer <em>G </em>subscribes to a <em>cold</em> observable that eventually transitions into a <em>hot</em> observable, for <em>G, </em>while it remains subscribed.</p>
<p>What about specialized subscription behaviors, such as one that causes an observable to behave like it's <em>hot</em> until all observers unsubscribe and then it becomes <em>cold </em>again for a subsequent subscription, which flips it back to being <em>hot</em> again -- does that behavior exist?</p>
<p>The answer to all of these questions is <strong>YES</strong>. Well, it seems more like <strong>YES </strong>and <strong>SORT OF</strong>, based on our common sense definitions. I'll try to explain.</p>
<p>Those behaviors might seem strange, but you've probably used them together before. They're implemented by a couple of well-known Rx operators; e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.replay(v=VS.103).aspx">Replay</a> and <a href="http://msdn.microsoft.com/en-us/library/hh211664(v=VS.103).aspx">RefCount</a>. Similarly, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publishlast(v=vs.103).aspx">PublishLast</a> and some particular overloads of <a href="http://msdn.microsoft.com/en-us/library/hh211622(v=vs.103).aspx">Publish</a> have strange behaviors with regard to <em>temperature</em>.</p>
<p>For example, keeping in mind our common sense definitions of <em>hot</em> and <em>cold</em>, let's assume that you have an observable <em>O</em> and you call <em>O.Replay()</em> to get an <a href="http://msdn.microsoft.com/en-us/library/hh211887(v=vs.103).aspx">IConnectableObservable<T></a>, which you assign to <em>C</em> and then call <em>C.Subscribe(J)</em> and <em>C.Subscribe(K)</em>. I think we'd all consider <em>C</em> to be <em>hot </em>(or at least <em>warm</em>, whatever that means) because all of its notifications are<strong> broadcast </strong>to <em>J</em> and <em>K</em>, even though notifications won't arrive until <strong>Connect </strong>is called. It's not entirely <em>hot</em> because it doesn't necessarily satisfy the <strong>always running</strong> factor, hence the introduction of the confusing term <em>warm</em>.</p>
<p>So far, <strong>Replay</strong> is identical to <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publish(v=VS.103).aspx">Publish</a>.</p>
<p>Then you call <em>C.Connect()</em>, which may cause <em>J</em> and <em>K</em> to observe notifications from <em>O</em>. If <em>O</em> is <em>hot</em>, then the <strong>always running</strong> factor was satisfied anyway, but if <em>O</em> is <em>cold</em>, then it's not satisfied; regardless, I think we'd all consider <em>C</em> to be <em>hot</em> at this point because of its <strong>broadcasting</strong> behavior alone.</p>
<p>Finally, you call <em>C.Subscribe(L)</em>, and now there's a race condition on <em>L</em> with respect to our common sense understanding of observable temperature. If <em>O</em> generated any notifications sometime between the calls to <em>C.Connect()</em> and <em>C.Subscribe(L)</em>, then <em>L</em> will immediately observe replayed notifications, thus <em>C</em> was technically a <em>cold</em> observable when <em>L</em> subscribed because those particular notifications aren't rebroadcast to <em>J</em> and <em>K</em>; i.e., <strong><em>C</em> generates specific notifications for <em>L</em></strong>. It means that while <em>C</em> is <em>hot</em> for <em>J </em>and <em>K</em>, it's <em>cold</em> for <em>L</em>; however, it's not permanently <em>cold</em> for <em>L </em>because after <em>C</em> replays all of the notifications that <em>L </em>missed, then <em>L</em> will be observing the same exact <strong>broadcast</strong> notifications as <em>J</em> and <em>K</em>, which means that <em>C</em> transitions from <em>cold</em> to <em>hot </em>for <em>L</em>. Although, if <em>O</em> hadn't generated any notifications before you called <em>C.Subscribe(L)</em>, then <em>C</em> would start out <em>hot</em> for <em>L</em> just like <em>J </em>and <em>K</em>.</p>
<p>Apparently, sometimes <strong>Replay</strong> is <em>hot </em>(though only if its source is <em>hot</em>, and only before <strong>Connect </strong>is called), sometimes it's <em>warm </em>(though only if its source is <em>cold</em>, and only before <strong>Connect</strong> is called), sometimes it transitions from <em>warm</em> to <em>hot</em> (though only for observers that subscribed before calling <strong>Connect</strong>) and sometimes it transitions from <em>cold</em> to <em>hot, </em>with a race condition (though only for observers that subscribe after <strong>Connect</strong> was called)<em>.</em></p>
<p>Part of the reason that this is confusing is because <strong>always running</strong>,<strong> broadcast </strong>and<strong> generate</strong> are actually relative concepts. They implicitly refer to the time of subscription, though we tend to ignore this fact. <strong>Always running </strong>refers to pre-subscription, <strong>generate</strong> refers to the time of subscription and <strong>broadcast </strong>is a post-subscription concept. This explains how operators like <strong>Replay</strong> can offer strange combinations of these behaviors.<em></em></p>
<p>The common sense meanings of <em>hot</em> and <em>cold </em>are diluted by their differences in relation to the time of subscription and the connectability of operators like <strong>Replay</strong>, with a dependence on the temperature of the source and the presence of a race condition.</p>
<p>Technically it's possible for an observable to be <strong>always running </strong>without <strong>broadcasting</strong>; e.g., simply don't subscribe to a <em>hot</em> observable. Our common sense definition tells us that it's <em>hot</em> even though it's not broadcasting. <strong>Always running </strong>and <strong>generating</strong> are opposite behaviors, which makes <strong>broadcasting</strong> seem more like a symptom rather than a definition.</p>
<p>It's also possible for an observable to be <strong>generated </strong>while <strong>broadcasting</strong>; e.g., publishing a <em>cold</em> observable. Again, common sense tells us that it's <em>hot </em>even though it's not always running, because we know that an underlying observable is actually responsible for generating notifications, which are broadcast to all observers. This makes <strong>always running </strong>seem more like a symptom rather than a definition.</p>
<p>And finally, as shown by the <strong>Replay</strong> example above, an observable can be <strong>always running</strong> and yet <strong>generated</strong> at the same time. They'll overlap until generation completes, like emptying a buffer, after which the observable seamlessly transitions into the <strong>always running</strong> sequence. It's hard to say whether this kind of sequence is purely <em>cold</em> based on the common sense definition of generation alone. We almost want to call it, "<em>hot </em>with some additional notifications". This makes <strong>generation</strong> seem more like a symptom rather than a definition.</p>
<p>In general, our common sense definitions of <em>hot</em> and <em>cold</em> aren't precise enough to be useful to observers so we tend to ignore them and make assumptions based on what really matters: side effects. All we really care about is answering one simple question:</p>
<blockquote>
<p>If I subscribe to your observable, might it cause side effects?</p>
</blockquote>
<p>It would be great if we could specify this behavior in a word. The terms <em>cold</em> and <em>hot </em>should provide the answers <em>yes</em> and <em>no</em>, respectively.</p>
<h1>Subscription Side Effects</h1>
<p>Wikipedia defines <a href="http://en.wikipedia.org/wiki/Side_effect_(computer_science)">side effect</a> as:</p>
<blockquote>
<p><em>Modifying some state or causing an observable interaction with calling functions of the outside world.</em></p>
</blockquote>
<p>However, sometimes mutation is the <em>primary effect</em>; e.g., assignment. Clearly the definition is relative.</p>
<p>So let's define <em>side effect</em> for our purposes as:</p>
<p style="padding-left: 30px;">Any effect that is not the primary effect.</p>
<p>The primary effect of subscribing to an observable (i.e., calling <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.subscribe(v=VS.103).aspx">Subscribe</a>) is to register an observer for callbacks, which probably means that the observer will be added to the observable's internal list of observers and a disposable will be created and returned to represent unsubscription.</p>
<p>Likewise, the primary effect of .NET event registration is to add a handler to the list of delegates in the event's <a href="http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx">MulticastDelegate</a> instance. We can easily <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromevent(v=vs.103).aspx">convert any event into an observable</a>. The primary effect of subscribing to an observable event is to convert an observer into an event handler, register it with the event, and return a new disposable that unregisters the observer from the event.</p>
<p>That pattern remains the same for other native asynchronous conversions as well, such as <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromasyncpattern(v=vs.103).aspx">FromAsyncPattern</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.threading.tasks.taskobservableextensions.toobservable(v=vs.103).aspx">ToObservable</a> (Task/Task<T>).</p>
<p>In addition, the compositional nature of Rx (more on that later in this post) allows operators to form subscription chains. Subscribing to the outer-most operator's observable causes it to subscribe to the previous operator's observable, which subscribes to another observable, and so on. The entire subscription chain is certainly part of the <em>primary effect</em> of subscribing. Ultimately, the goal is to subscribe to the inner-most observable through as many intermediary subscriptions as necessary.</p>
<p>Subscription chains inherit side effects. If any inner subscriptions cause side effects, then the outer-most subscription inadvertently causes them too; therefore, our definition of <em>subscription side effects</em> implicitly includes the sum of all inherited subscription side effects.</p>
<p>Based on the ideas above, a <strong>subscription side effect</strong> is:</p>
<p style="padding-left: 30px;">Any side effect other than subscribing to another observable, adding an observer to an observable's "list of observers" and creating a new disposable for unsubscription.</p>
<p>where the meaning of "side effect" is defined by wikipedia and "list of observers" is defined by the necessary conversion to the underlying asynchronous model, if any.</p>
<p>Perhaps for the sake of simplicity I should reduce that definition. Side-effect inheritance is implied, as is adding an observer to a "list of observers" and returning a disposable for unsubscription. All of these behaviors are intuitively part of the <em>subscription mechanism</em>.</p>
<p>Therefore, a <strong>subscription side effect </strong>is:</p>
<p style="padding-left: 30px;">Any effect beyond an observable's subscription mechanism.</p>
<p>Examples of subscription side effects include: Calling <a href="http://msdn.microsoft.com/en-us/library/system.reactive.concurrency.ischeduler.schedule(v=vs.103).aspx">Schedule</a>, <a href="http://msdn.microsoft.com/en-us/library/dd782792.aspx">OnNext</a>, <a href="http://msdn.microsoft.com/en-us/library/dd781657.aspx">OnError</a>, <a href="http://msdn.microsoft.com/en-us/library/dd782982.aspx">OnCompleted</a>, <a href="http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.getenumerator.aspx">GetEnumerator</a> or <a href="http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext.aspx">MoveNext</a>, mutating a field, creating an object in memory, running a CPU-intensive computation, sending a web request, reading a file, ending a process, formatting your C drive, or really anything else that you can think of that isn't merely the <em>subscription mechanism </em>and may cause an observable effect on the outside world, including notifications.</p>
<h1>Covering All Bases</h1>
<div style="float: right; margin-left: 5px; width: 400px; background-color: azure; margin-right: 5px; border: gray 1px solid; padding: 5px;">
<h2 style="margin-top: 0; padding-top: 0;">Duality</h2>
<p>If you're interested in the duality between observables and enumerables, then copy and paste the <strong>Covering All Bases</strong> section into your favorite text editor and replace the following character sequences (not necessarily on word boundaries):</p>
<table rules="all" cellpadding="2">
<tbody>
<tr>
<td>asynchronous</td>
<td style="text-align: center;">synchronous</td>
</tr>
<tr>
<td>observable</td>
<td style="text-align: center;">enumerable</td>
</tr>
<tr>
<td>observe</td>
<td style="text-align: center;">enumerate</td>
</tr>
<tr>
<td>subscription</td>
<td style="text-align: center;">enumeration</td>
</tr>
<tr>
<td>subscribing</td>
<td style="text-align: center;">enumerating</td>
</tr>
<tr>
<td>subscribe</td>
<td style="text-align: center;">MoveNext</td>
</tr>
<tr>
<td>notification</td>
<td style="text-align: center;">element</td>
</tr>
<tr>
<td>always running</td>
<td style="text-align: center;">pre-calculated</td>
</tr>
<tr>
<td>broadcast</td>
<td style="text-align: center;">broadcast/share</td>
</tr>
<tr>
<td>subject<br />connection<br />connect</td>
<td style="text-align: center;">IBuffer</td>
</tr>
<tr>
<td>pushed<br />listening in to<br />calling OnNext, OnError or OnCompleted</td>
<td style="text-align: center;">yielding</td>
</tr>
</tbody>
</table>
<p>It works! Some of the grammar and spelling is a bit off though, and some of the ideas and <a href="http://www.nuget.org/packages/Ix-Main/">operators</a> may be entirely irrelevant due to the lack of asynchrony in enumerables, but the given definitions of <em>hot</em> and <em>cold</em> and the summarization are correct.</p>
</div>
<p>The concept of subscription side effects completely covers our common sense understanding of temperature as follows.</p>
<p>Recall our definition of <em>subscription side effects</em> from above:</p>
<p style="padding-left: 30px;">Any effect beyond an observable's subscription mechanism.</p>
<p>Recall our common sense definitions of temperature from above:</p>
<p style="padding-left: 30px;"><em>Hot</em> observables are<strong> always running </strong>and they<strong> broadcast </strong>notifications to all observers<strong>.</strong></p>
<p style="padding-left: 30px;"><em>Cold</em> observables <strong>generate </strong>notifications for each observer.</p>
<p>Understanding how <em>cold</em> behavior relates to subscription side effects is easy:</p>
<p><strong>Generate </strong>means calling <strong>OnNext</strong>, <strong>OnError</strong> or <strong>OnCompleted</strong> when <strong>Subscribe</strong> is called. This can be done synchronously or asynchronously with an <strong>IScheduler</strong>. Either way these actions are, by definition, <em>subscription side effects</em>. That's pretty simple.</p>
<p>Now let's jump to the common sense definition of <em>hot </em>and see how it compares:</p>
<p><strong>Always running </strong>means that as soon as an observer subscribes it begins listening in to notifications. It implies that notifications will not be generated as a side effect of subscribing, but that the mere act of subscribing enables an observer to receive notifications that would have occurred anyway. In other words, subscribing to an observable that is <strong>always running</strong> does not necessarily cause subscription side effects. The primary effect of subscribing is all that is needed to begin receiving notifications asynchronously.</p>
<p><strong>Broadcast </strong>means that when a notification is ready to be observed it is pushed to all currently subscribed observers, which does not seem to imply anything about subscription side effects. Theoretically, an observable could asynchronously generate notifications upon subscription, pushing them to the original observer that caused these subscription side effects while also broadcasting them to any observers that are fast enough to subscribe before the notifications are generated. That's not the same behavior as <strong>Replay</strong>, for example, because <strong>Replay</strong> doesn't broadcast the notifications that it generates for an individual observer. Apparently this behavior doesn't exist in any Rx primitives. When an observer subscribes to a <em>cold</em> observable, without publishing, it observes notifications that are generated for it alone; i.e., <em>cold</em> observables don't broadcast.</p>
<p><strong>Broadcast</strong> in Rx means that an observable is not responsible for <strong>generating </strong>notifications itself, but instead <strong>broadcasts </strong>notifications on behalf of some underlying observable. That's the difference between the common sense definitions of <em>cold</em> and <em>hot</em>, respectively; therefore, broadcasting does not cause subscription side effects, meaning simply that when you subscribe to a broadcasting observable there will be no subscription side effects.</p>
<p><strong>Broadcasting</strong> a <em>cold</em> observable has to cause subscription side effects once, though it's not caused by an observer subscribing to the broadcasting observable, but the broadcasting observable subscribing to the <em>cold</em> observable; a.k.a., "connecting". Connection is exposed as a public operation, either by a subject's ability to act as an observer or by an operator returning <strong>IConnectableObservable<T></strong>. Theoretically, connection isn't necessary if the underlying observable is always running because observers that haven't subscribed yet are going to miss notifications whether the broadcasting observable is connected or not; however, if the underlying observable isn't always running (i.e., it's <em>cold</em>), then connection is required to ensure that observers don't miss notifications before they've subscribed to the broadcasting observable. As a result, exposing the connection behavior of broadcasting observables defers subscription side effects of the underlying observable. This implies again that broadcasting doesn't cause subscription side effects. Subscribing to a broadcasting observable is all that is needed to begin receiving notifications asynchronously from the underlying observable, although notifications may be deferred until connection if the observable is connectable.</p>
<p>An emerging pattern here is that subscription side effects aren't expected at all in <em>hot</em> observables, including the case where a <em>hot</em> observable broadcasts notifications for a <em>cold</em> observable, because subscription side effects are deferred until connection. We'll call them <em>connection side effects </em>instead.</p>
<p>Connectability may be hidden from observers. Subjects are observables, thus the <a href="http://msdn.microsoft.com/en-us/library/hh211761(v=VS.103).aspx">AsObservable</a> operator can be used to hide their connectability. The same applies to <strong>IConnectableObservable<T></strong>. In either case, <em>hot</em> behavior is retained even when observers know nothing about the underlying connectability of observables; therefore, simply knowing that an observable broadcasts implies that it doesn't cause <em>subscription side effects</em>. It may have caused or will cause <em>connection side effects</em>, but that's beyond an observer's control when connectability has been hidden.</p>
<p>In addition, some stateful behaviors in Rx use <em>connection side effects</em> to separate <em>notifications</em> from other kinds of <em>subscription side effects</em>. This is perhaps the most confusing case as far as the common sense definitions of <em>hot</em> and <em>cold</em> are concerned.</p>
<p>Recall from a previous section, when we reviewed the strange behaviors of <strong>Replay</strong> and <strong>RefCount</strong>, we determined that our common sense definitions are diluted because of their differences in relation to the time of subscription and the connectability of operators, with a dependence on the temperature of the source and the presence of a race condition.</p>
<p><strong>Replay</strong>,<strong> PublishLast</strong>, and overloads of <strong>Publish</strong> that have an <em>initialValue</em> parameter, broadcast all subscription side effects, including notifications, to any observer that subscribes before they are connected to the underlying observable. They also broadcast all subscription side effects, including notifications, to any observer that subscribes after connection but before the underlying observable generates any notifications. They broadcast all subscription side effects, excluding missed notifications but including future notifications, to any observer that has missed notifications. The missed notifications aren't broadcast, they are generated specifically for the particular observer that missed them.</p>
<p>These operators show that <em>hot</em> and <em>cold</em> are relative terms with regard to different kinds of subscription side effects, of which notifications are just one example. They separate <em>missed notifications</em> from other kinds of <em>subscription side effects </em>to return a relatively <em>cold</em> observable or a relatively <em>hot</em> observable, respectively. This is possible because <strong>broadcasting</strong> is a post-subscription concept and the ability to <em>miss</em> notifications is a pre-subscription concept that can be remedied at the time of subscription through <strong>generation</strong>, thus allowing an observable to be <em>hot</em> for some observers and <em>cold</em> for others, simultaneously.</p>
<p>Furthermore, the ability of these kinds of observables to transition from the common sense definitions of <em>cold</em> to <em>hot</em> is of no importance now, given that all we really care about is subscription side effects. In other words, the newly defined <em>hot</em> and <em>cold</em> terms are relative to the time of subscription and to different kinds of subscription side effects, so the ability to transition is irrelevant. An observable either causes subscription side effects or it does not.</p>
<p>Thus we no longer need any confusing terms such as <em>warm </em>to describe the behavior of connectables. A connectable observable is always <em>hot</em> before it's connected and is generally <em>hot</em> afterwards, though some operators apply special behavior to missed notifications to ensure that they aren't actually missed. These operators return an observable that is <em>cold</em> with regard to missed notifications, for a particular observer, and <em>hot</em> with regard to any other kind of subscription side effect, including future notifications; however, because our new definitions of <em>hot</em> and <em>cold </em>make transitioning irrelevant, we can say absolutely that an observer that has missed notifications will get a <em>cold </em>observable from these operators. (The race condition's effect on our new definition of <em>cold</em> will be addressed later in this post.)</p>
<p>In summary, our new understanding of temperature with regard to subscription side effects tells us that:</p>
<p style="padding-left: 30px;"><em>Hot</em> and <em>cold</em> are relative terms with regard to the time of subscription and to different kinds of subscription side effects.</p>
<p style="padding-left: 30px;"><em>Hot</em> observables either don't cause subscription side effects or defer them until connection, where they become connection side effects.</p>
<p style="padding-left: 30px;"><em>Cold</em> observables rely on subscription side effects.</p>
<p>Perhaps we can distinguish between these terms further by defining whether subscription side effects may or may not occur:</p>
<p style="padding-left: 30px;"><em>Hot</em> observables <span style="text-decoration: underline;">do not</span> cause subscription side effects.</p>
<p style="padding-left: 30px;"><em>Cold</em> observables <span style="text-decoration: underline;">do</span> cause subscription side effects. (Though keep reading because later on I'll relax this definition a bit.)</p>
<p>Finally, we now have a specific and useful definition of observable temperature:</p>
<p style="padding-left: 30px;"><strong>Temperature indicates the propensity of an observable to cause subscription side effects.</strong></p>
<p>Furthermore, we can largely ignore the relativity to particular kinds of subscription side effects since it only matters when discussing the special behaviors of <strong>Replay</strong>, <strong>Publish</strong> and <strong>PublishLast</strong>. And those operators only distinguish missed notifications from other kinds of subscription side effects, so they can easily be described as generally <em>hot</em> yet <em>cold </em>with respect to missed notifications.</p>
<p style="padding-left: 30px;">In general, the terms <em>hot</em> and <em>cold</em> cover all kinds of subscription side effects, including notifications. </p>
<p style="padding-left: 30px;">Concerning <strong>Replay</strong>, <strong>PublishLast</strong>, and <strong>Publish</strong> overloads with an <em>initialValue </em>parameter, they return observables that are <em>cold </em>for particular observers that have missed notifications, yet they are <em>hot</em> with respect to any other kind of subscription side effect.</p>
<p>Now let's test the reverse: We'll see if our original common sense definitions can be inferred from our new definitions of <em>hot</em> and <em>cold</em>.</p>
<p>Given an observable that is known to not cause any subscription side effects, one must infer that it's either <strong>always running</strong>, which never causes subscription side effects, or it must <strong>broadcast</strong>, which defers subscription side effects into <em>connection side effects</em>; therefore, we must refer to the observable as <em>hot</em>.</p>
<p>Our new definition seems to be holding up so far. Let's see how it compares to the common sense definition of <em>cold</em>.</p>
<p>Given an observable that is known to cause subscription side effects, one can infer that it might <strong>generate </strong>notifications when an observer subscribes, thus we may refer to it as <em>cold</em>.</p>
<p>It seems like we've got a match; however, notice that I wrote "might generate notifications". That's because, as described previously, subscription side effects are far more general than just generating notifications. A <em>cold</em> observable, by our new definition, can cause any subscription side effect. For example, it can send a web request or asynchronously read from a file, without ever generating any notifications. Of course, generating a notification would be useful so it's quite common for these examples in particular to generate notifications asynchronously once the operation has completed.</p>
<p>There are other kinds of subscription side effects that do not generate any notifications - not even asynchronously. For example, imagine tracking the number of observers subscribed to your observable; each time <strong>Subscribe</strong> is called an integer field is incremented by 1. That's similar to the behavior of the <strong>RefCount</strong> operator, described above. Another example is subscription logging, for diagnostic purposes, which may cause a file to be updated on disc every time an observer subscribes. The common sense definition of <em>cold</em> doesn't cover these cases, but our new definition does!</p>
<p>It seems to me that our new definition of <em>temperature</em> entirely covers the common sense definition, and does so elegantly as diametrically opposed concepts. Furthermore, our new definition of <em>hot</em> nicely ties together the two orthogonal concepts that make up the common sense definition of <em>hot</em>, while our new definition of <em>cold</em> identifies the important factor and generalizes it.</p>
<p>But why are subscription side effects the important factor?</p>
<h1>Composition</h1>
<p>LINQ operators enable the composition of observables into "queries". Applying any operator to one or more observables means that it will subscribe to those observables when you subscribe to the query.</p>
<p>When defining a query, it's not uncommon to reference an observable multiple times, which means passing the same observable to different operators or to the same operator as multiple arguments. Since we know that operators subscribe to the observables that you pass to them, referencing the same observable multiple times means that it will potentially have multiple subscriptions.</p>
<p>Some operators have the semantics of multiple subscriptions without multiple references. For example, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.retry(v=VS.103).aspx">Retry</a> only accepts a single observable and potentially subscribes to it multiple times. In this case it's desirable to duplicate subscription side effects. For example, if we pass to <strong>Retry</strong> an observable that makes a web request as its subscription side effect, then we want <strong>Retry</strong> to execute that subscription side effect every time it re-subscribes. In other words, we want to retry the web request.</p>
<p>That's why subscription side effects are the important factor. From the point of view of the <strong>Retry</strong> operator, we don't necessarily want to duplicate the observable's notifications (as indicated by our common sense definition of <em>cold</em>), we simply want to duplicate the subscription side effects, whatever they might be. In other words, it's not about generating the notifications, it's about executing the side effects, which are often responsible for generating the notifications.</p>
<p>Sometimes an observable is referenced multiple times without the semantics of allowing duplicate subscription side effects. For example, you could apply the <strong>Where</strong> operator twice to the same observable to create two different observables, then apply the <strong>Zip</strong> operator to merge them back into a single observable in a pairwise fashion. The query's output semantics aren't important here; what's important is that you don't want to create two subscriptions to the original observable. Instead, you want broadcast behavior.</p>
<p>Broadcasting is essentially the same thing as sharing subscription side effects among multiple observers. In the previous example, imagine that the observable to which you are applying the <strong>Where</strong> operator is <em>cold</em>; e.g., each time that you subscribe it sends a web request to open a reactive socket connection to a server and then streams the responses as notifications. The <strong>Zip</strong> operator is going to subscribe twice, but we don't want to send two web requests. Our desire to broadcast the notifications is the same as our desire to broadcast the web request, because it's the web request (i.e., the subscription side effect) that is responsible for generating notifications in the first place.</p>
<p>And again, that's why subscription side effects are the important factor. In the former case we wanted to duplicate them, while in the latter case we wanted to broadcast them.</p>
<h2>Composition in Custom Operators</h2>
<p>The previous cases are special because we had prior knowledge of an observable's <em>temperature</em>. But what if we didn't?</p>
<p>Composite operators are queries themselves; however, they don't typically define contracts for the <em>temperatures</em> of their observable parameters. In other words, when we define a custom operator, we must make assumptions as to the <em>temperatures</em> of observable parameters.</p>
<p>An obvious question is: Why can't we define <em>temperature</em> contracts on operators?</p>
<p>Well, technically you could, but then you'd be forcing callers in some cases to explicitly change the temperature of observables before calling your operator, which changes the declarative nature of some operators by bringing <em>temperature</em> into the foreground when perhaps it's unnecessary.</p>
<p>Furthermore, if a caller is unaware of the temperature, then an assumption has to be made anyway. Unless the contract is propagated to a caller that can control the temperature - and now we've got a viral effect, as is common with contracts.</p>
<p>Alternatively, you'd probably want to have two overloads for every operator where temperature is of concern: one overload for <em>cold</em> observables, one for <em>hot</em> observables. But how can you overload operators by temperature without defining new types?</p>
<p>Do we really need this complexity? What are the disadvantages of making assumptions at the operator level?</p>
<p>If you were to assume that all observable parameters are <em>hot</em>, then it's fine if your operator relies on broadcast behavior, but it's wrong if your operator must duplicate subscription side effects; e.g., <strong>Retry</strong>. Alternatively, if you were to assume that they are <em>cold</em>, then the reverse is true: It's fine if duplicating subscription side effects is what you want, but it's wrong if you need broadcast behavior.</p>
<p>Therefore, we need to consider the possibilities of conversion before we can determine which assumption is best in general.</p>
<h1>Temperature Conversion</h1>
<p>First, a quick note about language:</p>
<p style="padding-left: 30px;"><strong>IObservable<T></strong> is an immutable type; therefore, there's no way to mutate its <em>temperature</em>. When I refer to "changing" an observable to a particular temperature or "making" an observable a particular temperature, I'm using those terms in the general sense of unary operator application. For example:</p>
<div style="padding-left: 30px;">
<pre class="brush: c-sharp;">var x = 10;
var y = -x;</pre>
</div>
<p style="padding-left: 30px;">You might say that the second line "negates <em>x"</em>, but technically it doesn't because after the negation operation, <em>x</em> hasn't changed. It's applying the negation operator to <em>x</em> and assigning the result to <em>y</em>. The former is just a natural way of describing the essence of the operation. Although it's ambiguous in this situation, it's not when dealing with <strong>IObservable<T></strong> because it's immutable. Therefore, "changing" an observable's temperature or "making" it have a different temperature simply refers to the application of some operator and the assignment of the result into a new variable, which holds a different observable with the desired temperature.</p>
<p>We can change a <em>cold</em> observable into a <em>hot</em> observable by applying the <strong>Publish </strong>operator, which has overloads that project the observable into a <em>selector</em> function as a <em>hot</em> observable (though the operator itself returns a <em>cold</em> observable) and overloads that return a connectable observable. The latter defers subscription side effects until connection, effectively broadcasting them across multiple observers as <em>connection side effects</em>.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publish(v=VS.103).aspx">Publish</a> makes a <em>cold</em> observable <em>hot</em>.<sup><a href="#HCObCite4">4</a></sup></p>
<p><a href="http://msdn.microsoft.com/en-us/library/hh229160(v=VS.103).aspx">Defer</a> makes a <em>hot</em> observable <em>cold</em>.</p>
<p>The <strong>Defer</strong> operator allows us to add subscription side effects to a <em>hot</em> observable, thus making it <em>cold</em>.</p>
<p><strong>Defer</strong> also allows us to convert invocation side effects into subscription side effects; e.g., given a function that returns a <em>hot</em> observable like <a href="http://msdn.microsoft.com/en-us/library/hh211971(v=VS.103).aspx">Start</a> or a C# 5.0 <em>async</em> method that returns a <strong>Task<T></strong>, which you then convert into an observable with <a href="http://msdn.microsoft.com/en-us/library/system.reactive.threading.tasks.taskobservableextensions.toobservable(v=vs.103).aspx">ToObservable</a>, you can wrap either function in <strong>Defer</strong> to change its invocation side effects into subscription side effects, thus creating a <em>cold</em> observable from a <em>hot</em> function.</p>
<p>Alternatively, you can change the temperature of a <em>hot</em> observable by combining it in various ways with a <em>cold</em> observable. For example, if you <strong>Concat</strong> a <em>hot</em> observable to a <em>cold</em> observable, then the result is a <em>cold</em> observable, by our new definition, because the subscription side effects of the <em>cold</em> observable are prepended onto the <em>hot</em> observable. If you were to apply the <strong>Merge</strong> operator instead, then the result would also be a <em>cold</em> observable because, again, the new observable retains the <em>cold</em> observable's subscription side effects. Remember, it's the subscription side effects that are important, which is why combining a <em>hot</em> observable with a <em>cold</em> observable in such a way that the subscription side effects of the <em>cold</em> observable are preserved yields a <em>cold</em> observable.</p>
<p>Notice, however, that converting from <em>cold</em> to <em>hot</em> simply adds broadcasting behavior, while converting from <em>hot</em> to <em>cold</em> relies on the addition of subscription side effects. In other words, going from <em>cold</em> to <em>hot</em> is as simple as calling one operator, but going in reverse requires side effects to be added.</p>
<p>In the previous section, we left wondering which assumption is best for an observable with an unknown temperature: <em>cold</em> or <em>hot</em>. Perhaps we can answer that now by examining the consequences of making wrong assumptions with respect to temperature conversions.</p>
<p>When we need a <em>hot</em> observable, assuming that it's already <em>hot</em> and being wrong means that subscription side effects are duplicated, which breaks the semantics of our query; therefore, let's assume that every observable is <em>cold </em>and apply <strong>Publish</strong><em>.</em> When we're wrong, we'll end up applying broadcast behavior to a <em>hot</em> observable, which would simply have no effect. That's 1 point for assuming that observables are <em>cold</em>, because when we're wrong, applying <strong>Publish </strong>does no real harm.<sup><a href="#HCObCite5">5</a></sup></p>
<p>When we need a <em>cold</em> observable, assuming that it's already <em>cold</em> and being wrong means that subscription side effects won't be duplicated, which breaks the semantics of our query; therefore, we must assume that every observable is <em>hot</em> and... do what? Remember, the semantics of our query aren't to introduce new subscription side effects, we want to duplicate the subscription side effects of the observable that was handed to us. We can't make a <em>hot</em> observable <em>cold</em> without introducing subscription side effects; therefore, all we can do is assume that the observable is already <em>cold</em> and hope for the best! That's 2 points for <em>cold</em>, 0 points for <em>hot</em>.</p>
<p>In summary:</p>
<p style="padding-left: 30px;"><strong>We must assume that any observable with an unknown temperature is <em>cold</em>.</strong></p>
<p>In other words, it's safest to assume that any given <strong>IObservable<T></strong> may cause subscription side effects because it's easy to broadcast subscription side effects when necessary, but once broadcast it's impossible to reverse it. There's no way to force a broadcasting observable's <strong>Subscribe</strong> method to cause subscription side effects that were already broadcast.</p>
<p>Note that there is a way to reverse the broadcast behavior of an <strong>IConnectableObservable<T></strong>: simply dispose of the object that was returned by the <strong>Connect</strong> method. In fact, that's exactly how <strong>RefCount</strong> works. But this can't be done with any <strong>IObservable<T></strong>. Even trying to cast it to <strong>IConnectableObservable<T></strong> won't help because casting doesn't give you a reference to the disposable that was returned by <strong>Connect</strong>.</p>
<p>Given that it's safest to assume that any unknown <strong>IObservable<T></strong> is <em>cold</em>, it follows that sometimes we're going to be wrong. We should probably relax our previous definition of <em>cold</em> to account for that fact.</p>
<p>Here are our latest definitions: </p>
<p style="padding-left: 30px;"><em>Hot</em> observables <span style="text-decoration: underline;">do not</span> cause subscription side effects.</p>
<p style="padding-left: 30px;"><em>Cold</em> observables <span style="text-decoration: underline;">may</span> cause subscription side effects.</p>
<p>That should cover all possibilities.</p>
<h1>Classification of Subscription Side Effects</h1>
<p>A subscription side effect can be classified as any of the following.<sup><a href="#HCObCite6">6</a></sup></p>
<ul>
<li><strong>Synchronous</strong></li>
<ul>
<li><strong>Notification<br /></strong>E.g., directly calling <strong>OnNext</strong>, <strong>OnError</strong> or <strong>OnCompleted</strong>.<br />(Technically, notifications are always <strong>Asynchronous </strong>in Rx due to its implicit use of the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.concurrency.currentthreadscheduler(v=VS.103).aspx">CurrentThreadScheduler</a> to schedule subscriptions, though we'll ignore that fact and define <strong>Synchronous</strong> in relation to the outer-most subscription only, where synchronously calling <strong>OnNext</strong>, <strong>OnError</strong> or <strong>OnCompleted </strong>actually blocks <strong>Subscribe</strong> from returning.)</li>
<li><strong>Out-of-band<br /></strong>E.g., directly assigning a field, creating a large object in memory, executing a CPU-intensive computation or (synchronously) deleting a file on disc.</li>
</ul>
<li><strong>Asynchronous</strong></li>
<ul>
<li><strong>Notification<br /></strong>E.g., using an async mechanism, such as <strong>Task</strong> or <strong>IScheduler</strong>, to schedule calls to <strong>OnNext</strong>, <strong>OnError</strong> or <strong>OnCompleted</strong>.</li>
<li><strong>Out-of-band<br /></strong>E.g., making a web request or reading a file on disc. Often these kinds of operations are used for <strong>Asynchronous Notification </strong>as well.</li>
</ul>
<li><strong>Composition<br /></strong>Subscribing to another <em>cold</em> observable that causes its own subscription side effects, either synchronously or asynchronously.</li>
<li><strong>Computation<br /></strong>Executing costly or side-effecting code for each notification; e.g., a costly projection via <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.select(v=VS.103).aspx">Select</a> or imperative side effects via <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.do(v=VS.103).aspx">Do</a>.</li>
</ul>
<p>Perhaps these classifications could be useful when documenting operators.</p>
<p>For example, the documentation for the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.range(v=vs.103).aspx">Range</a> overload without an <strong>IScheduler </strong>parameter could state that it returns an observable that causes <strong>Synchronous </strong><strong>Notification</strong> subscription side effects. The overload with an <strong>IScheduler </strong>parameter may cause <strong>Synchronous </strong>or<strong> Asynchronous </strong><strong>Notification </strong>subscription side effects, depending upon the specified <strong>IScheduler</strong>; this is similar for all operators that are overloaded with an <strong>IScheduler</strong> parameter.</p>
<p>The documentation for the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.interval(v=VS.103).aspx">Interval</a> overload without an <strong>IScheduler</strong> parameter could state that it returns an observable that causes <strong>Asynchronous </strong><strong>Notification </strong>subscription side effects.</p>
<p>The documentation for the <a href="http://msdn.microsoft.com/en-us/library/hh229160(v=vs.103).aspx">Defer</a> operator could state that it returns an observable that may cause <strong>Synchronous Out-of-band </strong>subscription side effects, depending upon the specified function. It could also state that it may cause <strong>Composition </strong>subscription side effects, which basically means that it inherits the subscription side effects of the observable that is returned by the specified function.</p>
<p>The documentation for the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.select(v=VS.103).aspx">Select</a> operator could state that it returns an observable that may cause <strong>Composition </strong>subscription side effects, which basically means that it inherits the subscription side effects of the <em>source</em>. It could also state that it may cause significant <strong>Computation </strong>side effects, depending upon the specified <em>selector</em> function.</p>
<p>Most of these terms should be self-explanatory by now; however,<strong> Computation</strong> is particularly interesting since I haven't mentioned it yet. I consider a <em>computation subscription side effect</em> to be:</p>
<p style="padding-left: 30px;">Any effect beyond an observable's subscription and notification mechanisms that occurs for each notification.</p>
<p>The <em>notification mechanism</em> is the minimally required effects for notifying; i.e., directly calling <strong>OnNext</strong>, <strong>OnError</strong> or <strong>OnCompleted </strong>are the primary effects of notification. Anything else is a computational side effect.</p>
<p>Although this kind of side effect is part of an observable's computation, it won't occur until subscription. <strong>Subscribe</strong> is essentially the beginning of the computation, thus subscription side effects are technically computation side effects. But since subscription side effects are the focus of temperature, that's why I refer to computation side effects as a kind of subscription side effect, in the sense that computation side effects don't occur until an observer subscribes.</p>
<p><em>Computation side effects</em> are part of the definition of <em>cold</em> observables, though it basically means that applying any computational or side-effecting operator to a <em>hot</em> observable converts it into a <em>cold </em>observable; e.g., applying <strong>Select</strong> to a <em>hot</em> observable means that all observers will receive different notifications, generated specifically for them, which is the common sense definition of <em>cold</em>. That's not a very useful definition of <em>cold</em>, so I propose to separate the notion of computation side effects from subscription side effects and to exclude them from the new definition of <em>cold, </em>introducing new terms: <em>active</em> and <em>passive</em>. This separation allows a <em>hot</em> observable to be referred to as <em>hot</em> even if it causes <em>computation side effects</em>. And you can still apply <strong>Publish</strong> to broadcast the <em>computation side effects</em><em> </em>similar to how you'd publish a <em>cold</em> observable to make it <em>hot</em>.</p>
<p style="padding-left: 30px;"><strong>Passive</strong> observables <span style="text-decoration: underline;">do not</span> cause any significant <em>computation side effects</em>.</p>
<p style="padding-left: 30px;"><strong>Active </strong>observables <span style="text-decoration: underline;">do</span> cause significant <em>computation side effects</em>. Every notification may be computed with some relative cost.</p>
<p><strong>Select </strong>and <strong>Do </strong>are common examples of operators that return <em>active </em>observables.</p>
<p>These terms are context-sensitive, as indicated by use of the word "significant"<em></em>. An observable that is <em>passive</em> in one usage can be considered <em>active</em> in another. For example, a simple projection over an observable of integers, such as adding 5 to each value, probably isn't costly enough in terms of memory or performance to care if its computation side effects are duplicated. In contrast, a projection that calculates the factorial of each value might be costly enough in certain scenarios to consider publishing.</p>
<h1><a name="HCObConclusion"></a>Conclusion</h1>
<p>Temperature indicates the propensity of an observable to cause subscription side effects.</p>
<p>A subscription side effect is:</p>
<p style="padding-left: 30px;">Any effect beyond an observable's subscription mechanism.</p>
<p>Subscription mechanisms generally consist of storing an observer in a list or subscribing to other observables, and returning a disposable for unsubscription.</p>
<p>Examples of subscription side effects include: Calling <a href="http://msdn.microsoft.com/en-us/library/system.reactive.concurrency.ischeduler.schedule(v=vs.103).aspx">Schedule</a>, <a href="http://msdn.microsoft.com/en-us/library/dd782792.aspx">OnNext</a>, <a href="http://msdn.microsoft.com/en-us/library/dd781657.aspx">OnError</a>, <a href="http://msdn.microsoft.com/en-us/library/dd782982.aspx">OnCompleted</a>, <a href="http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.getenumerator.aspx">GetEnumerator</a> or <a href="http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext.aspx">MoveNext</a>, mutating a field, creating an object in memory, running a CPU-intensive computation, sending a web request, reading a file, ending a process, formatting your C drive, or really anything else that you can think of that isn't merely the <em>subscription mechanism</em>.</p>
<p style="padding-left: 30px;"><em>Hot</em> observables <span style="text-decoration: underline;">do not</span> cause subscription side effects.</p>
<p style="padding-left: 30px;"><em>Cold</em> observables <span style="text-decoration: underline;">do</span> cause subscription side effects; however, we must assume that any observable with an unknown temperature is <em>cold</em>, and sometimes that assumption will be wrong; therefore, a more accurate definition is:</p>
<p style="padding-left: 30px;"><em>Cold</em> observables <span style="text-decoration: underline;">may</span> cause subscription side effects.</p>
<p>Again, we must assume that any observable with an unknown temperature is <em>cold</em>.</p>
<p>In the simplest case, an observable may be permanently <em>hot</em> or permanently <em>cold</em>, though some observables change their temperature over time so that different observers may get different temperatures; therefore:</p>
<p style="padding-left: 30px;">The temperature of an observable is relative to the time of subscription.</p>
<p>Temperature is also relative to the kind of subscription side effect; however:</p>
<p style="padding-left: 30px;">In general, the terms <em>hot</em> and <em>cold</em> cover all kinds of subscription side effects, including notifications.</p>
<p style="padding-left: 30px;"><strong>Replay</strong>, <strong>PublishLast</strong>, and <strong>Publish</strong> overloads with an <em>initialValue </em>parameter return observables that, once connected, are <em>cold </em>for observers that have missed notifications yet <em>hot</em> with respect to any other kind of subscription side effect.</p>
<p>We must also consider an observable's <em>computation side effects</em>. A <em>computation side effect</em> is:</p>
<p style="padding-left: 30px;">Any effect beyond an observable's subscription and notification mechanisms that occurs for each notification.</p>
<p>Technically subscription side effects are initial computation side effects, although I've separated these concepts so that <em>hot</em> and <em>cold</em> only refer to subscription side effects, thus ensuring that <em>hot</em> is a more useful term. As a result, the phrase <em>computation side effects </em>can be applied to either <em>hot</em> or <em>cold</em> observables. I've assigned the following terms:</p>
<p style="padding-left: 30px;"><em>Passive</em> observables <span style="text-decoration: underline;">do not</span> cause any significant <em>computation</em> side effects.</p>
<p style="padding-left: 30px;"><em>Active</em> observables <span style="text-decoration: underline;">do</span> cause significant <em>computation</em> side effects.</p>
<p>The significance of computation side effects on performance is relative to the operation, query or application. What is significant in one context may be insignificant in another.</p>
<p>Now I can finally answer the original questions from the top of the post with absolute precision and certainty.</p>
<h1><strong>What <span style="text-decoration: underline;">really</span> makes an observable <em>hot</em> or <em>cold</em>?</strong></h1>
<p>Short answer:</p>
<p style="padding-left: 30px;">An observable's <em>temperature</em> is its propensity to cause <em>subscription side effects</em>.</p>
<p>Long answer:</p>
<p style="padding-left: 30px;"><em>Hot</em> observables <span style="text-decoration: underline;">do not</span> cause subscription side effects.</p>
<p style="padding-left: 30px;"><em>Cold</em> observables <span style="text-decoration: underline;">may</span> cause subscription side effects.</p>
<p>In addition, there are two related concepts that may be applied to both <em>cold</em> and <em>hot</em> observables:</p>
<p style="padding-left: 30px;"><em>Passive</em> observables <span style="text-decoration: underline;">do not</span> cause any significant <em>computation</em> side effects.</p>
<p style="padding-left: 30px;"><em>Active</em> observables <span style="text-decoration: underline;">do</span> cause significant <em>computation</em> side effects.</p>
<h1><strong>Why should I care?</strong></h1>
<p>You need to be aware of whether subscribing to an observable multiple times is going to duplicate side effects; i.e., <em>cold</em> behavior.</p>
<p>When defining a query that references the same observable multiple times, you'll typically want to broadcast notifications among the operators to ensure that they observe the same exact notifications. In other words, you want a <em>hot</em> observable. A <em>cold</em> observable may generate different notifications for each observer. You'll also want to broadcast other subscription side effects; e.g., given a <em>cold</em> observable that makes a web request each time an observer subscribes, you don't want two operators in the same query to make two separate web requests.</p>
<p>Alternatively, sometimes you want duplicate subscription side effects in your queries; e.g., given a <em>cold</em> observable that makes a web request each time an observer subscribes, applying the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.retry(v=VS.103).aspx">Retry</a> operator means that you want to keep making web requests until one succeeds. The very purpose of the <strong>Retry</strong> operator is to duplicate subscription side effects. It's perhaps a fairly common mistake to pass a <em>hot</em> observable to <strong>Retry </strong>and then wonder why <a href="http://fiddler2.com/home">Fiddler</a> isn't showing a second web request after the first attempt failed.</p>
<p>Furthermore, you must consider <em>computation side effects</em> to determine whether they may have a noticeable performance impact on your query. If they do, then you'll probably want to broadcast them as well.</p>
<h1><strong>How can I tell if an observable is <em>hot</em> or <em>cold</em>?</strong></h1>
<p>There's no way to be sure from an observer's point of view. Subscription side effects might be directly observable or they might not.</p>
<p>Furthermore, subscription side effects that generate notifications might be indistinguishable from the notifications that would be generated if you assumed that the observable is <em>hot</em>.</p>
<p>The only way to know for sure is to look at the <span style="text-decoration: line-through;">documentation</span> source code. :)</p>
<p>When in doubt, it's safest to assume that an unknown observable is <em>cold</em>.</p>
<h2>Temperature by Operator</h2>
<p>(You may want to review <a href="http://msdn.microsoft.com/en-us/library/hh242961(v=vs.103).aspx">Rx operators by category</a>, although it's somewhat outdated as of Rx 2.0).</p>
<p>All of the Rx generator methods return observables that are of course <em>cold </em>by definition: <strong>Return</strong>, <strong>Range</strong>, <strong>Timer</strong>, <strong>Interval</strong>, <strong>Generate </strong>and <strong>Create</strong>.</p>
<p>There are 4 additional generators that are kind of edge cases: <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.empty(v=VS.103).aspx">Empty</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.throw(v=VS.103).aspx">Throw</a> are<em> cold; </em><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.start(v=vs.103).aspx">Start</a> is <em>cold</em> too, but we'll get back to it later; <a href="http://msdn.microsoft.com/en-us/library/hh211979(v=vs.103).aspx">Never</a> is technically <em>hot</em>, but it doesn't really matter.</p>
<p>In general, it's safe to assume that Rx's built-in conversion operators for .NET events return <em>hot </em>observables; e.g., <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromevent(v=vs.103).aspx">FromEvent</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx">FromEventPattern</a>. In reality, there's no guarantee. For example, you can define a custom .NET event and implement an <em>add</em> method that synchronously invokes each handler that it receives. That event would convert into a <em>cold</em> observable! Luckily, events generally don't do strange things like that, so it's safe to assume that they are <em>hot</em>.</p>
<p>You can be sure that <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.replay(v=VS.103).aspx">Replay</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publish(v=VS.103).aspx">Publish</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.publishlast(v=VS.103).aspx">PublishLast</a> overloads that return <strong>IConnectableObservable<T></strong> are <em>hot </em>until you call <strong>Connect</strong>, though after <strong>Connect</strong> it's more complicated. <strong>Publish</strong> overloads without an <em>initialValue</em> parameter are always <em>hot</em>. <strong>Replay</strong>, <strong>PublishLast</strong>, and <strong>Publish</strong> overloads with an <em>initialValue </em>parameter, become <em>cold </em>when <strong>Connect </strong>is called since they introduce a race condition.</p>
<p>Each of those operators also have overloads that accept a <em>selector</em> function. The <em>selector</em> overloads return <em>cold</em> observables, though the observable passed to the <em>selector</em> function is similar to above. When the <em>selector</em> is called, the observable passed in is <em>hot</em>, but when the <em>selector</em> returns, the observable passed in is automatically connected and starts to behave as described previously.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromasyncpattern(v=VS.103).aspx">FromAsyncPattern</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.toasync(v=VS.103).aspx">ToAsync</a> return functions that return observables similar to <strong>PublishLast</strong>, but connected when the function is invoked. It's safest to assume that the observable is <em>cold</em>, just like <strong>PublishLast</strong>. You can think of the function as a parameterized connectable since it acts like the <strong>Connect</strong> method of <strong>IConnectableObservable<T></strong>.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.start(v=vs.103).aspx">Start</a> is similar to <strong>ToAsync</strong> and <strong>PublishLast</strong>, though it's not connectable, thus it's safest to assume that it returns a <em>cold</em> observable.</p>
<p><strong>Task </strong>and <strong>T</strong><strong>ask<T> </strong>are themselves <em>hot,</em> although the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.threading.tasks.taskobservableextensions.toobservable(v=vs.103).aspx">ToObservable</a> conversion returns an observable similar to <strong>PublishLast</strong>, thus it's safest to assume that <strong>ToObservable</strong> returns a <em>cold</em> observable.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/hh229160(v=vs.103).aspx">Defer</a> returns a <em>cold </em>observable, though actually it depends on whether it causes subscription side effects or not. Typically the only reason that you wouldn't know whether it causes subscription side effects is when you use it to defer an unknown function that returns an observable. The unknown function might not cause any invocation side effects and may return an observable that doesn't cause any subscription side effects, thus <strong>Defer</strong> may simply be passing through a <em>hot</em> observable. That behavior indicates either an edge case or improper usage of the operator.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.startwith(v=vs.103).aspx">StartWith</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.sample(v=vs.103).aspx">Sample</a> and <a href="http://msdn.microsoft.com/en-us/library/hh229585(v=vs.103).aspx">Using</a> return <em>cold</em> observables. They all cause subscription side effects.</p>
<p>All of the remaining operators inherit <em>temperatures</em> from their source observables. Well, maybe not all remaining operators – I may have missed a couple when I reviewed them for this post ;)</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.select(v=VS.103).aspx">Select</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.do(v=VS.103).aspx">Do</a>, <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.aggregate(v=VS.103).aspx">Aggregate</a> and <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.scan(v=VS.103).aspx">Scan</a> may cause significant <em>computation side effects</em>. (See above for a description of <em>computation side effects</em>.)</p>
<p>Technically, any operator with a delegate parameter that's invoked for some or all notifications may cause significant <em>computation side effects</em>. There are many more operators like this than what I've listed above.</p>
<p><strong>Remotable</strong> causes significant <em>computation side effects</em>, assuming that you consider transmitting notifications through the .NET remoting infrastructure to be significant in terms of its performance implications.</p>
<h1><strong>How can I change the <em>temperature</em> of an observable?</strong></h1>
<p><em>Subscription side effects:</em><em></em></p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;">Simple Conversions</span></p>
<p style="padding-left: 30px;"><strong>Publish</strong> is useful for broadcasting <em>subscription side effects</em>. It makes a <em>cold</em> observable <em>hot</em>.</p>
<p style="padding-left: 30px;"><strong>Defer </strong>is useful for adding <em>subscription side effects </em>and for converting <em>invocation side effects</em> into <em>subscription side effects</em>. It makes a <em>hot </em>observable or observable-returning function <em>cold.</em></p>
<p style="padding-left: 30px;">Operators such as <strong>Merge</strong> and <strong>Concat</strong>, among many other combining/zipping/joining operators, can add <em>subscription side effects </em>to <em>hot</em> observables by combining them with <em>cold</em> observables, thus returning <em>cold</em> observables.</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;">Complex Conversions</span></p>
<p style="padding-left: 30px;">Using a <strong>Subject</strong> as an observer makes a <em>cold</em> observable <em>hot</em>, though it's not a good reason to use subjects. See <a href="https://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx"><em>my previous post on subjects</em></a> for details<em><span style="color: #09480a;">.</span></em></p>
<p style="padding-left: 30px;"><strong>Replay</strong>, <strong>PublishLast</strong>, and <strong>Publish</strong> overloads with an <em>initialValue</em> parameter, are useful for broadcasting subscription side effects while also replaying notifications to observers that missed them. These operators make <em>cold</em> observables <em>hot</em> in terms of all <em>subscription side effects</em> except for missed notifications; therefore, they remain <em>cold</em> in regard to missed notifications.</p>
<p><em>Computation side effects:</em></p>
<p style="padding-left: 30px;"><strong>Publish</strong> is useful for broadcasting <em>computation side effects</em>. Whether or not you want to broadcast them depends upon their significance with respect to resource usage and/or performance and how they compare to your operation, query or application.</p>
<p style="padding-left: 30px;">Operators such as <strong>Select</strong> and <strong>Do</strong>, among many others, are useful for adding <em>computation side effects</em>.</p>
<p> </p>
<hr /><ol>
<li><a name="HCObCite1"></a>Not in a mathematical or academically formal sense. Posting the idea to my blog allows me to focus on rationalizing it and elicits proper feedback. Though if anybody can explain it in a mathematically formal sense, then by all means please describe it in the comments.</li>
<li><a name="HCObCite2"></a>Serial behavior is described in §§4.2, 6.7 of the <a href="http://go.microsoft.com/fwlink/?LinkID=205219">Rx Design Guidelines</a> document. Note that <strong>FromEventPattern</strong> does not enforce this contract, so it's either the raiser's responsibility to ensure that it does not raise the event concurrently or it's an observer's responsibility to apply the <a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.synchronize(v=VS.103).aspx">Synchronize</a> operator.</li>
<li><a name="HCObCite3"></a>Obviously not in any kind of official capacity. I just need a way to reference these new concepts now. I'd be happy to adopt better or formal naming conventions if they already exist or will emerge in the future.</li>
<li><a name="HCObCite4"></a><strong>Publish, PublishLast</strong> and <strong>Replay</strong> also have convenient overloads accepting a <em>selector</em> function that acts as a scoped query in which the original observable is <em>hot</em>, thus allowing callers to avoid having to deal with connection themselves. The <em>temperature</em> of an observable returned by these overloads is <em>cold </em>because it publishes and connects as a subscription side effect.</li>
<li><a name="HCObCite5"></a>Perhaps it would be nice if Rx's implementation of <strong>Publish</strong> could somehow detect whether an observable is either <strong>Subject<T></strong> or it's hidden by the <strong>AsObservable</strong> operator, in order to avoid introducing yet another subject into the query unnecessarily. But that would be an internal optimization and it doesn't change the fact that publishing a <em>hot</em> observable probably has no noticeable performance impact in most programs.</li>
<li><a name="HCObCite6"></a>I've made all of these terms up myself. I'll gladly replace them with formal terms if someone provides them to me in the comments.</li>
</ol>
https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx
https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx#commenthttps://davesexton.com/blog/post.aspx?id=5adc023f-6c36-482c-bc9d-083fde49b2f6Mon, 05 Aug 2013 00:45:00 +0000.NETRxdavehttps://davesexton.com/blog/pingback.axdhttps://davesexton.com/blog/post.aspx?id=5adc023f-6c36-482c-bc9d-083fde49b2f64https://davesexton.com/blog/trackback.axd?id=5adc023f-6c36-482c-bc9d-083fde49b2f6https://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx#commenthttps://davesexton.com/blog/syndication.axd?post=5adc023f-6c36-482c-bc9d-083fde49b2f6