Author Archives: paulvick

Free VB (and a book)!

(For those Aussies among my readers, this is not about free beer. Sorry.)

Someone pointed out to me a new promotion we’re running – if you attend three live or on-demand webcasts at http://www.aspnetwebcasts.com, you can get a free copy of VB Standard edition and an ASP.NET development book. What a deal! This only runs through November 30th, 2004, so hurry and learn something about ASP.NET, quick!

Drafting Edit and Continue

As I think the entire blog universe knows by now, C# is going to be adding Edit and Continue in their 2005 version. As I’ve said many times before, I think Edit and Continue is a great feature, so I’m happy to see another language on board with it. Of course, there’s a selfish part of me that would have liked to see the C# team continue to ignore such a great feature and leave it completely to us, but what’s good for the goose…

What’s interesting about this, though, is that it points up one of the practical reasons why having three .NET languages at Microsoft is a Good Thing(tm). As evidenced by the fact that the C# team didn’t originally plan to do Edit and Continue, if there had only ever been C# at Microsoft, Edit and Continue would probably never have happened. The CLR team only added the underlying support for Edit and Continue because VB insisted on it and then sat down with them and worked out how it was going to happen. Similarly, I don’t know if generics would have ever happened if there had only ever been VB at Microsoft, even though I think it’s going to be an excellent feature for our customers. Lacking the C++ history, it’s something that we probably never would have pushed the CLR team to implement the way the C# team did.

It occurs to me that this is an extension of Rocky’s excellent rant on programming languages, just flipped around. His point is that programmers who limit themselves to knowing just one language limit their ability to think about programming. I think the same goes for the Microsoft.

What I find really interesting is the way that the language teams end up drafting one another as we go forward. Drafting is the phenomenon mostly commonly used in cycling where a cyclist can maintain a higher speed with less energy when following in the backdraft of the cyclist ahead of him. (A better explanation can be found here.) A lot of cycling strategy involves members of the team riding ahead of other team members (say, Lance Armstrong) so that the following rider can conserve energy for the final push at the end of the race. Interestingly, drafting can also help the lead cyclist as well, although I lack sufficient physics knowledge to really explain that.

Anyway, the point of this whole digression is that a very similar thing happens inside of Microsoft as well. When the C# team decided to implement Edit and Continue, it was easier for them to do so than it had been for the VB team because the VB team had already worked out a lot of the details (and a lot of the kinks in the system) beforehand. Similarly, the C# team started implementing generics before VB did, so they ended up working out a lot of details for us ahead of time. In the end, each team takes advantage of the work the other team is doing to advance their own language more rapidly. It’s a very virtuous cycle.

Of course, a lot of the people who don’t like Edit and Continue are the same people who don’t think that Microsoft shouldn’t bother to have more than one language (read: C# is the “one true language”). So instead of drafting, they probably think of pollution instead. Ah well, to each their own…

Form constructors and DTEE

Some people were curious what I was getting at with my quick question yesterday, so now that I’ve got a little more time to explain, let me…

The problem that we’re looking at right now has to do with some subtle interactions between several new debugging features in VB 2005. One of the features is what we call Design Time Expression Evalutation (abbreviated to “DTEE”), which is just a fancy way of saying “you can evaluate expressions and call functions from the Immediate window even when your application isn’t running.” This was a nice feature from past versions of VB that we lost in VB 2002 and we’re happy to bring back in VB 2005.

The way DTEE works is that it actually starts up a copy of your application in the background when you try to evaluate something at design time. This background copy of your application is called the vshost process, and what the debugger does is set a breakpoint at the very beginning of the program to prevent the vshost application from actually running and doing things like putting up UI, etc. The vshost process then sits there in a debug break state, waiting for the user to ask to debug the application or do DTEE.

Another feature that I think we introduced in VB 2003 but are extending in VB 2005 is something called “Just My Code.” This is a debugger feature that filters out all the non-user code from places like the callstack window and prevents the application from breaking in non-user code. This means that if you call a .NET Framework API that throws an exception, you’re going to break in your code that called the API rather than way down in the Framework (since you likely don’t have any source code for the Framework). You can always turn off JMC in the options dialog if you want to see non-user code, BTW.

Now, let’s think about a new WinForms project for a moment. A new WinForms project contains no actual user code, because all the code in the hidden partial form class is marked as non-user code. So… can you see the problem? Right. You can’t do DTEE on a new WinForms project because the vshost process tries to put the breakpoint at the beginning of the program, but since the beginning of the program is not user code, JMC prevents the breakpoint from getting hit.

This isn’t a huge, huge deal – there are a couple of ways we can attack this problem. One proposed way would be to make changes to the debugger to recognize this kind of situation and handle it in a different way. Another proposed way was to change the way that we handle Sub New in the hidden partial class, perhaps making it compiler generated (and thus allowing us to fiddle with the way the debugger sees it). This would mean automatically generating the call to InitializeComponent as well, but what happens if the user specifies their own Sub New? Should we still automatically generate the call to InitializeComponent? If so, should it be before or after the user code in Sub New?

So the purpose of my request for feedback was to get a general feel for how we might have to proceed if we went down that path. The most important thing, of course, is to First, do no harm (to mis-quote the Hippocratic Oath). In solving one problem, we don’t want to create more problems for people.

I’ll let you know what we end up doing in the comments here… Thanks for all the quick feedback!

Feedback request: Form constructors?

A quick request for feedback… How often do you:

  • Use Sub New in a form instead of handling the form’s Load event?
  • When you do use Sub New, are there things that you have to do before the call to InitializeComponent, or do things generally go after the call to InitializeComponent?

We’re thinking about how to solve some issues that we’ve uncovered in the beta and this feedback might help in deciding how to deal with them. Thanks!

I’m rich, I’m rich!

Well, not really. However, I did get my first royalty check for The Visual Basic .NET Programming Language this week, which was exciting. Since this was my first book, I had no idea at all: a) how many books I might sell and b) how much that might mean in royalties. I was just hoping that it might bring in enough to, you know, go to McDonalds for a dinner or two.

I still have no idea if the book is selling “well,” since I have no idea what to compare the numbers to, but the royalties were quite a bit more than I had imagined. (Which may be more of a testament to my pessimistic expectations than to the size of the check.) I mean, it’s not like it’s a huge amount of money and I’m certainly not quitting my day job yet to write full time – I’ll leave that to the Petzolds of the world – but it ain’t nothin’. I still haven’t done the calculation yet, though, to figure out what the current “per hour” rate would have been for writing the book. That might still be a bit depressing…

Now just go out there and buy, buy, buy the book! Buy a second, third, fourth copy! Perish the thought that sales should fall off and I’d have to go back to buying lottery tickets to fuel my dreams of vast wealth…

Movin’ out

You may notice that comments are temporarily turned off on this blog for a day or so. This is because I’m moving the blog out of my basement and onto a hosted ASP.NET service, easerve.com. As much fun as it’s been to run everything myself, the reality that I’m not cut out to be a full-time system administrator has slowly sunk into my consciousness over the past year. That, and my wife really wants a webmail solution for her domain and I really don’t want to spend the time tracking one down, setting it up and maintaining it. So off we go. Once the DNS updates have propagated, you’ll be able to post comments again. Here’s hoping the move is smooth!

Dynamic languages/dynamic environments

The .NET Languages blog recently pointed me to an SD Times article by Larry O’Brien entitled “Dynamic Do-Over.” Most of the later part of the article talked about IronPython and Jim Hugunin, but the earlier part touched on something that I’ve discussed earlier: the question of language strictness when it comes to typing. The more I think about it, the more I believe that static typing is a good thing and something that should be encouraged wherever possible. But when I say that, I don’t mean to say that there isn’t something of value in all those scripty-like dynamic languages out there. I think Larry hits the nail on the head in his article: what makes dynamic languages so great is not their loose type systems, but their dynamic environments.

In the end, I think anything that helps the average programmer be more productive is a good thing. By and large, static typing satisfies this dictum: static typing enables all kinds of programmer productivity features like Intellisense, better error messages at compile time, etc. (One could argue, I suppose, that you could lose the static typing and use type inferencing instead, but I wonder whether it would be possible to build a complete enough type inferencing ruleset that: a) was implementable, b) made some kind of sense, and c) could compete with just stating the damn type of your variables.) Dynamic environments also do this: edit and continue (pace Franz et al.), continuable exceptions, being able to call functions at design time, etc. So I think marrying the two worlds has some facinating possibilities.

I should add, though, that I don’t believe loose typing has no use. One application for loose typing that I’m particularly interested in is modeling unstructured or semi-structured data such as XML. I think the work that the E4X group has been doing is particularly interesting…

Late bound overload resolution and structures

I was just reviewing some notes I made about updating the language specification and I came across this little gem: What do you think the following code does?

Option Strict Off
Structure MyStruct
Public MyField As Integer

Public Sub Mutate(ByVal x As Byte)
MyField = x
End Sub

Public Sub Mutate(ByVal x As Short)
MyField = x
End Sub
End Structure

Module Module1

Sub Main()
Dim o As Object = 5S
Dim s As MyStruct

s.MyField = 10
s.Mutate(o)
MsgBox(s.MyField)
End Sub

End Module

Yes, that’s right, it prints 10. Why? Well, it has to do with how we handle overload resolution and loose-typing.

When we were originally coming up with the rules for overload resolution, we noticed a particular problem with loosely-typed code (that is, code that doesn’t explicitly state the types of its variables). Because all the variables in a loosely-typed program are typed as Object, there are a lot of places where the regular overload resolution rules fall down. Take the example above: if you follow the normal rules of overload resolution, the call to s.Mutate is ambiguous. That’s because the argument type is Object and the two parameter types are Byte and Short. Object has narrowing conversions to both Byte and Short, so we can’t actually choose between them.

However, we thought, at run-time all values become strongly typed. So even though the variable may be statically typed as Object at compile-time, if we defered the overload resolution to run-time, we could probably resolve the overloading correctly. (I should point out again that this only applies to loosely-typed programs: in a strongly typed program, you’d just insert a cast to resolve the ambiguity.) So we added a special “loosely typed overload resolution rule” to handle this situation: if overload resolution produces an ambiguous result solely because of narrowing conversions from Object, then we defer the resolution until run-time. Or, in other words, we make the call late bound. This isn’t such a bad thing because if you’re doing loosely-typed programming, by definition you’re going to be doing a lot of late binding anyway.

OK, so all is well and good, no? Well, not exactly. You see, the problem in the above situation is that to make the call to Mutate late-bound, we have to call some helper functions at run-time. And those helper functions take the target of call as a value typed as Object (since you can late-bind against any type). Which means that we have to cast the target of the call to Object. Which means that, since MyStruct is a structure, we have to box the value. Which means that the target of the call is no longer the stack location indicated by s, but instead some heap location where we boxed the value to. Which means that Mutuate changes the heap location instead of the stack location, and so the change is lost when the method returns.

This is an unfortunate subtle interaction between two features. The good news is that you really only will get into trouble when mixing strongly-typed with loosely-typed code. If, in the example above, you’d typed s as Object and assigned it a new instance of MyStruct, everything would have worked as expected because the structure would always have been boxed. On the other hand, if you turn Option Strict On, the above example will give you an error on the overloaded call to Mutate and will require you to resolve the ambiguity with a cast. So the chance of anyone running into this is thankfully remote.

Be careful what you wish for…

So we’d been bugging Scoble for a while about getting more VB interviews (besides Robert Green’s appearances) up on Channel 9 and about a month ago, he took me up on my offer to interview about VB. He stopped by with his camera and we did our little bit and then he left. Then yesterday I get an email with a bunch of pointers to videos of our interview for me to review and make sure I didn’t say something horribly stupid or anything.

Ug, be careful what you wish for. The experience of watching myself on video is just torture – do I really look like that? I mean, I’m sure it’s fine – my wife and friends seem to think I look and sound OK – but geez. I’ve finally taken to just listening to the audio instead of watching myself and that seems to be better (although still a bit difficult).

Am I just being neurotic? Or does everyone hate to watch themselves on camera? (I guess not everyone, judging by reality shows.)