Loading user information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading user information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements


Bart De Smet bdesmet Bart De Smet ​[MSFT::SQL::​Cloud​Programmabi​lity::Rx]
  • Bart De Smet: Interactive Extensions (Ix)

    @Jules: Thanks for your post. First things first: to be clear, you can write the time-based operations for IE<T> without any change to the type. Where we disagree is in the interpretation of time. Let's go into more details.

    First, a quick reminder about the duality between IE<T> and IO<T>. If you distill the essence of the interfaces using arrows, you get both isomorphisms (ignoring the aspect of resource maintenance, captured by IDisposable, since we only care about the data flow aspect):

    • IE<T> ~ () -> (() -> T | Exception | void)
    • IO<T> ~ ((T | Exception | void) -> ()) -> ()

    The only thing we did is reverse the arrows, and end up with the dual type. Interfaces are a mere manifestation of the lack of discriminated union types, and have a particular imperative feeling to it that some consider to be "more clear".

    With regards to the time notion now. Your interpretation of time is one that treats time as data. The universe you describe is one where Tuple<Time, T> is a coordinate in a n+1 dimensional space with n being the number of spatial coordinates and 1 reflecting the time dimension. The spatial coordinates are defined by the CLR type system and heap here: typeof(T) and the particular instance of the type. This approach is totally valid, and in fact we have it in Rx in the form of Timestamped<T>, which is isomorphic to Tuple<Time, T>.

    However, there's a different interpretation of time that relates to the control flow aspect of computation. Rather than associating time with data (by treating it as data itself), time can be related to the execution itself. In Rx, this is embodied by the IScheduler interface which carries a clock. In this world, the scheduler defines the universe of space (where things happen, e.g. on the thread pool), and time (when things happen, related to the scheduler's clock). Going back to machine architecture analogies, you could see the number of instructions executed (or the number of CPU clock ticks) as the clock.

    Operators like Timeout have been defined in terms of the latter interpretation where time is extrinsic to the data (observe the IScheduler parameter passed in). For example, upon arrival of an OnNext message, the scheduler can be invoked to run a timeout timer to monitor the next OnNext message coming down the pipe. In this worldview, time is associated with the execution of method calls. You can do a very similar thing for IE<T>, now based on the dual MoveNext method. Again, you observe the time behavior of the environment that's sending you the data by running a local timer (ignoring relativistic effects), measuring the time that elapses between method calls: the incoming MoveNext call and the time it takes for the environment to respond to the outgoing MoveNext request. To do so, you need to rely on a clock which is extrinsic to the data, e.g. provided by the IScheduler interface.

    That's not to say you can't define time-based operations using an intrinsic notion of time, e.g. based on Timestamped<T>. In that case, you're performing distance measurements and coordinate transformations on the data itself, which happens to carry time information. I invite the niners to think about all kinds of operators in terms of this (e.g. Select translates an object in space). This approach works very well for analysis of historical data, e.g. log data. However, you could do this too by using virtual time scheduling.

    The discussion where to put time is very similar to the one on where to put other aspects of the control flow such as exceptions. Do you treat those as code or as data? In Rx and Ix, we treat exceptions as control flow aspects (cf. OnError and the dual of MoveNext throwing) at the interface level (note for Ix: the C# language doesn't provide checked exceptions, hence it doesn't show up in the IR<T> interface explicitly). However, one can employ reification to treat those control flow mechanisms as part of the data flow, using operators like Materialize. Similarly, the time aspect can be moved from control flow to data flow using the Timestamp operator. Both treatments are valid, and it depends on your scenario which one is more convenient than the other.

    Finally, the discussion on extrinsic or intrinsic notion of time with regards to the data is one of the essential differences between Rx and StreamInsight. In the latter technology, every event carries its own notion of time (cf. CepStream<T>), including duration. In Rx, we model those things differently using the concept of reactive coincidence. Again, because both notions make sense, there are conversions possible between both worlds; e.g. StreamInsight has an IO<T>-based programming model exposed.

  • Bart De Smet: Interactive Extensions (Ix)

    In case you want to use NuGet to install Ix, look for the Ix_Experimental-Main and Ix_Experimental-Providers packages (following our naming convention used in Rx).

  • Rx Workshop: Introduction

    @exoteric: Ix has shipped again with improved operator parity, some extensions, and some cleanup. More information here.

  • Announcing the Official Release of Rx!

    @wkempf: You can still get System.Threading.dll from old releases (prior to 1.0.10425) and use it, but keep in mind the bits are provided as-is with no support.

  • Announcing the Official Release of Rx!

    @vesuvius: Still there, in the System.Reactive.Providers assembly. On NuGet, use the Rx-Providers package.

  • Reactive Extensions for JavaScript (RxJS)

    I've uploaded the demos over here. Notice this file includes the current version of RxJS. For future updates, keep an eye on the Rx home page.


  • Reactive Extensions for JavaScript (RxJS)

    Hi everyone,

    Thanks for watching. Our apologies once more for the technical issues with the projection, which are being diagnosed. If you have any questions about the content, don't hesitate to post them, and I'll check regularly to provide answers.


  • DevCamp 2010 Keynote - Rx: Curing your asynchronous programming blues

    @Thorium: Thanks for your interest. Please use the Rx forums for questions: http://social.msdn.microsoft.com/Forums/en-US/rx.

  • Programming Streams of Coincidence with Join and GroupJoin for Rx

    @dream: I produce my best code with little sleep, so I try to live such a rhythm Smiley. Nothing's more lovely to watch than a new day being born in the summer with the first traces of daylight appearing around 5AM through the 21st floor windows. I think I'm one of the lucky few to survive on little sleep (~4 hours on weekdays).

    Thanks for the kind words. Back to the bakery now, the oven is heating Wink.

  • Bart De Smet: MinLINQ - The Essence of LINQ

    @Sebastian Gregor: Your analysis is right. Concerning language syntax, one question is whether you want one particular control flow primitive (foreach) to know about some kind of multi-value simultaneous treatment (zip), or you want to shift that into its own construct. I'm more in the latter camp where first-class tuples (with pattern matching) allow one to combine all the needed building blocks. Here's what Zip looks like in hypothetical syntax where * is a suffix type constructor for sequence and (,) is tupling syntax both in the type world and the value world:

    (T1, T2)* Zip<T1, T2>(this (T1*, T2*) source);


    IEnumerable<Tuple<T1, T2>> Zip<T1, T2>(this Tuple<IEnumerable<T1>, IEnumerable<T2>> source);

    Notice the beautiful symmetry of the lightweight signature shown above. Zip takes a tuple of stars to a star of a tuples. Assume the following use:

    foreach (var (i, c) in (1..10, 'a'..'j').Zip())
        f(i, c);

    == (ignore expansion of start..end range expressions)

    foreach (var __t in Tuple.Create(new[] { 1, 2, ..., 10 }, new[] { 'a', 'b', ..., 'j' }).Zip())
        var i = __t.Item1;
        var c = __t.Item2;
        f(i, c);

    Now the question is whether or not you want the GetEnumerator pattern to work on a "tuple of stars". If so, the Zip() call becomes redundant (if "foreach" were to resolve against extension methods, you could even do this right now). However, there are other ways of combining two sequences, such as Rx's CombineLatest. So this lightweight explicitness could be considered a good thing.