locked
Dynamic RX? RRS feed

  • Question

  • Suppose I am building an application with user-defined "events" (e.g. application initializing, variable changed). Is it possible dynamically build Rx queries at runtime as I might LINQ queries? Pointers to examples greatly appreciated. Thanks.

     

    Dave
    Saturday, March 27, 2010 3:10 AM

Answers

  • Hi Dave,

    The contract for IObservable<T> is similar to IEnumerable<T> in that they both define a lazily-computed sequence of values.  The keyword here is "lazy".  It means that you can compose a query using fluent method call syntax without having to define it all in one place.  Then once the query is composed, however that may be, you can execute or subscribe to it.

    If that doesn't answer your question, then you may have to explain what you mean by "dynamically".

    - Dave S.


    http://davesexton.com/blog
    Saturday, March 27, 2010 3:33 AM
  • Hi Dave,

    I've never heard of it being referred to as "dynamic LINQ".  In my opinion, this is a misnomer because LINQ was designed for this - there's nothing "dynamic" about it :)  You can piece together queries without any side-effects, until you're ready to execute them.

    IObservable<string> query = GetObservableSource();
    
    query = query.Where(s => !string.IsNullOrEmpty(s));
    
    if (userRequestedFilter)
      query = query.Where(s => UserFilter(s));
    
    if (userRequestedMaximum)
      query = query.Take(userMaximum);
    
    query.Subscribe(...);

    - Dave S.

    • Edited by Dave Sexton Saturday, March 27, 2010 6:07 PM Clarified distinction between lazy interfaces vs. lazy queries
    • Marked as answer by dave.d.dixon Sunday, March 28, 2010 8:14 PM
    Saturday, March 27, 2010 5:58 PM

All replies

  • Hi Dave,

    The contract for IObservable<T> is similar to IEnumerable<T> in that they both define a lazily-computed sequence of values.  The keyword here is "lazy".  It means that you can compose a query using fluent method call syntax without having to define it all in one place.  Then once the query is composed, however that may be, you can execute or subscribe to it.

    If that doesn't answer your question, then you may have to explain what you mean by "dynamically".

    - Dave S.


    http://davesexton.com/blog
    Saturday, March 27, 2010 3:33 AM
  • Hi Dave. Thanks for the reply, I think you did answer my question. It sounds like I should be able to compose a reactive query at runtime via lambda expressions, similar to "dynamic LINQ".
    Saturday, March 27, 2010 3:36 PM
  • Hi Dave,

    I've never heard of it being referred to as "dynamic LINQ".  In my opinion, this is a misnomer because LINQ was designed for this - there's nothing "dynamic" about it :)  You can piece together queries without any side-effects, until you're ready to execute them.

    IObservable<string> query = GetObservableSource();
    
    query = query.Where(s => !string.IsNullOrEmpty(s));
    
    if (userRequestedFilter)
      query = query.Where(s => UserFilter(s));
    
    if (userRequestedMaximum)
      query = query.Take(userMaximum);
    
    query.Subscribe(...);

    - Dave S.

    • Edited by Dave Sexton Saturday, March 27, 2010 6:07 PM Clarified distinction between lazy interfaces vs. lazy queries
    • Marked as answer by dave.d.dixon Sunday, March 28, 2010 8:14 PM
    Saturday, March 27, 2010 5:58 PM
  • Hi Dave,

    I just want to point out that my original response may have implied something that's not exactly true about the laziness of IEnumerable<T> and IObservable<T>.

    The laziness in the contracts of these interfaces refers to computation only.  In other words, it's possible for sources of IEnumerable<T> to calculate values as each is requested; e.g., C# iterator method; and for sources of IObservable<T> to begin calculating values upon subscription; e.g., Observable.Range.

    Note that these types of lazy sequences are referred to as, cold.  Whereas pre-calculated or "live" sequences are referred to as, hot.  The key difference is that cold sequences may have side-effects each time they are executed or subscribed to, whereas hot sequences will not.

    On the other hand, the laziness that is required to be able to form queries without side-effects is actually provided by the way in which fluent method call syntax is implemented, and not by the laziness in the contracts of IEnumerable<T> and IObservable<T>.

    However, query laziness does overlap a bit with source laziness.

    For example, a cold sequence will not begin calculating values until it's executed or a subscription is created.  This enables you to create the source, create a query over the source, and then execute or subscribe to start producing values.  Thus the query that you constructed and the source's computation are both lazy at the same time.

    hot sequence may have already produced values by the time you create your query and execute or subscribe to it.  But the important part is that even though you lose the laziness aspect of the source's computation, you do not lose the laziness aspect of the query, because the query will not be used until it's executed or subscribed to.  This means that you could construct multiple queries that work over the same source, and each query may be lazily constructed until the code is ready to execute or subscribe.

    - Dave S.


    http://davesexton.com/blog
    Saturday, March 27, 2010 6:37 PM
  • Hi Dave. Thanks for the excellent info. I don't suppose you could recommend a resource where I could do some "deep dive" reading on Rx? Trying to get a comprehensive picture in my head of how it all fits together.

     

    Dave

    Sunday, March 28, 2010 6:02 PM
  • Hi Dave,

    I believe there's no formal documentation yet, aside from the limited IntelliSense comments that show up in Visual Studio.  I'm also unaware of any deep dive reading, however there are a few awesome videos that go deep on Channel 9.  See all videos tagged with Rx.  Here's an example of one:

    http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx/

    However, I do recommend the following wiki for its samples.  It also lists Channel 9 videos that are particularly useful for describing some of the individual operators (at the bottom).

    http://rxwiki.wikidot.com/

    And of course, searching these forums you'll find some discussions that go pretty deep.  Here's an example:

    Homework: Find the Call/CC Operator
    http://social.msdn.microsoft.com/Forums/en-US/rx/thread/03f4730f-fe11-4ccf-a799-025fa6e73ac2

    - Dave S.


    http://davesexton.com/blog
    • Edited by Dave Sexton Monday, March 29, 2010 12:16 AM Added forums example
    Monday, March 29, 2010 12:13 AM