Bart De Smet

Back to Profile: bdesmet

Comments

  • Bart De Smet: LINQ to Z3

    @aL_: No commitments for a continuation (pun intended) of my blog series on the subject just yet. Expect an update after noodling around a bit more with Solver Foundation.

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

    @kevin: You can find the sample as a Hands-On Lab through our forum at http://social.msdn.microsoft.com/Forums/en-US/rx/threads. See section "Announcements" near the top for the link to the latest HOL documents.

    Hope this helps,
    -Bart

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

    @felix9: Slightly better for sure, because there's something you can grab. Passing it around though is still cumbersome: you'd need to pass the static event object, as well as the instance to which it applies. All the remainder points made in my .NET events comparison slide hold here too: their "events as data source" characteristic is not apparent, composition lacks, etc. What you got though is a slightly nicer FromEvent bridge.

    In fact, WPF events are not strictly more first class than .NET events, because you still have to pass two pieces of information around: the event object and the instance to which it applies. That's different with delegates, which can capture both the target method and the instance to go with it (remember all the function pointer "fun" in native C/C++ land to achieve a similar effect?).

    Having said all of this, again: we're not replacing existing event sources or sources of asynchrony. Instead, we can build bridges and expose those as observable sequences. Building this particular bridge is incredibly straightforward, too.

    Cheers,
    -Bart

    PS: In a former life, I was a developer on WPF, so yes, I'm very well-aware of what that particular platform got too Wink.

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

    @Waldemar: Thanks for the feedback. In fact I have two of those clickers (<AdWarning>Microsoft Wireless Notebook Presenter Mouse 8000</AdWarning>), which I either forget to bring or forget to switch off such that the battery dies prematurely.

    So yes, this was a little bit of jumping around on stage, which is good for my "calories burned count" anyway. Luckily some conference venues provide this kind of equipment Smiley.

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

    @AdamSpeight2008: I've actually mentioned during my talk (as far as I remember) that we have an overload that allows you to do more or less what you're describing, by passing in add and remove handler lambda expressions (which will be using the .NET event itself using +- and -= operations, respectively).

    Since I like to do all demos live and always avoid to import code snippets on stage (sure, I could build the entire Windows kernel live on stage by dragging and dropping a code snipet of a few million lines of code, that would be immediately obvious to the audience Smiley), I went for the shorter one. Following this approach of live coding allows the brainwaves of the audience to be in sync with mine while producing the code.

    That said, this overload is there as the closest one to being able to pass in an event. However, .NET events are merely metadata citizens and are not first-class constructs: in other words, you can't grab them nor pass them around (as opposed to methods which you can grab by means of delegate types).

    Hope this helps and thanks for watching,
    -Bart

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    Hi folks,

     

    The sample of the LINQ to WQL provider can (finally) be downloaded. More information can be found on this post on the Rx forum. Please use the forum for further questions and/or discussions on the subject.

     

    Have fun,

    -Bart

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    There are a few samples where the form quits before event subscriptions are disposed; it may be that's the case you're hitting, which looks similar in terms of exceptions. I'll have a look. Thanks for letting me know.

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    One versus many is a popular debate amongst language people. In fact, certain functional languages that will remain unnamed encode a lot of stuff using lists (e.g. "nullability" in terms of zero-length lists to represent "not present"), while others introduce whole separate language features to deal with 0 versus 1 cardinality (e.g. "option"). I'm much more in the former camp as many can encode one, but not vice-versa.

     

    Whether or not the IE/IQ design for aggregates it the right one is something that can be debated for a long time in a similar manner. If we're doing LINQ to SQL using it anyway, isn't a single result a single-column, single-row table? People have always used different methods on low-level APIs a la SqlCommand depending on the desired outcome. While you could use ExecuteReader to get a scalar value back, ExecuteScalar makes things simpler. But if LINQ generalizes operators over sequences, something can be said about it being closer to the ExecuteReader approach. With the sole argument of one more method call adding friction, xs.Sum().Single() isn't too bad. This said, I do buy the arguments made.

     

    The thing that's certain is that in an asynchronous world you don't want to leave the monad. There are multiple reasons for that. One is cancellation, but the more important one is to preserve composition. The former is definitely an IO thing, but the latter applies equally well in the world of IE. We may introduce similar aggregates in our Interactive Extensions (Ix) assembly for LINQ to Objects as well. Simply because the original LINQ design didn't account for further composition, doesn't mean it's not better. In particular, with operators like Amb and Timeout (amongst many others) introduced in Rx and Ix, composition for aggregates is incredibly useful. Also, a different return type outside IE requires people to write different code to do data binding to the result of an aggregation versus a grid-shaped result.

     

    Finally, in the IQ case, the fact you loose the expression tree breaks composition on that level in certain cases. Not if you're "lucky" and things like Sum() appear in a selector lambda expression. But if you want to translate computations involving multiple aggregates (agreed, not often done in today's world), you're left out in the dark as there's no way to get the tree representing Sum without triggering its execution (unless you manually reconstruct it using infoof(Queryable.Sum) in a MethodCallExpression). Btw, if aggregates stayed in IE, computation over multiple aggregates could be done easily using operators like Zip, which is just a "lifted binary operator" for single-element sequences.

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    The sample shown in the video will be posted at a later point at either the Rx team blog or my blog. I'll keep you current on that one.

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

     

    Bridging Rx with MSMQ is totally doable. At first sight, it doesn't look like there's a domain-specific queue query language you can apply to contents of a query, so the queryable approach seems redundant. Nonetheless, some of the System.Messaging APIs may benefit from mapping onto Rx equivalent operators. For example, the TimeSpan parameter used to specify a timeout on various Send/Receive operations is an ideal candidate for exposure through the Timeout operator of Rx.

     

    Concerning this bridging, simply creating operators that expose a message queue as an IObservable and vice versa would likely suffice. In fact, I've done such a thing in the past. Transactions could be totally part of this too. Basically, you'd check whether a MessageQueue object is marked as Transactional, and if so, you'd likely do something along those lines:

    • When importing an IObservable to MSMQ, you'd likely want a transactional send of many OnNext messages, rolling back the transaction on OnError and committing it on OnCompleted. This won't work well for infinite sequences of course (and likely you don't want to do a transactional "send just one message" kind of thing).
    • When importing an MSMQ queue as an IObservable, you'd likely want transactional receive to work on a per-message basis, only committing the transaction if the OnNext message you send out to the consumers gracefully returns. That is, you guarantee the user has seen the message successfully and could handle it.

    If this automatic transaction management doesn't work for you, a better option may be to have the user control the transaction himself, simply by use of MessageQueueTransaction objects. Not as sexy or smart as the above, but maybe necessary to accommodate for various more complicated scenarios.

     

    I'll leave it as an exercise to the reader to implement such bridging operators.

     

    (Edit: wanted to paste code, but it went terribly wrong; will try again later)

     

    Hope this helps. Happy hacking!

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    Changing names is easy, especially in our world of incubating ideas. Changing semantics on the other hand is hard. So let's focus on the latter first and then get to the aesthetics of it all. De gustibus non est disputandum and The colour of the bikshed apply here.

     

    Oh, and the "visually close" argument raised earlier is rather weak, especially since homo-iconicity is all about that Smiley. Is x => x too much like ... x => x, while they may be radically different behind the scenes (delegate versus expression tree)? Also keep in mind the interface is not what users of providers see, at all.

     

    This said, feel free to discuss naming on a dedicated thread on the Rx forums.

  • Bart De Smet: Observations on IQbservable - The Dual of IQueryable

    Thanks for the kind words, Jules.. It may be my new diet that's paying off Smiley.

     

    A few more pointers for the viewers:

    Things not mentioned in the video:

    • Some "imperative operators" using interfaces like IConnectableObservable, requiring code blocks (and hence statement trees in a fantasy homo-iconic world), are not available on Qbservable. There are just a handful of overloads that fall in this camp such as the parameterless Publish method (the lambda version is there though).
    • Qbservable also provides support for join patterns as expression trees. That is, the And and Then operators from System.Joins are available in an expression tree form as well. It's left to the reader to dream up the endless possibilities this enables for joining multiple data streams "in the cloud".
    • Constructors like FromAsync which return a Func<T1, ..., Tn, IObservable<TResult>> are supported too. They return a similar Func returning an IQbservable<TResult> instead. That IQbservable will contain an expression tree with an Invoke node upon invoking the returned function.
    • Parameters on Qbservable operators are only protected against null reference inputs. That is, no operator-specific enforcements are made. For example, one is allowed to write Take(-5) against an IQbservable, but not against an IObservable. It's up to the provider to decide what -5 means (take last 5?, don't allow?).
    • Observable has a static get-only Provider property that exposes the IQbservableProvider that can be used to create expression trees for "local" queries and can be used to get stuff like Return in an expression form, using Observable.Provider.Return(5), returning an IQbservable<int>. This is complementary to the AsQbservable operator.
    • Use of AsQbservable on a "local" observable sequence allows one to write expression trees against such a source. When calling Subscribe on the resulting IQbservable, which also implements IObservable per definition, the tree gets rewritten to target the Observable.* operators, including join patterns and whatnot.
    • For signatures Qbservable operators, notice that only a minimum set of parameters has been tweaked to be expression-friendly compared to the corresponding Observable operators. That is, things like Amb(IObservable, IObservable) only get the first parameter as IQbservable. This opens up for quite some flexibility; providers can type-check on the second argument.

    Play and amaze us with great observable providers Smiley.