Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
C9 Lectures: Greg Meredith - Monadic Design Patterns for the Web 4 of 4
Aug 02, 2011 at 5:50 PMThank you Greg! Thank you Charles!
This one was really giving me a blast (and still is). Today I got my copy of D.E.Knuth's "Surreal Numbers", which is an excellent little intro to Conway numbers back from 1974, and I would like to recommend it here. I devoured it in one go and will read it again as soon as possible, then equipped with pencil and paper. The other book, Conway's "On Numbers and Games", appearing in the slides, I have ordered already... and Greg's book is on the list
Now, having settled the praise, here's something that sparked off quite towards the end of this installment. It's about abstracting over the container representation for 'left' and 'right'. Hmm, possibly there's a good thing even in Scala's oddity of non-variant (immutable!) Sets (see ShiNoNoir's link above).
Ok, I got two things, the second about transfinite ordinals. I know, that sounds quite scary/impressive - but it ain't really so (much). I have put together a postscript below (admittedly long for a post, but still...) which I hope establishes the relevant point while presuming virtually nothing. Please also leave your comment on that particular attempt alone, if you have some.
____
p.s., "What's that Conway ω, by the way?" (simplifying quite a bit - as Greg mentioned, "there's a lot of devil (detail) in there"):
Rx Workshop: Observables versus Events
Jul 01, 2011 at 12:11 PMGreat workshop on exciting concepts - congratulations!
Had been watching Rx "from the distance" for quite a time, but now I decided to really get hands on.
So, re Challenge1: my first go on it yielded considerably less and more concise code for events than for Observables! I just could not see how this ought to illustrate the (better) composability of Observables; it seemed rather to the contrary... oops.
Then I realized that my simple-minded solution for events was way off spec (or what I think is the intended semantics) - while with Observables it all comes out just as it should be automatically.
However, the problem with the challenge at hand is IMHO that the "test case" in Program.cs does not surface any of the relevant bits. That is, I think, because it only tests the case where there is one subscriber for changes in length. Therefore I'd like to propose the following as expected output:
// Expected Output: // *** Events *** // The // Reactive // Extensions /* * */ // 1: 10 // are /* * */ // 1: 3 /* + */ // new /* + */ // and // verify: there is NO change in length! /* * */ // 1: 13 /* + */ // 2: 13 // verify: 2nd handler gets notified, too! /* + */ // 2: 1 // *** Observables *** // The // Reactive // Extensions /* * */ // 1: 10 // Extensions // are /* * */ // 1: 3 /* + */ // new /* + */ // and // verify: there is NO change in length! /* * */ // 1: 13 /* + */ // 2: 13 // verify: 2nd handler gets notified, too! /* + */ // 2: 1...produced by the this test code:
Console.WriteLine("*** Events ***"); var events = new Events(); Action<string> textHandler = text => Console.WriteLine(text); /* * */ Action<int> lengthHandler1 = length => Console.WriteLine("1: " + length); /* + */ Action<int> lengthHandler2 = length => Console.WriteLine("2: " + length); events.TextChanged += textHandler; events.OnTextChanged("The"); events.OnTextChanged("Reactive"); /* * */ events.LengthChanged += lengthHandler1; events.OnTextChanged("Extensions"); events.OnTextChanged("are"); /* + */ events.LengthChanged += lengthHandler2; /* + */ events.OnTextChanged("new"); /* + */ events.OnTextChanged("and"); events.TextChanged -= textHandler; events.OnTextChanged("compositional"); /* * */ events.LengthChanged -= lengthHandler1; events.OnTextChanged("!"); /* + */ events.LengthChanged -= lengthHandler2; Console.WriteLine("*** Observables ***"); var observables = new Observables(); var textChangedSubscription = observables.TextChanged.Subscribe(text => Console.WriteLine(text)); observables.OnTextChanged("The"); observables.OnTextChanged("Reactive"); /* * */ var lengthSubscription1 = observables.LengthChanged.Subscribe(length => Console.WriteLine("1: " + length)); observables.OnTextChanged("Extensions"); observables.OnTextChanged("are"); /* + */ var lengthSubscription2 = observables.LengthChanged.Subscribe(length => Console.WriteLine("2: " + length)); /* + */ observables.OnTextChanged("new"); /* + */ observables.OnTextChanged("and"); textChangedSubscription.Dispose(); observables.OnTextChanged("compositional"); lengthSubscription1.Dispose(); observables.OnTextChanged("!"); /* + */ lengthSubscription2.Dispose();The prefixed comments denote my changes/additions relative to the original. Besides the additional length-change subscriber I have added the new text-change events "new" and "and" after "are", which both should NOT yield a length-change event. The whole point of this is that the stream of events as such should really be independent of the subscribers, particularly:
a) which / how many subscribers there are and
b) *when* a particular subscriber actually did subscribe.
***Note that the above test case still does not account for the one case where we have both,
a) a length-change subscriber that subscribed even before the very first *text-change* event (missing in test case, SHOULD see an event since (no text ~ length 0) != (some text ~ length > 0)
b) a length-change subscriber that subscribed right in between the text-change events of "are" and "new" (present in test case, should NOT see an event since "are" and "new" are both three characters long)
The problem I'm seeing there is that in the event solution you can get either a) or b) to see the right thing(s), but not both - whereas, again, with Observables you get it right for both just naturally. That is, at least given the restriction that the original [Events|Observables].OnTextChanged(string) firing method may not be changed, I'm not even sure if it's possible at all to get it completely right with only events.
Well, and there we're back at compositionality: adding a new kind of event (stream) should really only require an additive change.
So that's what I wanted to share; this my train of thought felt somewhat educational to me. Sorry for that it all got soo lengthy
___
p.s.: please do try yourself a solution for *** based on events-only, it's one of those things which you deem "definitely doable" at first glance but find yourself utterly puzzled at when having to actually do it. At least that's what applies to me.