page 1 of 1
Comments: 19 | Views: 1058
blowdart
blowdart
Peek-a-boo

Is it air?

 

Oh no wait, wrong thread

 

aL_
aL_
Rx ftw

shoudnt it be exactly the same except that it has IObserveable as the base interface instead of IEnumerable? Smiley

 

dont forget to check out this 

Charles
Charles
Welcome Change

A thread on interface duality!! I love Channel 9! Smiley

 

Niners rule,

C

aL_
aL_
Rx ftw

hm i dunno..

seems like the properties in IQueryable, ElementType, Expression and Provider would instead be methods taking a type, an expression and a IQueryProvider respectivly.. i dont know how useful that would be though Smiley

 

it could be kind of interesting to use the expression trees to convert an IObservable query to something that could be sent to some other system or service. like if you have some sort of service that sends data very rapidly but over a very slow interface, you could encode your event filtering/joining as an expression and have the service do that internally and just send you the data thats interesting Smiley

I agree with your last statement.  IEnumerable yields values locally, while IQueryable sends a command that tells a remote system which values to yield remotely.  Thus if IObservable streams values locally, then IConfigurable? should send a command that causes a remote system what to stream remotely.  Unlike SQL there's not really any big standard remote stream configuration language that would be useful for IConfigurable, so it's probably a bit pie in the sky.  At least as far as I can see.

Actually I could see MS using an IConfigurable dual to IQueryable to configure how Sharepoint / Workflow events are streamed.

Blue Ink
Blue Ink
C you

Yes, that would work... essentially we are looking at an IObservable for which you can specify some predicate / transform on the data.

 

It could be handy even out of the obvious data scenario: for instance, you could subscribe the MouseMove event specifying: "if the left mouse button is not pressed, don't bother notifying me".

This would take some complexity off event handlers, as it would allow us to split the code to different methods instead of attemtping to sort out the conditions in the handler itself. It would then be up to the source to notify all the handlers that apply.

 

For instance (please disregard the syntax, I know it's horrid)

 

...

control.MouseMove.Where (e => e.Button == MouseButtons.Left) += control_MouseMoveWithLeftButtonPressed;

control.MouseMove.Where (e => e.Button == MouseButtons.Right) += control_MouseMoveWithRightButtonPressed;

...

staceyw
staceyw
Before C# there was darkness...

If any IObserable would take an IQueryable as input, then the IObserable/IObserver pattern remains unchanged (at the high level) and you don't really need a dual of IQuerable?  Your expression is sent to the obserable and it pushes data back matching the expression.  In sql, it would be interesting to be able to express a query to get notified on things like row and column change/update/delete.

Sven Groot
Sven Groot
My name has 9 letters. Coincidence? I think not...

In sql, it would be interesting to be able to express a query to get notified on things like row and column change/update/delete.

Actually, you can do that with .Net 2.0 and SQL Server 2005 and up, using SqlDependency.

exoteric
exoteric
I : Next<I>

Isn't this what the IO framework (Rx) (IObserver/IObservable) will already allow you to do!?

I desperately want to start playing with this stuff...

Actually this raises a further question—what is the dual of a database?

 

Also, I wonder if IObservable is truly the dual of IEnumerable.  Or, more precisely, whether it should be the dual of IEnumerable.  Certainly the interface designed by Meijer is the true dual, but I wonder if the intention is truly dual.  For instance, (from my perspective as a third-party device integrator that deals with streaming COM ports a lot), the general use of an IObservable will likely be for streams that never end under normal operation.  Whereas generally IEnumerables are assumed to be finite in size.  Thus, for instance, a Join operation makes sense for IEnumerable because it only has to join one finite set to another.  (Note that a join on an infinite IEnumerable would cause an infinite loop—should it only be defined on ICollection?)  A Join on a finite-duration IObservable would work, but on an infinite-duration IObservable would eventually run out of system memory, since it will have to maintain a lookup for every element that has passed through.  However, a "Zip" would make sense on an IObservable, in the sense of "give me an event combining the latest thing from stream A and the latest thing from stream B that match," though I don't see how that would make much sense in an IEnumerable.

 

That said, I'm not sure if I see a huge reason to change the interface for IObservable to something else.  It seems as suitable as anything.  Perhaps the C# team might want to consider the intention when designing the Observable extension methods, rather than simply copying the Enumerable extension methods for the sake of mathematical duality.

Also, what would be the dual of yield and foreach?

I think I figured out the yield and foreach thing.  Here's what I came up with:  it would be "yield" and "foreach".

 

My reasoning is that when you really look at it, Enumerable and Observable both essentially have the same single purpose—to transfer data from a provider (be it an array, a database, a stream, a yield statement, whatever) to a consumer (presumably the app).  The only difference is that the former uses a pull model, and the latter uses a push model. 

 

There's a bit of a mental barrier I had to get over to come to that recognition, essentially that we tend to associate Observable with events and things that are time-separated or take place on other threads, but there's no reason it has to be that way.  An Observable could easily simply contain an array, and in its Subscribe function, it could simply call subscriber.OnNext(T) for every T in the array and then call subscriber.OnFinish().  In which case, the Observable may as well just call "yield" (provide the data) and have the subscriber do a "foreach" (consume the data).  An Observable could even be used in place of Enumerables for database calls if we think about it in that fashion; the only difference would be that it would be pushing from the database rather than pulling from the app, but the data is the same, so the results would be the same.  (Again, mental barrier for the previous statement—it's easy to think it would behave differently because we mentally associate Observables with different threads—but I am assuming for this example that we have a single-threaded app in both cases.  Nothing else will execute until the data query is finished.  In fact, if we use a foreach the app code would be identical!).

 

Conversely, there's no reason that Enumerables can't be used to handle events or time-delayed multithreaded things.  If these things were simply stored in a queue, a pull model (Enumerable) works just as well for these too.

 

So ultimately, now I find myself wondering, is Rx really giving us anything new at all?

exoteric
exoteric
I : Next<I>

There appears to be a couple of assumptions in what you write.

 

Both IO and IE can be finite and infinite. That is the nature of being duals. The difference is push vs pull as you mention. Dispose is used to preempt a subscription (pull). OnDone is used to signal natural completion (push).

 

There are conversions between IE and IO - that's also the nature of being duals. Still, that doesn't mean you should convert all IOs to IEs or vice versa.

 

I see IO as inversion of control: the arrows are reversed* - so the data source is in control. It's remarkably intuitive when you think about it! IO reverses data flow. (* Thank Brian for that insight.)

 

One of the most important use cases for IO is probably wrapping .Net Events. IO takes advantage of latency, admitting when control is external, this is exactly what you want in a UI situation.

 

Now it doesn't solve the parallelization problem, it "just" solves the concurrency problem: composing reactions over time, not decomposing them into separate threads that load-balance the CPU. That's the problem that Px solves (my definitions)

Rx (Reactive Extensions for .Net)

     composing asynchronous computations

Px (Parallel Extensions for .Net)

     decomposing synchronous computations into asynchronous computations

I don't know about IQueryable because I haven't had the chance to use that or look at that yet. However we've had so much help from Erik and Brian now that it should be possible if it makes sense, at least to make a rough dualization. Reverse the arrows and work from there.

 

Smiley

staceyw
staceyw
Before C# there was darkness...

"Actually, you can do that with .Net 2.0 and SQL Server 2005 and up, using SqlDependency."

 

Thanks.  I meant using IObserable and linq expressions.  To leverage the same symantics and not have to need another object model.  Any kind of cmd (sql, dml) should be expressable and remotable to sql  in a cool world.

Yeah, I mean, I get the point of what Rx is for, and am absolutely excited for it to be coming out (I only found out about it when I started writing up a queryable serial stream parser and thought "I bet someone has done this before", and googled "Linq to Events").  I guess the main thing is just the nature of OP's original question, and me trying to figure out what the dual of foreach and yield might possibly be.  Still have no idea, and am not so sure it's even a well-defined question.  Like, I can't come up with a good dual of IList that makes any sense either, so I wonder if this "duality" is fundamental in any way to the workings of it, or whether it's just a convenient coincidence.

page 1 of 1
Comments: 19 | Views: 1058
Microsoft Communities