Tuesday, July 28, 2009

Mono.Upnp Dance Party

So it's been a while since mention was made of a certain UPnP library. What happened? First, I had various other things to do. Second, I decided to do two or three major refactorings, ditching a lot of code. Third, I moved development to github.

What the status?
The status? The status, you ask?! THIS is the status! If you can't see, I am pointing at my TV. My TV which is connected to my PS3. My PS3 which is playing music from my laptop computer with WIRELESS NETWORKING! Yes friends, tonight at last, Mono.Upnp and the PS3 are doing the DANCE OF LOVE. I plug, it plays. Universally. About ten minutes ago I finally tracked down the typo responsible for a day's worth of debugging and let me tell you, Starfucker never sounded so good (and they already sound so good anyway, seriously, you should listen to them).

What now?
I've kept pretty quite about the whole project because I wanted to lay all the groundwork before make too much noise. There is still work to be done on the core of the library, but now that it's working I'll start sharing more frequent updates. You can follow the project on github if you want commit-by-commit news.

Can I help?
Sure! But helping might be a little tricky. The solution only loads in MonoDevelop SVN, and there are certain necessary BCL fixes that require Mono from SVN too (one of them isn't even committed yet). It's not quite "checkout, compile, run," but if you're interested in helping out, I will be more than happy to get you up to speed. I wrote a TODO on the github wiki today with some stuff that needs doing. Testing is also something I will need help on. I don't have access to an XBox 360 anymore, so I'm going to need help on that front. As the library and the tools evolve, we'll need to test with as many devices as we can.

Yeah!
Yeah indeed! NOW DANCE!

Thursday, July 23, 2009

C#er

Was chillin' with the impish abock last weekend when, all of a hullabaloo, he geniused something wonderful.

"Behold!" he cried:

var button = new Button {
    Label = "Push Me",
    Relief = ReliefStyle.None
};
button.Clicked += (o, a) => Console.WriteLine ("ouch!');


To which I replied, "?"

"Watch..." said he:

var button = new Button {
    Label = "Push Me",
    Relief = ReliefStyle.None,
    Clicked +=> Console.WriteLine ("ouch!")
};


"?!" came my response.

"Is not it better?"

"Yes," quoth I, "but gentle abock, this wundercode... it doth not compile!"

"... YET!"

Well friends, yet is over. I am here today to tell you that yes, IT DOTH COMPILE. This is what you get when Scott forgets to pull the git repos for his real projects before a plane flight: unsolicited language features. And there are other goodies:

As with anonymous methods via the delegate keyword, you may omit the parameters to a lambda if you aren't going to use them. This is also helpful when the delegate type has no parameters. For example:

Func<string> myFunc = () => "blarg";


Just look at those parenthesis! Chillin' there all higgledy piggledy. They look like some unseemly ASCII art. But now, presto chango:

Func<string> myFunc => "blarg";


See what I did there? That's called an assignment arrow. It is better. Don't argue with me, because you're wrong.

For my next trick, you can do the same kind of thing with lambdas and event handler registration.

myButton.Clicked +=> Console.WriteLine ("higgledy piggledy");


Because who ever uses the EventHandler arguments? A big, fat nobody, that's who.

Last but not least, you can now do all of this plus regular event handler registration inside of object initializers. abocks around the world rejoice!

There Is No Syntax Without Corner Cases


So there is at least one possible ambiguity with this new syntax:

class Foo {
    public void Add (Action<string> action) { ... }
    public Action<string> Bar { get; set; }
}

// Meanwhile, in some unsuspecting method:
var foo = new Foo {
    Bar => Console.WriteLine ("HELP ME!")
};


Question: Is that an object initialization, or a collection initialization?

Answer: It's ambiguous.

Solution: It's an object initialization. If you want it to be a collection initialization, throw some parenthesis around "Bar." This would be a good candidate for a compiler warning. And if you want to make it an unambiguous object initialization, you could do:

var foo = new Foo {
    Bar = () => Console.WriteLine (
        "What does this ASCII art even mean?")
};


Patch


The patch for all of this is available here. Apply to mcs, recompile, then use gmcs.exe passing -langversion:future.

Future


There has been on-again-off-again talk about adding non-standard language features to the C# compiler under the guard of -langversion:future. The main concern voiced is the ability to maintain such extensions. I will definitely discuss this patch with Marek and co. to see about landing it in mainline. I'll keep you up to date.

Are You Bock Enough?


In the meantime, I call upon manly man Aaron Bockover to make the only manly choice available: fork C# and ship the compiler. Because you're not really a serious media player until you have your own special language.

Thursday, July 16, 2009

Casting Call

Type safety only gets you so far; eventually you have to cast. There are three features in the C# language which address typing: the unary cast operator and the binary "as" and "is" operators. I see people misuse these operators all the time, so here for your records are the official Best Ways to use each.

If you want to check the type of an object and do not care about using the object as that type, use the "is" operator. For example:

if (thing is MyType) {
    // do something which doesn't involve thing
}

If you want to check the type of an object and then use that object as that type, use the "as" operator and the check for null. For example:

var my_type_thing = thing as MyType;
if (my_type_thing != null) {
    // do something with my_type_thing
}

This only works for reference types since value types cannot be null. For value types, use the "is" and cast operators. For example:

if (thing is MyValueType) {
    var my_value_type_thing = (MyValueType)thing;
    // do something with my_value_type_thing
}

If you know for a fact that an object is some type, use the cast operator. For example:

var my_type_thing = (MyType)thing;
// do something with my_type_thing

These patterns minimize the operations performed by the runtime. This wisdom comes by way Marek who educated me on this a while ago. Please pass it on.

Thursday, July 9, 2009

Dear LazyMarket

Are you hiring? Do you know someone who is hiring? Well you're in luck! Because none other than yours truly is looking for a job. If you're interested in how great I am, send an email to lunchtimemama@gmail.com and I'll get you a copy of my resume. I look forward to hearing from you...