Subscribe: Dave Sexton's Blog : C#
Added By: Feedage Forager Feedage Grade B rated
Language: English
cold  documentation  iobservable  new  notifications  observable  observables  operator  project  sect  source  tie  white tie  white 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Dave Sexton's Blog : C#

Dave Sexton's Blog

on C# and Rx, mostly


Monads, and Comonads, and LINQ! Oh, my!

Wed, 19 Apr 2017 23:19:00 +0000

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. 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 Category Theory. Over The Rainbow Our journey begins with a few familiar types in a probably unfamiliar categorization. Sync Async Monad IEnumerable IObservable Comonad Lazy Task Don’t worry if you don’t understand these concepts yet, we’ll meet them again later... IEnumerable is the list monad. IObservable is the continuation monad. Task is the continuation comonad. Lazy is the singleton comonad (for lack of a better name). 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. Monads have bind and unit functions. Comonads have cobind and extract functions. Bind Unit IEnumerable SelectMany; a.k.a., flatMap Constructors of Array, List, etc. IObservable SelectMany; a.k.a., flatMap Observable.Return; a.k.a., just Cobind Extract Task ContinueWith; a.k.a., then get_Result (a property named Result) Lazy ? get_Value (a property named Value) You may have noticed that Lazy is incomplete. Can we define a cobind function for Lazy? What would it look like? What would it do? And what’s the relationship between monads and comonads? Is there a pattern? 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 cobind for Lazy. “Professor Marvel Never Guesses” Let's start by examining the bind function for IEnumerable. Here’s its signature: public static IEnumerable SelectMany(this IEnumerable source, Func> selector) So the bind function takes an instance of the monadic type for which it's defined, in this case IEnumerable, and a function that projects the element type, T, into another instance of the monadic type, IEnumerable. 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”. Well, we have a selector function that accepts a T, but we don’t have an instance of T yet. Since the source is a sequence, it seems that we must invoke the selector function for each T that it contains. So let's start there. We’ll do foreach over source and apply selector to each value. public static IEnumerable SelectMany(this IEnumerable source, Func> selector){ foreach (var value in source) { var results = selector(value); // ... }} Great, we're done with the Select (a.k.a., map) part. Now let’s check the return value. The selector returns an IEnumerable for a [...]

Reactive Reactive! Read all about it!

Fri, 10 Oct 2014 17:23:00 +0000

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. Reactive Reactive Nope, it's not a typo. It’s like acceleration to speed, or C# to IL, or higher-order functions to functions. Sometimes fast isn't fast enough.  Sometimes abstract isn't abstract enough.  Sometimes functions aren't... functiony enough? Sometimes Rx operators aren’t reactive enough. Many operators in Rx force us to supply static arguments, resulting in an operator's static behavior.  By static I mean upfront, immutable, unvarying values; e.g., typically scalar primitives like Int32, TimeSpan and DateTimeOffset.  Furthermore, stateful operators with static parameters prevent us from varying behavior without a potential loss of data. 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: var xs = observable.Skip(5); 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? Defer doesn't work if we want to subscribe now. We could attempt to change the value, without causing side effects, by writing some complicated dance within the Publish 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 Skip operator? Ok, easy solution, we define a new overload: public static IObservable Skip(this IObservable source, IObservable count); 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 count whenever we want to change it. Subscribe now, decide later. 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 count.1 But wait, are the values in count even necessary anymore?  It seems overly complicated.  Can't we just generalize our solution in terms of time? public static IObservable SkipUntil(this IObservable source, IObservable other); In other words, instead of an observable count, we'll simply use an observable.  T is ignored.  When the observable signals or terminates, the operator stops skipping. This "reactive reactive" pattern is already in use by several operators in Rx, such as SkipUntil and TakeUntil as of Rx 1.0, and some overloads of Window, Buffer, Throttle, Sample, Delay and Timeout as of Rx 2.0, but upon further inspection it seems that Rx is potentially missing a lot of similar opportunities. Reactive Overloads for Static Parameters Merge – A Case Study In one such example, we can see how data loss is a critical problem.  The Merge(maxConcurrency) operator is very powerful, but its behavior is static.  While inner observables are pushed in, Merge 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 Merge's observable, reforming the query with a new static argument and resubscribing; however, in the process any observables e[...]

I'm On Twitter

Sun, 28 Sep 2014 07:10:00 +0000

Just thought I'd mention that I'm attempting to be a bit less antisocial.

Follow me on Twitter @IDaveSexton

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.

Still, though, I'd rather be coding.

Reactive Extensions: The Power of T

Sat, 13 Sep 2014 03:42:00 +0000

The T in IObservable is more powerful than you may realize.Structural TT carries data, its most obvious purpose.T can be any type, such as Int32, String or MyAmazingObject.T can be void, as in System.Reactive.Unit.T can be anonymous, as in:  new { Value = "T", Awesome = true }T can be a choice, as in Either, which also seems to fix so-called "glitches".T can be a group of T, as in IObservable>; e.g., GroupBy.T might be there or it might not, as in Maybe.Meta TT carries notification.  Observables notify observers by pushing T.T can be notification reified, as in Notification.T can be collection change notifications, as in CollectionNotification.T can be directed mutations, as in CollectionModification.Temporal TT carries time.  Observables push T asynchronously (though sequentially-§4.2).  Even pushing synchronously takes time though.T can be a point in time; implicitly, the time at which it's observed, as in Amb or CombineLatest.T can be time reified, as in Timestamped, TimeInterval, Recorded or simply DateTimeOffset.Temporal Window TT carries duration.  A window is a duration of time that has a start and maybe an end.T can start a window, as in Join, GroupJoin, Window or Buffer.T can end a window, as in Join, GroupJoin, Window(closingSelector), Buffer(closingSelector), etc.T can be a window, as in IObservable>.T can be the end of time, as in that which precedes it, interpreted relative to the time of subscription (e.g., Timer), relative to a previous T (e.g., Interval or Throttle), or relative to some out-of-band time (e.g., Sample).Channel TT can be a channel or callback.  Observers invoke T to affect an observable.T can be a delegate, as in Action or Func.T can be a subject, as in IObservable>.  This establishes a full duplex, asynchronous communication channel.  The observable is a singleton and both ends subscribe to the subject; e.g., a chat application. (See also this blog post.)Future TT can be the promise of a future T, as in IObservable>; although, it's somewhat redundant since IObservable is also a promise of a future T and it has a wider cardinality [0,∞].  Task's cardinality is strictly [0,1].ConclusionT carries data, notification, time and duration.  It can also have communication channel or promise semantics.  Best of all, T carries any additional semantics that you choose.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 T the attention that it deserves.  You may just find that the answer to your problem lies within how you make use of T.So, have I missed any categorically interesting uses for T?  How do you use T?[...]

NuGet Package for Sandcastle

Wed, 16 Jul 2014 04:53:00 +0000

Did you ever want to build Visual Studio-quality reference documentation from your XML code comments by simply referencing a NuGet package?Well now you can! The latest release of White Tie includes full support for generating documentation using Sandcastle. No configuration necessary. (You must install Sandcastle yourself though - see the details below). Add a reference to White Tie's NuGet Package and then simply build your project in Release mode to generate reference documentation. Details 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. 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 Sandcastle Guided Installer. The other options provided by the installer, such as SHFB Visual Studio Package, are not used by White Tie at all. Of course, you're free to install them anyway if you'd like. After you've installed Sandcastle, documentation is generated automatically when you build your project in Release 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, bin\Release\). In addition, White Tie packs the compiled help file into the NuGet package that it generates for your project as well. Documentation Configuration 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. 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. The configuration options for generating documentation (as of White Tie v1.3.5) are as follows.See the official documentation for details. MSBuild Properties $(BuildDocumentationEnabled) $(DocumentationProjectName) $(DocumentationProductName) $(DocumentationCompanyName) $(DocumentationCopyright) $(DocumentationVersion) $(DocumentationProjectSummary) $(DocumentationRootTopicEnabled) $(DocumentationRootTopicTitle) $(DocumentationFeedbackEmail) $(DocumentationFeedbackLinkText) $(DocumentationHeader) $(DocumentationFooter) $(DocumentationStyle) $(DocumentationLanguage) MSBuild Items @(DocumentationContent) @(DocumentationImage) @(DocumentationNamespace) @(DocumentationSource) @(DocumentationReference) @(DocumentationFrameworkReference) Undocumented Sandcastle Configuration Properties and Items Advanced users of Sandcastle may be wondering how to configure Sandcastle's many other options that are missing from the list above. 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 Roslyn documentation generator and in the future I'd li[...]


Sun, 29 Jun 2014 01:07:00 +0000

In this post, I'll introduce you to my new OSS project called White Tie and I'll describe how it relates to Rxx a bit. I'll also introduce you to a new feature of another OSS project of mine, Visual Studio Settings Switcher.  This new feature allows you to easily share VS settings files with your solution, and OSS contributors to easily take advantage of it. 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. 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. Your feedback is welcome. White Tie I've recently created the White Tie project on CodePlex.  I like to think of it as "formal buildware for use after 6PM". 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. 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 Configuration documentation for details.) White Tie is delivered as a NuGet package, so it's really easy to integrate into your projects.  Simply build your project in Release 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 here for details about build errors caused by missing assembly-level attributes in new projects. One of White Tie's key features is the NuGetFlavor item group.  By adding project references as NuGetFlavor items, rather than as ProjectReference items, White Tie will automatically include the referenced projects' output into the primary project's NuGet package. For example, let's say that you have a primary class library project called Project A, which targets the full .NET Framework 4.5.1.  If you add a NuGet reference to White Tie, then whenever Project A is built in Release mode (by default), White Tie will generate a NuGet package for Project A.  Now let's say that you also have a portable class library project called Project B, which targets a portable profile that includes Windows 8 and Windows Phone 8.  Project B is intended to be the same as Project A, only targeting different platforms.  You might refer to Project B as a "flavor" of Project A.  Now you can simply edit the project file of Project A to add a NuGetFlavor item that points to the project file of Project B.  Whenever you build Project A in Release mode, White Tie ensures that Project B is built as well, and it also includes the portable library built by Project B into the NuGet package that it builds for Project A, and in the correct target framework subfolder. White Tie offers several more features and configuration options.  Take a look at the documentation to get started, and let me know what you think. White Tie's Origins and Future 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 Rxx project, such as its support for NuGet, though some features even predate Rxx. Since&n[...]

Checklist for Creating Rx Operators

Wed, 30 Apr 2014 08:16:00 +0000

This blog post was originally posted here 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. Prerequisites Know the existing Rx Design Guidelines document.  You will find references to it throughout this checklist. Know how to properly use existing Rx operators.  This checklist is not 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. For the purposes of this checklist, an observable operator is any instance, static or extension method that returns IObservable, including those that are typically considered to be static factory methods or combinators. (§6.3) Also for the purposes of this checklist, the term observable refers to any local variable, parameter or member that is of the type IObservable or a delegate to a function that returns an instance of IObservable. Checklist 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. Behavior Implement your new operator by composing existing Rx operators together, whenever possible; otherwise, just use any overload of Observable.Create.  Do not implement IObservable yourself.  (§§6.1, 6.2) Ensure that your operator satisfies the Rx grammar and assume that IObservable parameters are well-behaved. (§§4.1, 6.6) OnNext* (OnCompleted|OnError)? Ensure that your operator serializes notifications and assume that IObservable parameters are well-behaved. (§§6.7, 6.8, 4.2) IObservable is a model for concurrency; therefore, assume that observable parameters execute concurrently when Subscribe 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) Assume that IObservable parameters are cold. Convert their temperature before subscribing multiple times to avoid duplicating subscription side effects, if your operator does not have retry or repeat semantics.  (§5.10) Protect calls to user code.  (§6.4) Do not catch exceptions thrown by observers; i.e., calls to OnNext, OnError and OnCompleted. Implement lazy (deferred) execution when generating a cold observable.  Check arguments up front, but do not cause any side effects until Subscribe is called.  This includes scheduling work, iterating enumerable parameters, and mutating external state or parameters.  (§6.16) Implement unsubscription, and do it properly.  (§§6.17, 6.18) Parameterize scheduling when appropriate.  (§§6.9, 6.10, 6.11, 5.4) Avoid deep call stacks caused by recursion.  (§6.15) Watch for reentry when executing user code and assigning the result to a SerialDisposable.  Use the double indirection pattern to avoid the effects of race conditions. Performance and Memory Do not block.  Execute asynchronously instead.  (§6.14) Do not introduce extra asynchrony. Avoid the ObserveOn operator, whenever possible. Rely on your notification source, if any, to handle asynchrony itself; alternatively, consider offering parameterized schedulin[...]

Hot and Cold Observables

Mon, 05 Aug 2013 00:45:00 +0000

I've touched on the topic of observable temperature while answering questions on the Rx forum and in my previous post on subjects.  I tried explaining it more deeply in this particular discussion, but now I'm finally ready to provide a deep and comprehensive1 analysis in this blog post. I'll answer the following questions:  What really makes an observable hot or cold?Why should I care?How can I tell if an observable is hot or cold?How can I change the temperature of an observable? The analysis that follows is not intended for beginners, though you may find the following section and the conclusion to be informative.  You may also want to watch this first and look here for additional information. Common Sense We like to think of hot observables from two different perspectives as follows. From the perspective of observers, there's the potential to miss notifications.  Hot 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 IObservable or not.  In general, if I hand you an observable and tell you that it's hot, then as an observer you'd infer that you might have missed notifications that happened before you subscribed.  Pretty simple. From the perspective of observables, hot observables broadcast notifications to all observers.  The canonical example is converting an event into an observable; e.g., FromEventPattern.  If three observers subscribe to IObservable, then each observer will serially2 observe the same notifications, as opposed to observing different notifications or concurrent notifications. We like to think of cold observables from the same perspectives as follows. From the perspective of observers, there's the potential for each observer to get different notifications.  Cold 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 Create, which can asynchronously generate notifications whenever an observer subscribes. From the perspective of observables, cold observables won't generate notifications until an observer subscribes, and they generate notifications each time that an observer subscribes.  The canonical example is Range, which generates a range of numbers whenever an observer subscribes. In summary, common sense tells us that: Hot observables are always running and they broadcast notifications to all observers. Cold observables generate notifications for each observer. 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 hot and cold are well-defined terms based primarily on the concept of side effects.3 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. Uncommon Sense We know that an observable can be either hot or cold, but can they mix?  Can an observable be generated while broadcasting?  Can it be generated  and yet always running?  Can it be always running without broadcasting?  Can the temperature change dynamically? That last question is particularly interesting.  Can an observable change its temperature after an observer subscribes?  E.g., Observer E subscribes fir[...]

To Use Subject Or Not To Use Subject?

Sat, 22 Jun 2013 07:19:00 +0000

That is the question!  There appears to be some confusion on the web about whether or not Subject should be used, ever.  Tis a question oft asked by developers new to Rx after reading expert recommendations to avoid subjects, due to common misuse, yet subjects seem to persist an air of mystery even for seasoned reactive developers. First, a primer on Subjects.  Take a moment to read that. Done?  Great.  Let's continue... As you may already know, Erik Meijer doesn't like subjects.  End of discussion, right?  Wrong!  Erik doesn't like subjects to be used in place of purely functional alternatives.1 As Erik puts it: [Subjects] are the "mutable variables" of the Rx world and in most cases you do not need them. So let's enumerate the cases where we should and shouldn't use subjects. We'll start by examining two interesting properties of subjects: They implement IObservable and IObserver simultaneously, which makes them suitable for both output and input, respectively. They are hot.  (See also: Hot and Cold Observables) Thus to answer the question of whether we should use a subject when defining an observable (output) we must consider: the input; i.e., the source of the OnNext, OnCompleted and OnError notifications. the desired temperature of the generated observable; e.g., hot or cold. To determine whether or not to use a subject, start by asking yourself the following questions: what is the source of the notifications?  I.e., where do the values of T come from?  Who is responsible for calling OnNext? must observers share subscription side-effects or not?  I.e., does calling Subscribe execute some kind of initialization code each time it's called or does initialization occur once and its state is shared by every call to Subscribe? Let's answer all possible combinations of these 2 questions.  I'll provide more details and examples later in this post to explain why these answers make sense. Question 1:  What is the source of the notifications? The source can be one of two kinds: Let's call them external and local.  An external source is any observable or event that already exists outside of your code.  A local source is when you generate an observable from your code, kind of like defining and raising a custom .NET event.  More details on these distinctions later in this post. If the source is external, then do not use a subject. If the source is local, then do use a subject. Question 2:  Must observers share subscription side-effects or not? If not, then do not use a subject.  (Define a cold observable.) If yes, then do use a subject.  (Define a hot observable.) Let's enumerate all possible combinations:  The source is external and I want a cold observable. The source is external and I want a hot observable. The source is local and I want a cold observable. The source is local and I want a hot observable.  As you may have noticed, there are conflicts. What if you have an external source and you do want to share subscription side-effects? What if you have a local source and you do not want to share subscription side-effects? What if the temperature of an external source differs from the desired temperature? I believe these conflicts cause additional confusion among developers.  They seem to blur the line when it's appropriate or inappropriate to use subjects, though in fact the line is actually quite clear, as we'll soon see. Let's resolve these conflicts now. The source is external and I want a cold observable. If the source is cold, then use it as is.  You can also wrap it with Defer to add subscrip[...]

Bye Google Reader, Hello Windows RSS Platform

Tue, 04 Jun 2013 05:34:00 +0000

With the impending demise of iGoogle and Google Reader, which have been set to my web browser's home page for several years now, I had recently come to the realization that I was going to open IE one day and see an error message where iGoogle used to be.  All of my subscribed RSS feeds would be gone. I did some research to see what kinds of replacements were out there.  For me, RSS feeds provide topics of particular interest that may be worthy of exploring on the web, and my web browser's home page is the gateway to the web; therefore, I wasn't interested in using feed-reader software that runs outside of my browser.  Feeds contain hyperlinks that lead me into the browser, so I might as well read my feeds right on the home page. It seemed appropriate to begin my research by revisiting the Feeds tab in IE 10.  I had thought perhaps there have been improvements that could make it a viable replacement for Google Reader.  It didn't take long before I realized why I had chosen Google Reader several years ago and never switched to IE's built-in RSS feed support.  Alas, since I have no choice now but to change, I decided to research deeper into this feature of IE and see whether it may be worth using.  There were a few things I really liked about it: IE automatically detects feeds on web pages and lets you subscribe to them easily via a button on its Command Bar. IE opens feeds in a special reader allowing you to easily search, sort and filter.  It also provides a link to quickly subscribe or unsubscribe. IE lets you easily organize your feeds into folders. I'm sure you'd agree that the integrated experience is a huge plus; however, IE also has a few negatives: IE doesn't provide a "What's New?" kind of view; i.e., an aggregated view containing all of the latest unread items among all feeds. IE doesn't provide a way to quickly view a list of items in a selected feed without showing their contents. IE doesn't provide a way to mark a single item as read/unread. So it seems that IE has a great story for subscribing to and organizing feeds, though it really lacks in support for interacting with feeds.  The latter is extremely important to me, which is why I had originally chosen iGoogle as my home page for its Google Reader widget. But the story doesn't end there.  Digging deeper I discovered that IE builds its RSS features on top of a public Windows API called the Windows RSS Platform.   IE merely provides a GUI containing only a subset of the functionality offered by this platform.  That was great news!  I decided to write my own web page against this API.  I could set it as my home page and interact with my RSS feeds easily, similar to the Google Reader experience, while taking advantage of the integration and organizational features built-in to IE. These were my primary goals: Implement a stand-alone HTML page.  No server, no external scripts, no external style sheets, no external images. Target HTML5 in IE 10 (desktop mode only) for Windows 8. Touch input support. Use JavaScript to interact with the Windows RSS Platform APIs via Window's built-in ActiveX automation. Display 3 synchronized panels: Tree view shows all feeds organized into folders, similar to the Feeds tab in IE. Aggregate view containing all of the latest unread items; i.e., "What's New?" Content viewer for the selected item. I'm happy to report that my project was a success.  I worked on it all last weekend.  I even added several usability features that will hopefully make it appealing to others.  It relies heavily on jQuery, w[...]