Category Archives: Visual Basic 2008

(Almost) final VB 9.0 language specification posted

I wanted to let people know that an (almost) final VB 9.0 language specification has been posted on the download center. The spec is missing some copy-edits from the documentation folks, but is otherwise complete. Since I’m not going to get a chance to incorporate the copy-edits until I am back from vacation in January, I wanted to get the spec out there for anyone interested in documentation of the XML features that weren’t present in the previous version of the spec. (I apologize for the lateness of this vis-a-vis the release of the product itself, it’s been a busy fall.)

This updated language specification corresponds to Visual Studio 2008 and covers the following major new features:

  • Friend assemblies (InternalsVisibleTo)
  • Relaxed delegates
  • Local type inferencing
  • Anonymous types
  • Extension methods
  • Nullable types
  • Ternary operator
  • Query expressions
  • Object initializers
  • Expression trees
  • Lambda expressions
  • Generic type inferencing
  • Partial methods
  • XML Members
  • XML Literals
  • XML Namespaces

Questions, comments or criticisms can be sent to basic@microsoft.com. Thanks!

Beta VB 9.0 language specification released…

While I was visiting MSR Cambridge this week with some other people from Redmond, Beth put up the Beta 2 version of the Visual Basic Language specification on our developer center–so she got to beat me to the announcement! This updated language specification corresponds to Visual Studio 2008 and covers the following major new features:

  • Friend assemblies (InternalsVisibleTo)
  • Relaxed delegates
  • Local type inferencing
  • Anonymous types
  • Extension methods
  • Nullable types
  • Ternary operator
  • Query expressions
  • Object initializers
  • Expression trees
  • Lambda expressions
  • Generic type inferencing
  • Partial methods

The following features are not covered but should be shortly:

  • XML Members
  • XML Literals
  • XML Namespaces

The XML features are a little more difficult because I’m debating how much I should just refer to the XML 1.0 spec, versus how much I should specify explicitly. I’ll probably err a little more on the side of the latter, since it’ll be necessary for understandability…

What’s in VB 2008? What’s out?

As a medium of communication, blogs have their strengths and weaknesses. The informal nature of the communication makes it incredibly easy to communicate information on an ongoing basis. The down side, of course, is that the very informality of blogs can also trip you up if you don’t pay enough attention to follow up. I’ve certainly been guilty of that on this blog (there are still some loose ends I think haven’t really been tied up), and we’ve been guilty of that as a team.

One thing we haven’t always done a good job of is keeping people apprised of feature decisions that we’ve made as the VB 2008 product cycle has progressed. As a result, there has been some confusion as to what features are in and which features are out of the product. So let me start by giving a reasonably concise list of the feature set for VB 2008…

General features

  • Friend assemblies. We now pay attention to the InternalsVisibleTo attribute.
  • Relaxed delegates. As long as there is a way to map one delegate’s parameters to another, you can now convert freely between delegate types. (I’d wanted to see this extended into full delegate currying, but that will have to wait for a future release.)
  • Runtime agility. The ability to compile without a VB runtime, or targeting another VB runtime.
  • Calling Object members on interfaces. Minor feature, but useful in some situations.
  • Ternary operator. A short-circuiting conditional expression like C’s ?: operator.
  • Improved generic type inferencing. In VB 2005, we would not infer a type for a type parameter that had multiple inferred types (i.e. a parameter T matched two arguments typed as Integer and Long). In VB 2008, we will now pick the wider of the two types. (Actually, it’s more complex than this, but you get the idea.)

LINQ

  • Local variable type inferencing.
  • Anonymous types.
  • Extension methods.
  • Nullable types.
  • Query expressions. This is the From…Where…Select… expression.
  • Object initializers. For VB 2008, we will only support initializing read-write fields of non-collection objects (more on this further down).
  • Expression trees.
  • Lambda expressions. For VB 2008, we will only support expressions in lambdas, not statements.
  • Partial methods.

XML

  • XML literals.
  • XML members.
  • XML namespaces.

I think most everything on this list has so far been discussed, with the exception of the omissions from object initializers. Our original plans, going back to PDC05, included several more features for object initializers, such as being able to write to read-only properties, as well as collection and array initializers. In the end, the schedule for VS 2008 was not sufficient to implement these features with a high degree of confidence. Which unfortunately means that they will have to wait to a release beyond VS 2008.

VB Runtime agility, Orcas and new platforms

One of the problems that we’ve run into when trying to get new platforms such as the Compact Frameworks or Silverlight to support Visual Basic is getting the VB runtime supported on the new platform. The VB runtime, besides having a bunch of user functions such as Left and MsgBox and such, contains a number of language helper functions that are required for the correct functioning of the language. For example, when you convert an Integer value into a String value, we emit a call to a helper that does the conversion for you, since there is no native IL instruction for this. The number of situations where we emit helper calls isn’t huge, but there are some core features of the language that just won’t work without them. This is why there’s been no officially supported way to remove the reference to Microsoft.VisualBasic.DLL.

More than the language, though, the problem is that the compiler won’t work without the helpers, either. Basically, the VB compiler will just crash when it fails to find a VB runtime helper. Even if you’re careful to avoid features that don’t use helpers, it still doesn’t mean you can just run without a reference to Microsoft.VisualBasic.DLL–there are still many cases where we sanity check for helpers even if we aren’t going to use them. Which means that even if you managed to figure out how to get the compiler to not reference Microsoft.VisualBasic.DLL, it was likely that lots of things aren’t going to work.

As we faced the prospect of more and more platforms starting to support .NET, we realized that we needed to do something about this situation in Orcas. So we did a feature we’ve been calling “runtime agility.” The runtime agility work basically enables new platform developers to compile without a standard reference to Microsoft.VisualBasic.DLL and we’ll only barf on missing runtime helpers if you try to use a feature that requires them. And when we do barf, we give you a nice error message telling you what helper was missing instead of just crashing. You can also redirect the VB runtime reference to another DLL if you’re building a new one for your platform. For platform developers, this means that they can more easily develop a VB runtime DLL for their platform without having to stub in a bunch of helpers that they don’t support. And, yes, if you really want to run without a VB runtime, you can now do that.

This switch is only supported on the command-line for Orcas–there’ll be no UI expression of it. The switch is “/vbruntime” and should show up, I believe, in Beta2.

Partial Methods in VB

As is always the case in a major release, there are a number of smaller features that don’t get very publicized because they’re not as big or sexy as the major features. One that someone asked me about privately in email was partial methods. VB will support them in pretty much the same way that C# does. In fact, rather than writing a big, long entry about it, you could just check out Scott Wisniewski’s excellent entry on them. You can also check out Wes Dyer’s excellent entry on them for C#.


How’s that for lazy?


Updated 05/30/2007: Somehow I’d missed the fact that one of our own wrote a whole entry on them on the VB blog! Eek! My apologies to Scott for missing his entry and check it out!

Mutable and immutable anonymous types, and keys

About a month ago, the C# team announced that they were making anonymous types immutable in C# 9.0. The issues with mutable anonymous types are pretty well described in Sree’s blog entry, but what it boils down to is this: in several places in LINQ, anonymous types are used as keys for things like grouping and filtering. For example, if you group customers by state and country, then the grouping is done on a composite key made up of the State field and the Country field in an anonymous type. To enable keys to be used to do grouping efficiently, they have to expose a stable hash value. That is, once a key has been constructed, it always needs to return the same hash value.

The problem was that anonymous types base their hash value on the hash values of the constituent members of the type. If those values are mutable, then that means that the hash value is mutable. Which means that the hash value might not be stable, which means that it might be possible to really hork up LINQ queries by accidentally changing keys during an operation.

In looking at this problem, though, we didn’t want to throw the baby out with the bathwater. Anonymous types are somewhat limited at the moment because they cannot be named, but you can use late binding to work with them even outside of the context in which they were declared. And future features that we’re interested in exploring, such as nominal anonymous types and dynamic interfaces, may make anonymous types even more useful. As such, it seemed too drastic to simply make them immutable, especially because this would be a one-way decision–once they were immutable, compatibility would make it extremely difficult to make them mutable again in the future if it become more desirable to do so.

At the same time, it occurred to us that the problem we’re dealing with here–generating hash values–is one that applies to many situations, not just anonymous types. Generating hash values is a common operation for types, and making it easier to do that right seemed to be a win. So instead of changing the way anonymous types work, we’ll be introducing in Beta 2 a way to more easily generate a correct hash value from a type. For Orcas, this will be limited to anonymous types, but beyond Orcas, we’d like to generalize this to all types.

In Beta 2, you will be able to specify a Key modifier on a field of an anonymous type (i.e. “New With { Key .Country = “USA”, Key .State = “WA” }”). This modifier will do two things: one, it will make the field read-only (since keys have to be stable), and two, it will cause GetHashCode to be overridden and call the GetHashCode of the key field. You can have as many Key fields as you like, and the hash codes of all the keys will be combined. The LINQ query expressions will automatically use Key fields in any situation where a key is going to be generated (for example, Group By), but you will need to include the Key modifier if you are calling the LINQ APIs directly. Post-Orcas, we’d like to generalize this concept to all types and allow you to declare Key properties or fields, and do the same thing as with anonymous types. This will, we hope, simplify the work of making types that can be easily hashed.

IIF becomes If, and a true ternary operator

Many months ago, I discussed the fact that we were finally planning to come up with a true ternary conditional operator that would allow short-circuited conditional expressions. (Just as a quick recap: the current problem with the IIF function is that it evaluates all the arguments since it is just a regular method call. So “IIF(x Is Nothing, “Empty”, x.Name)” will throw an exception if x is Nothing, because we still evaluate x.Name.)

At the time, we were considering taking the IIF function and making it intrinsic. In the end, this looked like it would just be too big of a compatibility problem. There were lots and lots of subtleties around the return type and the short-circuiting behavior that were going to pose problems. So instead we simply reused an existing keyword and invented a whole new operator–the If operator. The If operator works just the way you’d expect it–it evaluates the first operand and if it is True, evaluates and returns the second operand. If it it’s False, then it evaluates the third operand and returns that. There is also a binary form of the If operator that takes a reference type or a nullable value type as its first operand. If the value is not Nothing, then the first operand is returned. If the value is Nothing, the second operand is returned. This is useful for doing a database coalesce operation, something like “If(x.Name, “<no name>”)”.

The result type of an If operation depends on the types of the two operands that might be returned from the operation. In general, we pick the wider of the two types. If the two types don’t convert to each other, then you get an error. (For example, if you did “If(<boolean>, <integer>, <long>)”, the result type would be long. If you did “If(<boolean>, <Button>, <string>)”, you’d get an error because there was no conversion between Button and string.)

One question people might have is, “why the parenthesis?” More than a few people have suggested an expression form of the If statement, something like “x = If y Is Nothing Then “<none>” Else y” or other variations that weren’t delimited by parenthesis. In the end, most everything that didn’t use parenthesis as delimiters just ended up looking funny when you put it in an If statement (“If z = If y Is Nothing Then “<none>” Else y Then…”) or funny when you strung a few of them together using AndAlso/OrElse. For what it’s worth…

The If operator won’t appear in Orcas until Beta2, unfortunately. So you’ll still have to wait a bit longer…

(And, as a final piece of trivia, why is the IIF function called “IIF?” It stands for “Immediate If“.)

Beta 1 of Orcas is out (for those domiciled under igneous formations…)!

My +1 link postings are always the last ones in to the pool, but in case you haven’t seen it elsewhere, Beta 1 of Visual Studio Orcas is now available for download! This has a large majority of the Orcas features for VB in it, although there are still some features that will be coming in post-Beta1 (lambdas, nullable types, etc.) because of the way the schedule came together. (You can find more details about new features in Beta1, such as “Intellisense everywhere” on our team blog.)

I’ve been writing a LOT of Visual Basic code in the past couple of months, and this is making me excited to work towards getting off of VB 2005 and on to Orcas…

Check it out!