Bill pointed out that I didn’t have a nice zipped up source release to go with the binary, so I added one. [07/12/2014: The sources are now on GitHub.] It looks like people were starting to join the workspace just so they could get the source, so I just declined them for now so people could pick up the source zip if that’s all they wanted. If you want to join the workspace to make contributions, just reapply. The more the merrier!
Category Archives: Visual Basic
VBParser Beta 1 released…
When I started this blog a year ago, one of the things that I mentioned that I was working on in my spare time was a scanner and parser for the Visual Basic language. It’s kind of been on the back burner, behind things like VB 2005 and the book, but it’s finally gotten complete enough to release! I created a GotDotNet workspace [07/12/2014: The sources are now on GitHub.] for the code, and there’s a binary release there as well.
I’m calling this release a “beta” because although I’ve run my own tests on it, I haven’t subjected it to enough stress to be 100% confident in it. (Keep in mind: this is just a sample that I’ve worked on in my own time. It’s not an official Microsoft thing, so I’m the developer and tester.) If you find bugs, feel free to submit them to the workspace and I’ll see about getting them fixed. If you’d like to contribute something, sign up for the workspace! For now, the parser only supports the language we shipped in VB 2003. As time goes on, I’ll look into extending it for VB 2005.
The goal of the parser, besides being a fun side project in VB for me, is to be available to anyone who might want or need to scan or parse VB code. I’m hoping it will encourage people to write tools that work with VB code, and I have a few ideas of my own… Once I get some more time to spend on other side projects, that is. I’m not holding my breath…
Interesting take on the VB mentality…
Ted Neward has an interesting take on the VB mentality and it’s meaning in an entry entitled “The problem of “Do It Yourself” and Java”. A small quote:
[…] The VB community has long been a community that focuses on “getting the job done”, no matter what it takes, which of course to the ears of a C++ guy has that evil and despised overtone of “HACK” written all over it. The C++ guy would MUCH rather find the elegant solution, rather than live with code that smells. Unfortunately, this sort of thinking tends to lead towards solutions that are single-shot and specific to the project (if not the company) that creates it. […] It’s a problem I’d never seen before until I started spending more time in the company of those who actually come from that community. […] Don’t believe me? Take some time to hang out with the local VB crowd for a while, and just see how different their approach, styles, and thought patterns are. And don’t, for God’s sake, look down on their way of doing things, or you’ll be missing the point entirely.
The entry is definitely worth checking out!
Visual Basic Power Pack released!
I can’t believe I’m the first person to blog about this (maybe my aggregator’s stuck?), but the new Visual Basic Power Pack has been released on GDN. Here’s a description:
The Visual Basic Power Pack consists of seven custom controls written in Visual Basic .NET 2003. The controls provide enhanced user interface elements and enable you to create more interesting and more colorful client based applications.
The Power Pack controls consist of:
· BlendPanel. This provides a background for a form where the color fades from one shade to another.
· UtilityToolbar. This is a toolbar whose look and feel is similar to the Internet Explorer toolbar.
· ImageButton. This is a button that displays a graphic over a transparent background.
· NotificationWindow. This displays text and graphics in a pop-up window (commonly known as “toast”).
· TaskPane. This is a container that provides collapsible frames for displaying additional information on a form.
· FolderViewer. This displays directories in a hierarchical format.
· FileViewer. This displays a list of the files in a specified directory.
They’re being released as a sample, so full source code (in VB, of course!) is available. Have fun!
For Each and Option Strict
Duncan pointed me to a thread on GotDotNet that asked a frequently asked question: why doesn’t For Each require a cast when Option Strict is on? For example, the following code is entirely legal:
Option Strict On
...
Sub Foo(ByVal array() As Long)
For Each i As Integer In array
...
Next i
End Sub
As For Each iterates through the array, each element of the array is automatically cast from Long down to Integer without comment, even though Option Strict usually requires an explicit cast. Why is that? Mostly for developer convenience with dealing with collections such as Collection or Arraylist. In those cases, the element type of the collection is always Object. If we required a cast to iterate through a collection of Object values, where would you put the cast? There’s no place to actually do the cast in the For Each statement, so you’d be stuck having to have your iterator variable be typed as Object and then doing the cast yourself into anoher variable:
Option Strict On
...
Sub Foo(ByVal array As ArrayList)
For Each o As Object In array
Dim i As Integer = CInt(o)
...
Next i
End Sub
Since ArrayList/Collection object tend to have the same type in them and people iterate through them a lot, we decided that it made more sense to bend the rules in this case and do the cast automatically for you. (You can thank us later.) As an interesting side-note, C# does exactly the same thing in their foreach statement.
Conversion operators in VB
In my entry on “native” languages on the CLR, I made a blanket statement that the intrinsic VB conversion operators would be faster than the conversion functions in the Convert class because they compile down to IL rather than function calls. In my quest to emphasize my point, however, I made a serious misstatement which was not intentional but should be corrected. Not all intrisic operators compile down to simple IL instructions, although most do so. And the ones that don’t are worth discussing. So let me spend a moment talking about conversions.
The intrinsic conversion operators (CObj, CByte, CShort, CInt, CLng, CDec, CSng, CDbl, CDate, CStr, CChar, CType, DirectCast) generally fall into several broad categories of implementation:
- Conversions that are pure IL statements. The best example here is the conversion from Integer to Long or Long to Integer. This compiles directly down to a conv.i8 or conv.i4.ovf instruction, respectively. You really, really, really don’t want to be calling functions to do this kind of conversion unless you’ve got a lot of faith in inliners, which I generally don’t.
- Conversions that are mostly pure IL statements. The best example here is the conversion from Double to Integer. This compiles down to a call to Math.Round and then a conv.i4.ovf instruction. The purpose of the extra call is to implement banker’s rounding, which the CLR doesn’t natively support. (In banker’s rounding, a decimal number equidistant between two whole numbers is rounded to the nearest even number. So 3.5 rounds to 4, but 2.5 rounds to 2.) In this case, calling Convert.ToInt32(Double) is not the same as CInt(Double), and you have to choose which semantic you desire.
- Conversions that are calls to the Convert class. The Decimal type is not natively supported by the CLR. As such, conversions to and from Decimal (with the exceptions listed below) turn into calls to Convert.ToDecimal() or the appropriate helper. There’s no point in us reimplementing the conversion since it’s the same for both the CLR and VB. In this case, calling Convert.ToDecimal(Integer) is exactly the same as CDec(Integer).
- Conversions that call VB specific helpers. There are only two cases that fall into this category: conversions to and from String, and conversions from Object.
- Conversions to and from String call VB specific helpers because VB does a variety of extra things for you. For example, when converting String to Integer, we’ll parse decimal numbers and do the appropriate rounding. So while Convert.ToInt32(“10.5“) will barf with an exception, CInt(“10.5“) will work just fine. And this is just one example of the nice stuff that we’ll do for you. As always, though, extra functionality can equal extra cost. So if you just want the very basic functionality that Convert.ToInt32() calls (or you prefer calling two functions), you might get slightly better performance by calling it instead of using CInt on a String.
- Conversions from Object call VB specific helpers because VB needs to be able to implement VB specific semantics (such as the String conversions and banker’s rounding) when converting values from one type to another. For example, Convert.ToInt32(CObj(“10.5“)) still throws an exception, while CInt(CObj(“10.5“)) won’t.
One interesting thing to note is that if you really want only the CLR conversions and nothing else, the DirectCast operator will turn off most of the VB-specific conversion features (I believe we still do banker’s rounding, though). Then you can call the Convert class methods when you run into conversions that DirectCast doesn’t support. I still think that this is an extreme way to go about things, but I know some people are just that way. Me, I use the regular VB operators and then look out for performance sensitive areas where I might need something different.
Application-level events.
The 3leaf guys have a short entry on application-level events, a new feature in VB for VB 2005. Check ’em out!
The Truth about Nullable Types and VB…
There’s been a little confusion about how VB’s going to handle nullable types in VB 2005, so let me try and amplify a little bit on the entry on the VB team blog.
What are nullable types?
One of the primary differences between value types such as Integer or structures and reference types such as Form or String is that reference types support a null value. That is to say, a reference type variable can contain the value Nothing, which means that the variable doesn’t actually refer to a value. In contrast, a value type variable always contains a value. An Integer variable always contains a number, even if that number is zero. If you assign the value Nothing to a value type variable, the value type variable just gets assigned its default value (in the case of Integer, that default value is zero). There is no way in the current CLR to look at an Integer variable and determine whether it has never been assigned a value – the fact that it contains zero doesn’t necessarily mean that it hasn’t been assigned a value.
Unfortunately, there are situations where it would be nice for value types to have an actual null state. The most common example is in a type that represents information from a database. Many databases allow columns of any type to contain a null value that means “you didn’t assign a value to this column.” For example, an Employee database might assign null to the Salary column of retired workers, meaning that they no longer have a salary (instead of assigning some magic value like zero to their salary, which might be accidentally confused to mean that they are still working for no money). The fact that the CLR doesn’t support null values for value types can be somewhat painful in this situation and is the reason that we have the System.Data.SqlTypes namespace. But those types do a lot of extra SQL-type stuff. Wouldn’t it be nice to have this for all value types?
The answer to this is yes, and the generics support added in VS 2005 allows us to do it. In VS 2005, we’re introducing a new generic type called Nullable(Of T) that adds nullability to any value type. How it does this is beyond the scope of this entry and is left as an exercise for the reader. But, suffice it to say, it works just fine. Here’s an example:
Sub PrintValue(ByVal i As Nullable(Of Integer))
If i.HasValue Then
Console.WriteLine(CInt(i))
Else
Console.WriteLine(“Null value!“)
End If
End Sub
What is C# doing?
From this base level of functionality, C# is taking nullable type support a bit further in VC# 2005. The primary features they’re implementing are:
- A new type modifier ? that means “nullable.“ So instead of writing “Nullable<int> i;“ in C#, you can write “int? i;“.
- A “coalesce“ operator ?? that is a quick way of converting a nullable type to a non-nullable type with a default value. So “int x; int? y; x = y ?? 0“ will assign the value of y to x if it is not null, and will assign the value 0 to x otherwise.
- Lifted conversions. If a type T has a conversion to type U, then the type T? will have a convertion to type U?. This means you can convert an int? to a long? without having to do explicit null checks.
- Lifted operators. If a type T supports an operator X, then the type T? supports the same operator. This means that you can add two int? values and get an int? value in return without having to do null checks.
Beyond the question of convenience, the last point means that nullable types in C# will support null propagation semantics. If you add two int? values and one of them happens to be null, then the result of the addition is going to be null. The one place where they break this is for comparison operators – unlike a language like SQL, comparing two nullable types is always going to result in a bool value, not a bool? value. I understand why they’re doing this, but it is an unfortunate thing to have to do.
What is VB doing?
Very unfortunately, nothing will be done in VB 2005 beyond what’s already supported by the Nullable type. We would very much like to support features along the lines of what C# is doing (although I don’t think you’ll ever be writing “Dim x As Integer?”), but nullable types were introduced into the BCL too late in the product cycle for us to be able to add extra features this time around. It’s very disappointing, to say the least, but we do look forward to adding more support in the future. (One interesting point is that it is likely that VB will be able to preserve null propagation when lifting comparison operators because we have two comparison operators. Score another point for Is vs. =.)
This isn’t to say that Nullable types won’t be very useful in VB – just that some extra niceties you’ll get in C# will be, um, temporarily unavailable. May we suggest while you’re waiting that you enjoy the other fine features of our language?
More than you might have wanted to know about late binding…
…can be found here. Good to see more from Cameron!
Aw, crap, Bill’s blogging… What have I done?
Bill McCarthy has started blogging and he blames me for it. What have I done? Bill is a VB MVP and is very outspoken about his opinions about the language, so it should be a good blog. It just means, though, that he’s got yet another way to harass me about stuff… 🙂
Welcome Bill!