I've often wondered how Microsoft convinced so many people that "you can do x without writing a single line of code!" was the test of a quality programming language. However they did it, they did it successfully with a number of people I've worked for. That's how I went from being a Java programmer to being a .NET programmer.

Since Microsoft ripped off many of the concepts in .NET from Java, most of the time I'm not bothered by my situation. I'd like to say I was still coding Java, but that's just my ego. You say StringBuffer, I say StringBuilder.

While .NET as a whole may not be totally useless and evil - especially if you're writing in C# - VB.NET is pretty awful. I've never worked with VB6, so maybe I'm spoiled. Programming in VB.NET is like trying to accomplish an important task with a stoned, poop-throwing monkey as your partner. It's amazing. You'd think C had never existed.


Everything in VB.NET has to be explicit, or the compiler gets really upset. If you want to overload a method, it's not enough to just create two methods with the same name and different signatures. You need to use the Overloads keyword. Want to declare a new variable? You'll need the Dim keyword (also a pretty good description of VB.NET's syntax rules).

Not all of the keywords VB.NET reserves (read: half the English language) are unnecessary. The rest fall into two categories: those which are taken from C and other languages, and those that are nonsense.

Not a moment ago, I was trying to remember the syntax for calling the constructor of a superclass from the constructor of a subclass. Super.new()? No... This.super.new()? No. This.parent.new()? Nope.

The keyword used to access the superclass is MyBase. In hindsight, it makes perfect sense. The class calls itself Me, so of course its properties are going to be MySomething. Having remembered how to do things properly, I was able to call MyBase to initialize MyProperties and run MyApplication until it was time to press MyCloseButton and send the whole thing to MyGarbageCollector.


I've heard that in SmallTalk, there are no primitives, only objects. Every language I've ever used until VB.NET has had primitive types. If I needed to make a primitive type a little more flexible, I could use a wrapper class to give it the functionality of an object.

VB.NET has its own special way of dealing with primitive types. At first, it might look like you access its primitives through wrappers. But those are no wrappers! They're Structures (which is not the same as a struct).

As far as I can tell, a Structure is an object that acts like a primitive. You can use it without instantiating it, you can only reference its value, you deal with it using operators, not methods. So then why isn't it a primitive? I assume it's so that the Structure can be easily recognized by the .NET Virtual Machine (or Common Language Runtime, as Microsoft calls it). But is the 32-bit integer really such an inconsistently implemented type that we can't just reference it directly?

Even if you could discuss primitive types as primitive types, you'd still have VB.NET insanity to deal with. If I want to set the value of a char, I can't do that by using a number or a character in single quotes. I have to do this: Dim c as Char = "?"c.

White space

VB.NET can only figure out what you're doing based on how much white space you leave around it. Sure, there are no curly braces or semicolons for putting several thoughts on the same line. It's not just that. If I wanted to, say, concatenate two strings, I'd need to have a space between each and the ampersand that joins them. Even though the ampersand is a damned operator, VB.NET can't recognize that if there's one in the middle of a string of text it should interpret the stuff on either side as two separate expressions.


The operators VB.NET offers are kind of limited and arbitrary. You can't ++ something to increment it. There is no time-saving ternary operator - you have to go through the whole if...then...else...end if, using up at least five lines and denying you the ability to perform a test inline.

Operators in VB.NET don't mean what you might think they'd mean, either. & is for concatenation, not bitwise operations (is there even such a thing in .NET?) or conditional statements. Not equal is represented as <>. Lots of popular operators are replaced by keywords, like and, or, and mod.


It's not just that a method has to have a keyword in its declaration in order to know it's a method that bothers me. It's that I have to use two different goddamned keywords for method declarations, depending on whether or not they return a value. If your method returns something, it's a function. If not, it's a sub.


Computer languages have a lot to do with formal logic, and anyone who's ever studied formal logic or even given it five seconds of thought can tell you that a true condition and (or plus) a false condition equals false. So if you were a computer programming language and someone told you to do something only if condition A and condition B were true, wouldn't you move on to the next thing if you realized one of them was false?

VB.NET, bless its little heart, likes to be thorough. If you have an if statement with two conditions, it's going to check both of them. Even if they're joined by and and the first is false. Even if they're joined by or and the first is true. This is a huge pain in the ass if you wanted to do something like

if not x is nothing and x.indexOf(y) > -1 then ...
That test is going to blow up if x is nothing (null, for the rest of the world), even though you check for that, because it always checks the second expression.


To cast something in VB.NET, you have to use an idiotic function called cType. There's also cInt, cDbl, and a host of specific functions for different data types. But for objects, it's cType. C# understands Superclass obj = (Subclass) otherObj. But apparently that was too straight-forward for VB.NET, so we use this archaic function that's doing god only knows what. Probably it's just running off and doing it the normal way somewhere where it won't confuse our little VB.NET programmer pea brains.

The whole thing makes me feel like I'm five and being told I have to do things the way some little Napoleon of a babysitter wants them done, "just because". Trying to understand VB.NET as a programmer is like trying to understand etiquette as a toddler. I get so fed up sometimes I just want to curl up on the couch with my blankie and watch Sponge Bob.

While I agree with pretty much everything prole writes, my overall assessment is very different: I love VB.NET. This is mostly because most of what in the writeup looks like a criticism of VB.NET is neither a bad thing nor specific to VB.NET. Some examples.
MyBase designed to make you feel like a five-year old?
As prole clearly states, the concepts of MyBase and Me are not specific to VB.NET; they are common to most object-oriented languages, including Java, and their common predecessor, Smalltalk (1975), which knew them as self and super. Now Smalltalk was in fact designed to be a programming system that five-year olds can use, so MyBase is indeed a concept in VB.NET designed for use by a five-year old. The unstated assumption, however, is that this would be a reason to shun VB.NET and prefer Java instead. Java has the exact same concept. It just uses a different name for it.
How Microsoft convinced so many people that You can do x without writing a single line of code!?
This was what Smalltalk set out to do, its single great innovation. To programming language specialists like you and me, object oriented programming means language features such as inheritance, polymorphism, methods and messages, up to and including the MyBase concept. To Alan Kay, one of the Smalltalk inventors, it means putting programs together by direct manipulation of user interface objects. Yes, Microsoft's programming tools, which take great effort to support this approach, have managed to convince very many people that the approach actually works; what is more, the many applications produced with them constitute proof. This is hardly surprising, since it rests on a great deal of solid research, performed by the Smalltalk team and those who came after them, including Microsoft. There is nothing factually wrong with the remark that Microsoft convinced many people to put software together this way; what is wrong is the implicit assumption that other object-oriented languages or tools are somehow to be preferred for that reason. It is like saying: I love E2, except that it's so easy to contribute to. Furthermore, there is nothing VB.NET specific about this criticism: Microsoft's tools support other languages such as C#, managed C++, J#, C++, VB6, JBuilder does it for Java, the Smalltalk system did it in the seventies, and any modern IDE for any language must do it if it wants to be successful.
As prole already guessed, most of them were taken from VB6. This is hardly surprising, since VB.NET is nothing but C# for VB6 programmers: its syntax is as close to VB6 as possible, and it comes with a whole array of predefined functions that correspond to VB6 equivalents; supporting the VB6 keywords was a design goal. The need to stay close to VB6 also produces silliness such as the "q"c character denotation syntax. Again, proles comments are right on the mark, but what is the complaint here? These features were designed for VB6 programmers; if you don't know or like VB6, VB.NET wasn't meant to be used by you - use C# or some other .NET language.
Wrapper classes
If prole needs to make a primitive type a little more flexible, she can write a wrapper class for it. If Harry wants to make the same primitive type a little more flexible, he can do that, too. He will. And I will. And any other programmer will. Wouldn't it be nice if the language automated this process so we could actually save some work and share the same wrapper classes, be convinced that they are correct out of the box, and so forth? That is what VB.NET does. Except that it is actually .NET which does it, so all languages that compile to .NET support this, including VB.NET and C#.
The same is true for structures, a compromise between value types and objects. I don't like them any more than prole does, but they are a .NET feature. Good barking, but VB.NET is the wrong tree.
Statement separation
VB.NET does have a statement separator: :. In fact, it has two: newline is the normal one. I wouldn't use anything else: putting multiple statements on the same line is poor coding style. Teach a writer how to use layout, and he might be read one day. If C or C# had had the nerve to apply such an advanced concept to their if statement, they would have saved us from a whole category of bugs. Of course, there is such a thing as job security.
Whitespace-dependent &
OK, so the compiler isn't sure how to read a& b, since a& is a valid expression, and has nothing to do with string concatenation. The ternary operator looks like a function: IIf. VB6 compatibility strikes again.
No ++
Wait a second - being able to mistype a++ + b as a + ++b is supposed to be a good thing? Sure, C's ++ operators made sense, because they were in the PDP 11 instruction set. I don't think VB.NET is used much on the PDP 11.
Sub versus Function
I don't know about you, but when I declare a function in C, C++, or Java I have to say whether it returns void or not. What does void mean, anyway? It means that the function is really ... you guessed it, a subroutine! Sure, understanding void makes me feel like a grown-up; I was taught programming in Algol 68, the language C took it from, and Algol 68 has a need for void, since it has a type system in which functions are regular type constructors. In C on the other hand, void is little more than an excuse to cast function arguments to void * that the programmer can't be bothered to type correctly. I prefer VB.NET, which supports properly typed function arguments in the form of delegates.
In programming languages, the evaluation of arguments of logical expressions can have side effects, and takes time, so evaluation order matters; in standard predicate logic, it doesn't, so logic isn't any help in deciding in which order evaluation should happen. Always evaluating left to right, like Java does, seems to be the best approach, but many programming languages, like VB6, require both arguments to be evaluated. VB.NET, thorough as it is, offers both: And and Or preserve VB6 semantics, while AndAlso and OrElse are for the rest of the world. Run FxCop to get the list of Ands and Ors to replace.
Indeed, VB6 programmers like their type conversion functions such as CInt, CDbl, so it is no surprise to see CType for performing a similar conversion. To just cast, use DirectCast.

In summary: every single point raised is a valid issue, but none of them represent specific VB.NET concepts or shortcomings; yes, some of these concepts turn out to work for the five-year olds they were designed for, and yes, that eats into your job security. Let's all go back to fixing buffer overflows in string operations.

Log in or register to write something here or to contact authors.