Roger Ebert was — is — a hero of mine. I’ve often thought that if I could be one tenth as clear, witty, insightful and kind, I’d consider myself a good writer.
I remember getting a copy of Microsoft Cinemania in the early 1990s, casually browsing the archive of Ebert reviews and realizing that here was someone who really, really knew how to write — and from that point on I was hooked. In the decades since then I don’t think I’ve rented a movie or gone to the theater without checking to see what Ebert had to say about it first. On the few occasions when he wrote something that moved me to respond directly he always answered my emails thoughtfully and kindly. That he took the time at all out of his incredibly busy life to answer fan emails is just one small example of his generosity.
Tonight I’m going to take AV Club reviewer Zack Handlen’s advice and watch Citizen Kane again with Roger’s commentary track. It’ll be good to hear his voice.
The C# compiler has a
/langversion switch that is rarely used; most people do not know what it is for, and if asked to guess, most guess wrong. So let me disabuse you of your wrong guess right away: the purpose of the langversion flag is not to decide what C# language version to use. It is not a “go into compatibility mode” switch or a “use a previous version of the compiler” switch. The only effect of the langversion switch is to put the compiler in a mode in which use of features from a version of the language higher than the given version cause the compiler to emit an error.
Let me illustrate with a hilariously contrived example:
My erstwhile Microsoft colleague and parallelism guru Stephen Toub just did what I did not do last time: he applied the same treatment I gave to the maybe monad and sequence monad to the task comonad. Check out his awesome blog article!
OK, for reals this time, that’s it for the monad series. Next time on FAIC: ever wonder what the langversion switch on the C# compiler is for? Me neither. But next time you’ll find out anyway.
Holy goodness, this series got a lot longer than I expected. I was hoping to get to some actual category theory, but let’s just talk a bit about LINQ and then wrap up. Maybe I’ll do a series on the basics of category theory in the future.
I’ve said several times that
SelectMany is the
bind operation on the sequence monad, but of course there are several overloads of the
SelectMany extension method of
IEnumerable<T>. The one that is
bind is as we previously discussed: (Error checking removed for clarity.)
public static IEnumerable<R> SelectMany<A, R>(
this IEnumerable<A> items,
Func<A, IEnumerable<R>> function)
foreach(A outer in items)
foreach(R inner in function(outer))
yield return inner;
Now you might think that when you say
from outer in items
from inner in function(outer)
this translates directly into a call to
This is not what actually happens.