The time: The early 1700sThe place: England, at the beginning of the Industrial Revolution.
In this book, Jenny Uglow details the lives of the group of men - industrialists, scientists, doctors, and others - who made up the “Lunar Society of Birmingham“.
Some of them you've may have heard of - James Watt, Joseph Priestly, Erasmus Darwin. For others, such as Josiah Wedgewood, you may know the name from something else .
And other you've probably never heard of.
This is a pretty good book. It's interesting, for example, to find out about the amount of chemistry that is required in pottery making to get the right result.
It would be a better book, however, if it were around 300 pages rather than 500 page in length. There's a lot of detail there, and while I appreciate a desire for historical accuracy, after 400 pages I lost interest and moved on.
Last night, my wife surprised me with a night at the W in downtown Seattle as a late birthday present.
The W is currently my favorite hotel by far. I spent a little time last night thinking about why.
It's not because they have a “living room” rather than a lounge.
It's not because there's house (or trance (or drum and base (or something like that))) music playing in the elevators.
It's not because the rooms have really clean design.
It's because the experience is consistent. Somebody took the time to think about the whole hotel experience, and make it as smooth as possible. Even down the “do I want the sheets washed” sign, which is a wheel that lets you set it to whatever you want.
I appreciate that level of thought.
We had dinner at Cutters, a great place for seafood.
This morning after breakfast we walked over to the new Seattle Library. Nice building, but the neon green is too jarring.
A good friend of mine recently resurfaced after being out of touch for about 18 months. The last time I had lunch with him, he was having some marital issues and had just joined the ranks of the unemployed (he's a tech guy as well).
In the 18 months, he got divorced, took some Spanish classes, and then went on a home-study trip to Costa Rica. When he got back, he decided he needed a different kind of job, so he's now working as a ramp service agent for Alaska Airlines at SeaTac airport, and looking to get back into writing.
I envy his ability to push the reset button on his life, and then figure out what he really wants to do when he grows up.
I've been trying to simplify my life as well recently, though I doubt that any changes I make will be as drastic as his were.
The tradeoff between money and free time is a hard one. Ideally, I'd like to have both, and while that could happen if my stock market investments go well, it's not something that's going to happen overnight - or even in the next few years.
I may write about one specific “life simplification” decision in a separate blog, if I decide to go that way...
I'm thinking of setting up a new category named “Strangely Compelling”.
I came across a link from the Journal of Improbable Research (also home for the Luxuriant Flowing Hair Club for Scientists (LFHCfS)), which led me to the following pictures:
Want to try your hand?
Visit Warp-A-Kitty
In a recent email, a customer asked for a delegation feature. He wanted to do something like (purely theoretical syntax):
class MyClass: ITest{ MyHelperObject o: ITest;}
so that he could delegate the implementation of the interface to a helper object, and have the compiler automatically generate the interface implementation methods.
My response was that we had talked about this several times in the past, but hadn't been able to come up with a syntax that worked well.
This is a not uncommon state for us - on several occasions in the Whidbey (excuse me - “Visual Studio 2005”) design process, we tried to come up with a syntax that allowed the user to declare a trivial property (backing store, trival getter and setter) with one bit of syntax, but weren't successfull.
I thought I'd talk about that process to give you some insight on how we approach things. I can't be exhaustive with all of our considerations, mostly because we don't really operate that way (there isn't a set checklist). If you have a question on a specific feature, I am happy to consider talking about other features and decisions - see the “suggest a topic” hard link on my main page. Just note that my success rate on actually covering such topics is not exemplary. Also note that I make no attempt to answer questions in the order asked.
The process is fairly organic, in that the steps I list don't happen sequentially, and they are often iterative. Despite the length of this post, I've simplified what goes on significantly.
Sniff Test
We start with what I'm going to call the “Sniff Test“, which is basically the highest level triage to determine if we think such a feature is something we would ever consider for C#. Some features fail because they don't fit the language philosophy, some fail because there's no way we could ever express them in syntax.
Scenario Exploration
Our next level of attack is looking at what user problem we're trying to solve. This typically involves us writing down (or up, on the whiteboard) the code that users are currently writing. Sometimes this is limited to the most common scenario, sometimes we'll cover several scenarios - it all depends on what we need to know. This often happens iteratively with the next step.
Syntax Iteration
If we've gotten to this step, we're usually fairly convinced that there is a user need. We don't yet know if there is a language solution to that need. In this step, we'll start talking about what we could do in the language to make the developer's life easier.
This step typically works with Anders writing on the whiteboard while the rest of the design group gives suggestions and feedback. When we hit on a promising approach, we'll explore it for a bit to see where it leads us, contrast it to other approaches we could take.
In this step, we're asking questions such as:
In a single session, we will sometimes decide to do a feature and sometimes decide to not do a feature, but more typically we'll decide that we need to discuss it more. We go away and think about it, gather feedback from the people who read our language notes and those closest to the scenario, and then revisit it in a future meeting. A lot of the iteration is around exploring all the corner cases (some of which don't come up until implementation) and making sure the feature is well defined, still does what we want it to do, and still is in the best interests of the developer.
It's not uncommon for us to change our minds on the details of a feature, or even to decide upon reflection that we need to either reduce or eliminate a feature.
Structured Feedback
If we've gotten to this point, we're fairly sure that we want to have the feature, and typically have an implementation (though not always). We use feedback with the C# Customer Council (a small group of customers who we work closely with), and the C# MVPs (we've done a little with the MVPs in the past, we'll be doing more in the future) to see what their perspective is on the feature.
This is also the point where we work with the ECMA standards body to talk about our proposal, though it's often difficult to align the schedules of the standards body with product milestones.
There may also be internal Microsoft presentations at this point, depending on the feature.
Many times the feedback is positive, but sometimes it causes us to refocus the feature, and there have been language features that we cut due to feedback at this point.
Manufacturing and Shipping
If we've gotten this far, the feature is in the language, and often implemented. The remainder of the work is to polish the implementation, finish the testing (sometimes testing is concurent with implementation, sometimes it lags a bit - it depends on the type of feature and our resource constraints), do the spec, and discuss how we'll be presenting it to customers.
Visual Studio Breakpoint Helper
The .NET Frameowrk Bootstrapper makes it easy (er) to distribute the framework as part of your application. (yes, that is the right post - look at the bottom).
I came across this on one of our internal aliases.
Math.NET is a cool mathematical framework. It supports both arithmetic and symbolic operations.
Phil Haack writes about the difficulties of language design.
And no, I'm not linking just because he mentions me twice...
One reader commented that nullable types don't seem to fully work in the community preview drop.
He's correct, and I apologize for not making that clearer in my post.
The time constraints of the community preview prevented us from getting all the nullable support in the compiler, but it will be there in the upcoming beta.
For the community preview, the following things work:
The following things don't work:
I've been reading a series of posts by N. Alex Rupp on his experiences at TechEd, and his thoughts on the Microsoft and Java communities.
I'm especially interested in this because I'm going to JavaOne at the end of the month...
On Wednesday night, I spent some time at the O'Reilly reception. In the SWAG bags that they gave us was a copy of the book, Hackers and Painters by Paul Graham.
The O'Reilly website has this to say about the book:
"Hackers & Painters: Big Ideas from the Computer Age, by Paul Graham, explains this world and the motivations of the people who occupy it. In clear, thoughtful prose that draws on illuminating historical examples, Graham takes readers on an unflinching exploration into what he calls "an intellectual Wild West." The ideas discussed in this book will have a powerful and lasting impact on how we think, how we work, how we develop technology, and how we live. Topics include the importance of beauty in software design, how to make wealth, heresy and free speech, the programming language renaissance, the open-source movement, digital design, Internet startups, and more. "
I wanted to like this book, but after reading about half of it, I have mixed feelings. I think some of Graham's observations are interesting, though some aren't new (the fact that some programmers are wildly more productive than others will not surprise many developers). But in others I think he makes assertions that aren't well supported.
In one of the early chapters (I think it's chapter 1, but I don't have the book here right now because it's in my luggage at the hotel), he makes the assertion (and I'm simplifying a ton here) that since children in medieval times started apprenticeships when they were in their early teens and we don't have record of them having the same sort of problems today's teenagers have (which I'll label as "teenage angst", though that's not exactly what he's talking about), then the behavior we see today must be societal and environmental in nature.
The problem with this argument is that there is some very good research that says that the brains of teenagers are not fully developed until around the age of 20 (see this from NIH, or Bradley and Geidd's excellent book "Yes, your teen is crazy!"), which means that the assertion that there's some biological basis for teenage behavior has some good support.
Given that this book is a collection of essays, I don't expect the same level of research I would in a full book devoted to the topic, but it's unfortunate to have this sort of oversight.
Another example is in one of the chapters on wealth, which I think are pretty good overall. Graham's assertion here is that before the industrial revolution, there has been wealth transference, but not a lot of wealth creation, and that wealth has been accumulated through theft (either directly or via taxation). I think this is basically true. His second assertion is that this changes with the application of technology. I agree that technology has brought new wealth (if you measure wealth by standard of living).
He then uses this as a basis that inequities between rich and poor are not a bad thing, because the creation of wealth is a good thing. But I think he ignores the fact that the old methods of wealth accumulation are still alive and well - the rich are (not surprisingly) interested in staying rich, and are willing to use their influence to make this happen. Given that, I don't think one can make the "Greed Is Good" argument without at least some qualification.
For those of you who have never met me, I'm approximately 6'2” tall, and currently weigh about 168 pounds. For all of my (reasonably) adult life, I've been a “Large”. If I needed a T-shirt, or a coat, or a sweatshirt, I was always a Large.
My consistent largeness provided comfort as I navigated the often turbulent waters of life.
But recently, things have changed. America has - and I'm sure I'm not telling you anything new, unless you've been living in a cave for the past 10 years (presumably a cave with a nice 100 MBit network, a cable modem, and a kickin' gaming system), you've probably noticed that America has been getting fatter. Not the country, which at my last measurement, was just a bit under 1000 leagues wide, but the people.
For a while, this was no issue, but clothing manufacturers have started to adjust their sizes upwards, which means that Large isn't the Large that I have grown to love. But, of couse, all of them haven't done it, so now I sometimes end up with a large, and sometimes with a medium. Not that bad if you can try them on ahead of time, but for TechEd I got two Large shirts - you have to order large because if medium is too small, you're SOL - and I swim in them a bit. I guess I could wear 10 or 12 T shirts underneath to fill it out a bit, but that hardly seems practical.
Argh.
Nullable Types in C#
One of the "late breaking" features in C# 2.0 is what is known as "Nullable Types". The details can be found in the C# 2.0 language spec.
Nullable types address the scenario where you want to be able to have a primitive type with a null (or unknown) value. This is common in database scenarios, but is also useful in other situations.
In the past, there were several ways of doing this:
To make this easier, in VS 2005, we're introducing a new type named "Nullable", that looks something like this (it's actually more complex than this, but I want to keep the example simple):
struct Nullable<T> { public bool HasValue; public T Value; }
You can use this struct directly, but we've also added some shortcut syntax to make the resulting code much cleaner. The first is the introduction of a new syntax for declaring a nullable type. Rather than typing:
Nullable<int> x = new Nullable<int>(125);
I can write:
int? x = 125;
which is much simpler. Similarly, rather than needed to write a null test as:
if (x.HasValue) {...}
you can use a familiar comparison to null:
if (x != null) {...}
Finally, we have support to make writing expressions easier. If I wanted to add two nullable ints together and preserve null values, if I didn't have language support, I would need to write:
Nullable<int> x = new Nullable<int>(125); Nullable<int> y = new Nullable<int>(33); Nullable<int> z = (x.HasValue && y.HasValue) ? new Nullable<int>(x.Value + y.Value) : Nullable<int>.NullValue;
At least I think that's what I'd have to write - it's complex enough that I'm not sure this code works. This is ugly enough that it makes using Nullable without compiler support a whole lot of work. With the compiler support, you write:
int? x = 125; int? y = 33; int? z = x + y;
Last night, I attended a TechEd bloggers party, held in a pretty nice suite on the 40th floor of the Hyatt. (Not the 4th floor, as many of us had assumed. I realized later that this is because I'm used to the Microsoft buildings that I work in, where the first digit is the floor number. It didn't help that the party was in the Elizabeth Suite, and there's an Elizabeth ballroom on the 4th floor).
So, there we were, a bunch of bloggers, talking the sublime expressiveness of Cezanne's painting of Mont Sainte-Victoire.
and then somehow we got onto the topic of technology.
There were - as there always are in such a gathering - a few TiVo fans, and we got into discusing the "wired house", and the utility of the internet refrigerator:
The problem with the internet refrigerator is that it doesn't go far enough. The first obvious thing to add is a way to keep track of the inventory. That can be easily added though a bar code scanner and a few weight sensors, and then your fridge can make sure that you're alway stocked with a healthy supply of pickle slices, Miller Lite, and non-dairy whipped topping.
Do a little more, and you can have a fridge that won't let you eat that last slice of pizza, but will let you make yourself a nice healthy salad (sans dressing, of course).
All those are great features, of course, but the real benefit comes from solving the “what's for dinner?” problem. By tying in TiVo's “suggestion” feature, your fridge can notice that since you bought a frozen pizza, you might also like other tomato-sauce-based products, and presto, when you come home, you not only can have the pizza, but you can also have a serving of lasagna, or a nice tomato soup.
But it gets better. Just picture this...
You're at home on a Friday night with a date, cudling on the couch and watching the latest episode on Emeril on the Food Network. Just as Emeril finishes off making Emeril's Taco Salad with a Roasted Poblano Buttermilk Dressing and your date leans closer, your hear your fridge say, “You could make that right now!“.
Women dig talking appliances.
I gave my Teched talk at 5PM today, entitled “C# Best Practices - What's wrong with this code?”. Rather than take a more lecture-based approach, I tried something more interactive. It was an interesting, if not fully successful talk. If you attended, please leave me some comments - what did you like, what didn't you like, etc. If you didn't attend, you should see slides on the dev center *eventually*.
Good:
Bad:
Overall, I think it went fairly well, but I haven't talked to anyone in my group, so I don't know what they think.
Oh, and the worst part was that I had to share the stage with two rack mounted servers that made it really hard for me to hear anything.
Afterwards, one of the room supervisors told me that the talk was SRO, and that it seemed to be a “younger crowd” than many of the other talks. I'm not sure what to make of that.
Overall, I'm not sure how happy I am yet.
In a bid to keep my blog hits high, I've decided to revisit this again.
The comments (I read all comments, though I don't respond to all of them) have been fairly split.
There has one group who agrees with me, and another group that is opposed to my perspective. I'd like to address those who disagree with me, as there are a few points I didn't cover last time.
I do want to state up front that this is an area in which there is room for honest disagreement.
I think the point that I didn't make very well earlier was that one of the reasons we're somewhat - okay, perhaps “paranoid“ is too strong of a term, but it has the right “feel“ - is that if we had a virtual method on a class but didn't support it, there's a likelihood that it will break in the future (the discussion of how likely that is is an interesting side discussion. Some may argue that it is likely, others may argue that it's not likely at all. ).
If that break happens, I don't expect the customer response to be, “Oh, it broke, so I guess I shouldn't do that“. I expect it to be more along the lines of “Why didn't Microsoft build this thing correctly in the first place?“, which is why we work very hard to avoid that situation.
There's one other point I'd like to raise. When you look at a class and there's a method that isn't virtual, you rarely have any idea why it isn't virtual. It coul be that the designer just didn't want to support that as a virtual. But it could also be that making it virtual would raise a security issue, or cause your cat's fur to fall out.
After a lot of work on Anders' part, we now have an updated version of the C# 2.0 Language Specification on the website.
Not only does it have updated information on the “big 4” - Generics, iterators, anonymous methods, and partial classes, but it also has new information on a few other areas.
The biggest one is nullable types, which are a new way to creating nullable versions of value types and specialized language syntax to support using these types. There are also a few “miscellaneous” ones, the most awaited one surely being different accessability on property getters and setters.
About 4 or 5 weeks ago, the C# team was working on our TechEd presentations. There's an organized (ish) process to get all the speakers to get their slides done in a timely manner, but we decided to add a bit more rigor on top of that process, so that we wouldn't be “behind the 8 ball” and could avoid “starting down the rhino” on our way to “communicating with the masses”.
One of the general checkpoints was to make sure our draft slides were turned in so our track owner (Brian) could pass them on to our technical reviewer (Dan), so he could review them. But in this case, Dan had already signed off that our process was fine with him and he would be getting slides earlier, so turning our drafts was largely a pointless exercise.
I joked that I was going to turn in a presentation with 28 slides, all of them having pictures of kittens on them. I then thought better of it, saying that if I did that, I would show up at TechEd for my talk, do my introduction, hit the space bar, and then hit space bar, only to be confronted with...
Kittens...
I should have known better than to tempt the demo gods.
The first problem was when I got an email on 4/12 that said, "Thanks for getting your final slides done early". Which was interesting, since I hadn't gotten my slides done early. My kitten comment was coming back to haunt me. Or, to be more correct, it was coming back to haunt the whole team - Anders' slides were okay, but all the others were the draft ones we had put out weeks earlier. Which means that if I had sent in slides with kittens, they would have been my final slides .
A few emails later, I thought I had the problem resolved, but when I showed up at the convention center yesterday morning, I checked in with the slide team and there were no slides for my talk. I took them a new copy of them yesterday, but I'm showing up to the talk with my laptop and with my slides on a USB memory stick.
And I've been trying not to think about
Here is a summary of the community-recommended bloggers.
Gary and James took issue with my position, so I'd like to expand a bit on what I said.
Gary wrote:
Eric suggests that final should be used in most cases with virtual reserved for the special occasions. I totally disagree, you can't lay down the law as to how another developer is going to extend your class, (other than in the special circumstances I mention here). If the choice is being flexible versus being static, then in the interests of good software engineering you *must* go with the flexible option. Or is that just the Smalltalk programmer in me coming out :)
My answer to that question would be “yes”. I'm not being flippant on that, and I'm about as far from being a Smalltalk programmer as you can be, but I think it comes down to the tradeoff between robustness and flexibility. If you allow more extensibility, you are being more flexible, and also being less robust (or, to be precise, being potentially less robust), especially if you aren't testing the extensibility.
James wrote:
The long and short of it - Eric thinks that library designers know everything and that one of the primary jobs is to protect those dumb application developers. There's just no telling what they might do if we let them.
James has it backwards. I don't think that library designers know everything. I think that they know very little about how users might use their classes, and therefore shouldn't be making promises their code can't keep. If they want to support extensibility, then that should be something they design well and test for. If they aren't going to go to that effort, than I don't think providing extensibility that will “probably work” is doing their users a service, and it may be actively doing them a disservice. Not only will such code be more likely to fail, but the constraint of such virtuals limits how the class can evolve in the future. It's bad when you'd like to make a small change that would help 99.9% of your users, but you can't because somebody might have existing code that depends on your behavior. But maybe that's just the compiler guy in me...
I do think that this depends on the kind of library you're building. In general, the more closely coupled the api writer and user ae, theless of an issue this is.
For TechEd attendees, you can request meetings with Microsoft people through the Rio system. I went to look at my schedule, and found out that either nobody had requested a meeting with me, or I couldn't get to my meeting requests.
Have any of you tried using Rio to do this? Have you been successful?
I've been skimming through “Hardcore Java”, and I came across a section on the use of 'final' in Java. In it, one of Simmons' comments (okay, I'm not sure it's his comment because he's listed as editor and not author, but that sounds better than “whoever wrote this section) is (and I'm paraphrasing here):
Don't use final on methods unless you're sure you want them to be final
He then goes on to say that this is because you never know who might want to extend your class.
There are really two viewpoints on this issue. They are:
“Make it virtual in case somebody wants to extend it”
and
“Don't make it virtual unless you're sure somebody wants to extend it”
I'd like to expand on the first viewpoint, which I've sometimes labelled as “speculative virtuality”. I don't like it.
My reasons have everything to do with predictability and robustness. If you can't conceive of a user extending your class in a specific way but still choose to provide such extensibility, then it's pretty clear that you don't have an extension scenario in mind, which means that neither your code nor your tests are likely to ensure that it does work - especially across versions. Sure, it's possible that it may work in the current version, and may even continue to work in future versions, but I wouldn't call it a supported scenario. I'd prefer to use classes where I know what I'm doing is supported.
The second issue is around understandability. If I walk up to a class (in the metaphorical sense, of course, you can't really “walk up” to a class) and it has 29 virtual methods, it's hard for me to tell whether the author *intended* me to extend the class through a certain method or set of methods, or whether they just left them virtual “just in case”. Where if a class only has one (or a small number) of virtual methods, that's a good indication that the designer wants me to use them (ie they're part of a supported scenario).