Note: How many times have I promised never to get mixed up with VB? But here I go again. This particular backsliding example is from September of 2008. It's probably outdated, but as before, I am leaving it for historical reasons.
I thought I was cured. I hadn’t
thought about VB or any other computer language for years. But then out of
the blue a woman named Kathleen Dollard sent me an email asking if I was the
same Bruce McKinney who wrote a certain book about a certain language. Well,
yes, I did write that book back in a different lifetime. I started a
conversation with Ms. Dollard (who turned out to be some sort of VB.NET
goddess) and during that conversation I idly asked how VB.NET had turned
out. I had written a short analysis of VB.NET in its
beta stage back in 2001, but I never saw the finished product, much less the current version of
what should have been a mature language.
Well, one thing led to another (as it had in the past and as I had promised it never would again). Kathleen pointed me toward what I thought was a crippled toy version of VB.NET called Visual Basic Express Edition. Why not download it and at least look through the language syntax to figure out what happened? Well, anybody reading this probably knows that VB Express is one of the largest toys in history. It didn’t take long to realize that I had probably made a mistake.
The first thing I discovered is how bad the help and the
help engine are. It's a mess of incompleteness and broken links—even worse
than the execrable help in VB6. During setup I made the mistake of saying I
wanted help first on my disk rather than online. The result was total
confusion with all sorts of languages mixed up with incomplete topics.
Everything seemed related to VB6, and some of it was completely wrong about
VB6, and its differences from VB 2008. You'd think after seven years most
VB.NET programmers would be new people who wouldn't know or care about VB6,
but the internal help seems oriented to people who skipped all those earlier
versions and were just then converting from VB6.
Finally I got online to an MSDN site that summarized all
the language features. It wasn't great, but way beyond what came with the
program. I worked for five or six years in Microsoft language documentation
before I went into development and then to Microsoft Press. We had less
training and education than documenters have today, but we did a much better
job. Are there no good technical writers left? Is MSDN paying three times as
much as the VB team to get the few semi-competent ones? It was depressing.
Once I finally found documentation, I had some surprises.
First I checked everything I criticized in the beta and sure enough the
mistakes were mostly still there. They really did cripple arrays. They
really did put AddressOf in the Delegate syntax even though it's a lie. They
really did change While/Wend to While/End While instead of killing it. They
really did change the Property syntax for no reason other than to break
code. They really did remove the powerful Imp and Eqv operators. Fortunately, they restored Static, which some idiot had removed
from the beta.
Now I know these are really small things in the big
picture, but languages are about symbolism and metaphor. If you don't
understand the importance of metaphor you shouldn't be designing languages.
And if you're going to clean house and change everything, why not kill Dim?
If they had just added Local, they could have left Dim in place for
compatibility, but no thoughtful coder would have ever used it in new code.
But no one on the VB team seems to understand the purpose of compatibility or
deprecated features.
The thing that bugged me the most was the crippled arrays.
In VB6 (as in all real high-level languages) you can declare any array
bounds you want. For example, assume I wanted an array of temperatures
within a reasonable range so that I could record how many times each
temperature was reached.
Const iMinTemp As Integer = -50, iMaxTemp As Integer =
125
Dim aTemp(iMinTemp To iMaxTemp) As Integer
aTemp(iTodayTemp) += 1
That’s how I’d do it in VB6 (or Pascal or any other
civilized high level language), but that’s not possible in VB.NET (or C# or
Java or any of the other pretenders). Instead I’d do something like:
Dim iOffsetTemp = 0 - iMinTemp
Dim aTemp(0 To iMaxTemp - iMinTemp) As Integer
aTemp(iTodayTemp + iOffsetTemp) += 1
I have to do all the stupid bookkeeping (with all the risk
of an off-by-one error) every time I use the array even though that’s the
sort of thoughtless bookkeeping high level languages are supposed to take
care of. Every time I used one of these brain-dead arrays it would make me
angry that someone had deliberately crippled our language.
But of course that shouldn't be a problem with VB.NET, because, unlike VB6, it has all three legs of the the object-oriented stool. If I don't like the way they do arrays, I can inherit their crippled arrays to create real ones. Right? Unfortunately, when I tried this I found out that you can't inherit arrays because there isn't really an array class. Arrays have a whole list of great methods and properties that make it look like one of the coolest classes in history, but it's really an internal language feature that has a non-standard class syntax. The documentation says right up front (one of the few cases of clear documentation) that you can't inherit arrays.
But I still have encapsulation. I can just encapsulate a real array inside my own class and extend it by adding features. Since VB.NET has operator overloading, I can overload operator() to make my array have an array-like syntax (just as you could do in C++ with operator[]). Alas, the parentheses used in the array syntax aren't considered an operator in VB.NET. You can encapsulate arrays with just a few lines of code, but the syntax for using the resulting class doesn't look anything like the syntax for a real array, and you have to write separate classes for multidimensional classes. In addition you don't automatically get all those cool array methods and properties like you would with inheritance. I created the class, but it wasn't worth the trouble.
I was surprised to even find operator overloading in VB.NET. Does overloading work nice and easy in VB? Or is it loaded with gotchas as in C++? It looks like it's a lot simpler (and less powerful). You can overload your basic arithmetic and comparison operators, but you can't use equivalents of the weird C++ overloads for =, (), and [] operators. I’d have to get a lot farther into this than I want to go to figure out the limits of VB.NET operator overloading.
I did discover by accident that one of my original
criticisms of VB.NET is completely wrong. Although it doesn't have Shl and
Shr operators, it does bit shifting with << and >> operators. Does
that mean you could violate all operator overloading guidelines as they do
in C++ and overload << to be a stream formatting operator? Interesting
possibilities.
I found some
other surprising new stuff such as += and
-=. I didn't expect that. It's hardly in the
Basic tradition, but I always appreciated those operators in C. They also
added signed integers. Kemeny and Kurtz didn't just forget about signed
integers. They left them out on purpose and bragged about their absence as a
feature. I'm sure signed integers are there for interoperability, which
shouldn't be a Basic goal and wasn't needed, not even to call signed
arguments in the library.
Generics look simple enough, and it would be nice to have them built
into the language without the weird side effect of the C++ preprocessor. I
had a great time building generic C++ classes for VB safearrays (now gone).
I hope generics in VB are as much fun as in C++, but less confusing.
But enough philosophizing. Let's write some code. I start out by trying File New Project. Interesting choices. I have not the slightest idea what a WPF Application might be (and when I check help I see I don't want to know), but I can guess what a Windows Form Application might be. So I try it. There's my form. Once again VB guesses that I want to call my form variable Form1 and that the caption on it should be "Form1". Just as wrong and evil as in VB1. You'd think by now they'd have learned not to encourage bad habits.
OK, I want to put a button on this form, but there are no
buttons. I play around for three minutes before I figure out how the toolbox
slides over. Cool.
I put a button on the form. It comes out as
Button1 rather than
Command1. A tiny step forward. It takes me a minute to figure out how
to change the variable name to something sensible: btn.
I add a label named lbl. When I remove the text
from this label it disappears. Something funny is going on in the
properties, so I examine the list. There are some properties I've never
seen. I put the cursor on an unfamiliar one and press F1. It tells me what a
property list is, but nothing about any particular property. Hmmm. Finally I
figure out how to turn off AutoSize and make the label 3-D.
I click on the button and insert lbl.text = "Hello, world" in the btn event procedure. I run it and it works. Just as miraculous as in VB1. But when I click it again nothing appears to happen because it’s overwriting the same message. I need the text to change. I go back to the event procedure and type Static c As Integer = 1. Ahhhh! What a luxury! What I would have given to do that back in VB5. I started begging for this in VB4.
I go to the bottom of the procedure and type c += 1. I'm still not sure I like this += stuff, but I do it anyway. Then I think what if VB has... Naw, it couldn't be. I try c++, and what a relief. It doesn't work.
Then I go back up and change the label assignment to
lbl.text = "Hello, world " + c. I get an InvalidCastException. So, VB is not so loose anymore with type conversions.
Good riddance to “Evil Type Coercion”. How about
"Hello, world " + Str(c). This works. But then
I think: This is an object oriented language. An integer variable ought to
have conversion methods. So I remove the CStr
and type a dot after c. All the methods appear
including ToString. Wow! I type lbl.Text = "Hello,
world " + c.ToString. Yes! When I run it, the text counts every time
I click.
Not quite like old times, but it has its moments.
Then I remember an interesting choice not taken from the File New Dialog. Can I really use VB to write a console application just like the miraculous BASICA program that changed my life back in 1983? I try it and there's the Sub Main() followed by End Sub with a cursor sitting in the middle. It looks more like my first C program than my first BASICA program, but it's obvious what to put in between. I type Print "Hello, World".
VB encloses my string in parentheses.
Is Basic's syntax difference between a Sub and a Function really gone?
Apparently so. When I press Run, it starts a console, but then fails and
tells me an InvalidCastException was handled. A syntax diagram tells me that
print takes a file number followed by ParamArray
Output(). OK, we're not in
This isn't enough information, so I move the cursor to
Print and press F1. Information Not Found. No help on Print? I look in the
help index. No Print statement. There is an entry for a Print # statement,
but that takes me to a table of changes from VB6. I find Print # in this
table and click on a topic called Print and PrintLine. Information Not
Found.
After messing around for a while and seeing more
Information Not Founds, I figure out that I may be on the completely wrong
track. It appears that maybe writing text is done through the FileSystem.
Instead of Print, I try
My.Computer.FileSystem.WriteAllText("Hello, World"). This fails
because it needs three arguments, the first a file name. Maybe there is a
standard string for the console such as "CON" or "SCRN". I think this worked
in some version of C file I/O. After some experimenting, I try arguments
WriteAllText("scrn", "Hello, world", True). This
is valid and runs, but doesn't print in a console. Probably somewhere on my
disk is a file called "scrn" containing the words "Hello, world". I search
and sure enough, there it is in a semi-random directory.
I put my cursor on WriteAllText and press F1. Information
Not Found. I mess around for a while longer and find a link to a help topic
on console applications. Information Not Found. Do I really want to be a VB
programmer? Information Not Found.
Now it happens that at the moment my home internet connection is broken so I have to go to work to get online, but I'm doing this at home. I could probably figure it out if I could get to MSDN. But there's no excuse for installing a broken help system on something called VB Express Edition that takes more than an hour to install. Sure enough, when I get back to the internet, the solution is simple, although I never find it in VB help or MSDN. Instead I google "VB.NET console sample" and find the information on a non-Microsoft web site. After several hours of research I have the classic first program for any new programming language:
Sub Main()
Console.WriteLine("Hello, world")
End Sub
There are some good things here, but overall I think I
better get this damn thing off my computer before I get really mad. Or
hooked.
Bruce McKinney