This page describes things we hate about VisualBasic versions 3 through 6 -- IE: VbClassic. For VisualBasicDotNet vitriol, see ThingsWeHateAboutVisualBasicDotNet. What is it about VB that polarizes us? One camp revel in the stuff and can't figure out why anyone would program in anything else. The other camp find it physically sickening and inappropriate for modern engineering. It seems that here's a HolyWar to pale EmacsVsVi. Now the first camp have their own page on ThingsWeLoveAboutVbClassic. This page is for the other crew. Here, you can let off steam about the language that epitomizes everything evil at MicrosoftCorporation. Let it all out - you'll feel so much better. '''IDE''' * Possibly the world's worst IDE. Having to close and reopen your project just to unregister DLLs is ... there aren't words. - Except for all the other ones (with the exception of Delphi) that copied its ideas or the majority of "better" (but not for client-gui apps) languages whose IDE's and client side toolkits are non-existent vaporware or pale imitations. Have you ever actually used Eclipse, Borland Delphi/JBuilder/C++ (or Visual C++ circa 1997)? Have you ever tried to do Microsoft COM programming in Python or Ruby? Why can't these elegant languages produce an IDE worthy of their reputation? A: Because the available toolkits suck worse. -- MMcTernan * Not that this makes life much easier, but if you manually use regsvr32 to register/deregister your DLL, you don't have to close or reopen the project. -- JacobCohen * Further to above, you have to close and reopen your project if it '''uses''' (in References) a DLL that is being recompiled in another instance of VisualBasic. In other words, it holds a lock on all DLLs in its References list so they cannot be deleted, even in the common case of being deleted just prior to replacement. This is annoying, time-consuming, and disruptive of the MentalStateCalledFlow when (as is common nowadays) you are building a multi-tier application with VisualBasic. * The references dialog. What were they thinking?!? ''(What exactly do you find wrong here? could you be more specific?)'' * No I '''do not''' want to search for my project in Source Safe. * No I '''did not''' tell you to switch "End Sub" to "End Function" below the fold. * So it's better to have to retype lines of code you currently aren't on and perhaps can't see? -- MarkMcTernan * How do I open an arbitrary text file? Why do I have to ask? ''(Add it like you would a module, only this time choose the Add As Related Document option at the bottom of the dialog)' * Cannot even support copy and paste operations of code added to a command button or other object. Try this little trick: Add a button, add code to the click event. Copy and paste the button. Look MA: No Code. Now delete the old button, double click on the form Look MA: Your old code is still there. * I don't want to use your !@#$% text editor. I want to use mine. The VC++ IDE has no problem with that - why does VB? * It won't let you save changes that you make while debugging. When it crashes (see below), you lose all of your changes -- Thanks. * The system changes the capitalization of all your variables when you change their declaration. This is real cute ... when it's stable and does not insist on the wrong capitalization permanently. Then it can cause bugs, by afflicting the type libraries that link VB to case-sensitive languages. - try closing and opening the project to fix the problem. You will end up doing this inconvenient process when you occasionally make a mistake a lot less than you would have to use search and replace if it didn't reset the case for you. -- MarkMcTernan * Try this trivial, repeatable crash scenario: open a project in VisualBasicSix, open a code module, press Ctrl-F to open the Find dialog box, specify text to find, click to Find Next, close ALL code modules, press F3 to Repeat Find, watch VB completely crash. (--Amanita: doesn't crash in SP6) * Watching VB clear your clipboard when you load the IDE. -- Amanita * The tiny tiny textbox in the 'make' tab of the project properties... It basically can't even hold a normal copyright string ! (And the tiny tint textbox of the references dialog too....) -- Amanita (See VbClassicIdeIssues) '''Language''' * Two function call syntaxes that work in mutually exclusive contexts * For the "Run-time error '13': Type mismatch", would it have killed them to print out the type it thinks you have? instead of making you fish around for it? * If you forget to either assign a function value, or to use the word "call" in front of a procedure, you get no error or warning, but instead reference parameters just get passed by value. Is that inexplicable or what? * By-value parameters should be the default, not by-reference, as the former is safer. (They fixed this in .NET) * Okay, it has no inheritance, and won't even let you fake it. But does its polymorphism have to be ''so'' lousy? I mean, if you implement the foo interface, which say has a method bar, your implementation can only offer this as Myclass.foo_bar >:-P (''But what if I want to have function bar that belongs to implementing object not the interface. It's bless that they done it in that way -- Alex'') * No lazy evaluation of conditionals. And, Or and IIf always evaluate all expressions, whether they need to or not. So instead of clear logic, you have nested ifs. ''I used to complain about that, but now I think that having control of flow hidden inside a conditional expression sequence is a code obfuscation we can do whithout. Code should say what it does plainly and directly - in this case, probably with guard clauses.'' * The lack of real OO encourages SpaghettiCode on a massive scale. Lots of plumbing code, redundancies, nested ifs and so on. ** ''Example? I believe this to be an exaggeration.'' * Giving variables declared inside blocks nested scope would just confuse too many people, so let's encourage only procedure-level scope. Or higher. ** On the "importance" of block nested scope: A programmer that escews declaring variables at the top of the current scope and sprinkles ad hoc variables declarations throughout their code is evincing pretty strong evidence that the programmer hasn't sufficiently thought through the underlying datastructures of their code and is making it up as they go along. Variables are important: They should be properly declared on their own line and grouped together in a proxy_current_url that reflects their importance: The top of a module/file/class, or the top of the procedure, not whereever you first think to use it. -- MMcTernan * Its builtin types lack power and flexibility; ''Example?'' * The associative arrays are particularly poor. ''Example?'' ** The dictionary class exposed via the MS Scripting Runtime library serves the purpose. The same library also offers an excellent file io abstraction. -- MMcTernan * No string-based list API's. * Variant. Specifically, when you don't want one because you'd like typesafety you gotta type _more_, not less. ''Variants allow one to do scriptish-like coding if they want. I wish more corporate languages allowed this option instead of forcing strong typing down your throat.'' * Collection. Specifically, to probe for the existence of a key inside one you must catch an error. ** ''I think they fixed this in 6.'' *** it is not fixed in 6. ** ''I could have sworn I found a function/method to check the existence of a key. I don't have VB6 here to check though. Anybody else?'' *** '''NOT''' fixed in VB6. Most people make a function that catches the error and returns some kind of NULL value. But even that can be a pain when you want to run the debugger in "stop on all errors" mode, to catch errors. (...which may not be handeled well or properly by your code; a typical problem.) -- JeffGrigg *** ''Depends on how you define "fixed". If one wants to check keys, they should perhaps use the new dictionary object instead (see below). It has been "superseeded" by a more powerful collection type. I consider this "fixed" for practical purposes. Use the right collection type for your need.'' ** ''Syntax: object.Exists(key) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbenlr98/html/vamthexists.asp '' *** That's for the 'Scripting.Dictionary' object. We were talking about VB6's native "Collection" object - http://tinyurl.com/4g2cj - It has only the "Item" method; no Exists method. Item method: http://tinyurl.com/5ug2x **** An object from the VB runtime library is no more "native" than the MsgBox function. Why complain about one library's object when a more suitable one exists. Use the dictionary object instead. -MMcTernan *** {I could have sworn I've seen Exists or something similar in VB6, but don't have it anymore to check. You had to use a different class than you did in earlier VB though. They added a new collection type rather than added more methods to the existing one IIRC, and that may be why you didn't see it.} *** ''Being in the library does not by itself make it "bad". What don't you like about the library one other than needing a bit more syntax to use?'' * You can't query the key of a collection if you have an index, meaning you need to glom together two Collections to make a true map. ''Please clarify.'' * You can define variable-dimension arrays. Trick, right? Wrong. You can't test if the array has zero-dimensions. Anything you type is a syntax error. ''Use a dictionary array instead, see above.'' * The builtin aggregate data types are inconsistent between zero-based and one-based indexing. Arrgh!! -- RobertEikel * VbClassicDateConversions = there is no way to convert a string to a Date, in a way that does >NOT< depend on the current locale settings. (Actually, there is... see VbClassicDateConversions -- DaveBeer) * 16 Character Method Name Limit - Yes you can type in something like 256 characters for a method name, but VB only evaluates the first 16 (boundary determined largely by experimentation). Coupled with the way VB implements "Interface Inheritance", quickly leads to name collisions. When one uses "Implements" in VB, the inherited interface methods are renamed to base class name, underscore, method name. Result, method name collisions and being forced into composition rather than inheritance. ** ''Many languages do this including C, maybe you should considering writing variable/method/etc names that are shorter and more to the point'' *** ANSI C only guarantees evaluating external identifies to the first 6 chars, and LongNamesWhichGoOnForever.BecauseIDEsMakeItEasy are not good for readability. -- MMcTernan **** I think C99 (which allows more than 6 chars) has superseded ANSI C, and most C programs will have pretty long names_which_describe_some_specific_function especially in kernel code. Most compilers have no issues with long function/ident names. * Not being able to distinguish between integer and boolean arithmetic. And, Not and Or can be confusing sometimes. ** A lot of dynamic languages have this "problem". In dynamic languages you generally have to be a bit more careful about using Booleans. (This is not the place to discuss the general merits of typing dynamics.) * Being able to add spaces in Enum names : what were they thinking ? -- Amanita * The "Set" keyword. The compiler could EASILY know if a variable is an object reference and put the "Set" in for us. -- Andrew J. Marshall ** For better or worse, that's actually by design. In VB, assigning to or from an object reference without using Set means to get or assign the object's default value property. Thus, if I have 2 vairables referring to controls on a form, ctlFoo = ctlBar actually copies the value attribute (whatever the default attribute is) from the first control to the second control. Default properties can make for shorter more natural code and some miss this in the wordier Dot-Net. Perhaps the real problem is with the choice of the word "set". Perhaps "new" or "clone" would be a better choice. Also, it catches people off guard because it is not a feature readily found in other OOP languages. I chalk it off to a personal choice rather than an outright flaw. If you get used to it, it will not throw you anymore. * The nature of DIM and OPTION EXPLICIT was poorly designed. VB should have had the option of assignment-based auto-declaration to match that of other scripting languages. Instead, without OPTION EXPLICIT undefined variables inside expressions (right side) were treated as Nil, which was rarely desired. Thus, it was too all-or-nothing. MS should have added the assigment compromise available in other scripting languages. Call it OPTION ASSIGNMENT perhaps. ** They should have made the statement OPTION IMPLICIT, so that the default was forced declaration. A default of OPTION STRICT to force the specification of datatypes would be even better. **''Not sure I agree. I would vote OPTION ASSIGNMENT (above) be the default.'' (See VbClassicLanguageIssues) '''Stability''' * It crashes. It's an interpreter for crying out loud. It could actually ''catch'' and handle exceptions, it could dump you into edit mode or terminate the run. But it doesn't, it just poops out and goes away. ** VB precompiles before running since VB4? Even stepping through code in debug mode uses a second, precompiled instance to emulate what expressions would evaluate to. It wouldn't even step one line without compiling first. Also, there is no reason you shouldn't be able to trap an error if you actually implement error handling more sophisticated than 'On Error Resume Next'. -- MMcTernan * Stability is heavily dependent on picking just the right combination of service packs and hardware. * Stability is impacted by running it on the same box as other apps - even MS apps like SQL Server. * Stability is impacted by running it on a box with less than 128 meg of memory. Maybe 256 for larger apps. ** Try running Windows XP on 128megs or less. These stability complaints all seem to spring from the same source: A general lack of stability in Windows in general. -MMcTernan * Stability is impacted by the exact set of ActiveX Controls grafted onto your project. If you pick the wrong ones, or if any have even the smallest bug in their interfaces or in their license code, you die a thousand deaths. All in oblivious disregard to VB's stated market position as the killer app to support a cottage industry building these controls. ** This is partly a problem of success: all the choices of add-ons means you are at the mercy of far more players than Microsoft. Choice == Complexity. * If you reinstall the app, or reopen the project, it will reset a bunch of brainless features to their most unstable mode. Like "Don't Save All Files Each Time You Run". * Different versions of other MicroSoft products as well as VisualBasic itself, when installed on a machine, have been known to break each other (see MicrosoftIncompatibleDependencySuite). * Every service pack fixes as many bugs as it introduces. * 'binary compatibility' of ActiveX should be read independently : it's a binary file, and it's only compatible with itself. You'll probably still need to recompile all exes that depend on the new version of the activex. -- not if you give a new reference compatibility version after every NEW public method added. Pharao * You can edit source code in debu execution, add new variables on the fly, but why can't we just add a space in between variable name and it's type to align the code nicely in execution ? ** Because you are modifying a declaration which has already been loaded into the stack. Aligning variables with code? Hmmm, sound's like the unexamined datastructure practice condemned above. -MMcTernan * (See VbClassicStabilityIssues) '''VB Programmers''' * Managers count Vb experience as programming experience * VbProgrammers think that 5 years working in VB is 5 years valuable experience ** If one can learn to navigate a clunkly organically-grown language such as VB, then they can pehaps navigate any swamp. * VbProgrammers typically don't get: ** low coupling. Jam it all into one class. HMI, algorithms, etc. *** "Low coupling" is buzz-speak and has no consensus metric. ** UnitTest''''''ing ** What is actually going on under the hood *** How is this different than say Java, with its after-thought meta system? ** Anything '''Other''' * It fills the registry full of junk GUIDs that you have to muck out one by one with RegEdit. * Total-Rebuild of a whole project is either hours of Click-n-Grin, or you write a bunch of brute-force scripts that are just as much work. (See MakefileForVbClassicBuild for a possible solution.) * VB is easy to learn and hard to use. This means it's easy during the first 5% of a project's lifecycle with it. * VB is commonly used as the "proof-of-concept" language, but once shown to the GoldOwner, becomes the prototype, and initiates the ScheduleCompression, because ''you already have a working version'' ** "Working version"... HMMM. Numerous studies keep finding a 2/3rds failure rate for small to midsize projects despite several DECADES of Project Management/Software Engineering/ISO9000/CMM/Pattern quackery, and you want to blame the language which applies the 80/20 rule to produce a working version within weeks. Reminds me of a Java Developer who used to prototype everything in Python within a few days and then spend the next several weeks reimplementing a buggy version in Java. -- MMcTernan * Because it is so easy to learn, everyone who can write a form in VB calls themself a VB programmer. To actually be a useful team member on a large project, you need to be a programmers who understand VbClasses, InterfaceInheritance, VbEvents! I would bet that many large VB projects are underestimated because the programmers assigned do not have the necessary know-how. * Focus! The locked/enabled/visible properties have me dancing around, constantly wasting time telling VB where the focus should go. I'll just use a standard wizard. No, wait it's not quite right, I'll just change this one ... no, gotta set the focus ... why am I getting "Save not available ..." Arg! ---- '''List of Issues''' * Why can't VB have a treeview display in their IDE for project files (like in Java)? It's impossible to express logical groupings of classes in the IDE, which results in a view that is one-dimensional. * I HATE "DIM"! Why can't we specify scope here... Dim is so dim! * Why can't I pass custom types (structs) as parameters? (Well, I can create a clsArray, and dim a field(n,m) as new clsArray, and pass this field as parameter, I think this fine enough.) * Creating multiple threads is too hacky in VB... * No implementation inheritance * Basically, any 'advanced' feature you need (and you always do need one) must be forcefully hacked in with api, typelibs or else (including the multiple crashes and reboots that go with it). Anything new after 1999 must be implemented in some awkward way. Just thinking about 48x48 icons, multiple language resource files and resource loading, max/min form sizes, etc... -- Amanita ''AaronSevivas: (FingersCrossed): I think .NET has addressed this stuff'' ''You (SarcasticResponse): They have, it's called CsharpLanguage'' -- AaronSevivas (I'm not ALL flame... ThingsWeLoveAboutVbClassic) ---- Your views comments -plus/minus/interesting -- Original Basic - 'line numbers and gotos' - gives quick results in Excel/VBA ---- '''Checkboxes and Booleans''' "Thirteen Ways to Loathe VB", by Verity Stob (DrDobbs): http://www.ddj.com/documents/s=1503/ddj0001vs/jan00.htm This article gives the following code (where Check1 is a checkbox in a form): Dim b As Boolean, c As Boolean b = Check1.Value c = Not Check1.Value And claims that while b will contain True if the checkbox is checked and False if the checkbox is unchecked, c will ''always'' contain True. The key to understanding this is that CheckBox.Value returns an integer (0 is unchecked, 1 is checked, and 2 is grayed out), and when 'Not' is applied to an integer, it means 'two's complement' (~ in C; otherwise known as a bitwise not); thus, 'Not Check1.Value' evaluates to ~1 = -2, which when cast to a boolean is True (as it is nonzero). Change the code to: Dim b As Boolean, c As Boolean b = Check1.Value = vbChecked c = Not (Check1.Value = vbChecked) And you're fine. ''My response to this: Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah. !!! (Give me the insane idiot who thought that we would need bitwise Not for normal language use as opposed to bitmap manipulation. It's a broken design causing bugs, and what's worse, it's an obsure part of the design. Thus it can cause errors that you will drink much, much black, bitter coffee before you track them down and then proceed to swear for at least 5 hours)'' This is not necessarily a "design flaw". The checkbox has 3 variations, each of which are enumerated. If you try to map 3 enumerated choices into Boolean, you are asking for trouble. Any 3 choices mapped into 2 choices without thought is risky regardless of language. I don't see any easy way out of this unless you remove the greyed-out option. I agree that greying out is perhaps a GUI design smell, but the VB interface gives you that option rather than dictate what you can't use. I suppose one can reduce the chance of such errors by using strings such as "on", "off", "grey" instead of integers, but that invites its own problems. Or have methods like "setToGrey", etc. But this can make it difficult to share or store the info outside of the language, requiring not only case statements, but a more complex interface as well. Some may suggest that if zero was false and non-zero was true the problem wouldn't happen. However, 2 (grey) would then be rendered wrong, giving one meaning in conditionals and another in the GUI. In short, DontComplainWithoutAlternatives ---- '''Coordinate-based-GUI''' Creating resizeable windows - absolute positioned controls should be obsolete, but VB enforces their use. It is an exercise in tediousness to create nicely resizeable windows that are a piece of cake in Qt, GTK, or Swing. Resizable forms are easier in VB.net -- Brian Such issues are debated in CoordinateVersusNestedGui. There are ways to have stretchable coordinate-based windows (although VB does not natively suppose such). Also, in my opinion the best choice is "it depends". The best GUI system would have both choices. ---- It is pretty clear that VB has grown up "organically". BASIC was originally a teaching language on the first time-share (paper) terminals. Vendors just kept adding to it over time, which resulted in some odd syntax and conventions. For a while BASIC (and its variants) was probably the most widely known non-mainframe language, and even mainframes had it. ---- '''Block Syntax''' Moved from DatabaseNotMoreGlobalThanClasses OO and XML is something people give lip-service too in order to look hip. What they really want deep inside are web apps that are built and run like VB, for good or bad. As long as OO keeps acting like it is better, I will continue to pressure it to produce objective benefit evidence. That is science, for good or bad. -- top ''No good programmer I know wants anything near VB. VB is a horrible little language full of inconsistencies and is consistently overly verbose in everything it does. As an ex VB programmer, I have every right to say that, it was my first language and it crippled my mind for quite a while. If you want web apps built like VB, use VB.net, you'll love it.'' * Not to mention '''numerous''' other procedural languages (or OO languages that don't make procedural ridiculously difficult, if you want to avoid OO and put all state in the DB) that are miles better than VB. Perl, Python, Ruby. Some of them are naturally more convenient on platforms other than Windows. * ''If you use VB a lot, then you learn to live with or work around its idiosyncrisies. In a Microsoft shop you could not avoid it because it was there in one form or the other (VB, VBS, VBA), so one soon learned about the weird stuff and stopped being bothered but it. It mostly bothered me when it made something much more difficult to do, not so much goofy syntax. However, almost every language or tool has rough spots. It was not my first choice, but it was "good enough" for most tasks.'' I meant the concept of it more than its language idiosyncrasies. VB more verbose than Java? Now that is a curious claim. It used to be you could say 'textBox = "foo"'. However, it seems every generation of copycats tacked on more and more stuff so that now it looks more like 'application.formx.textBox.value.setValue("foo")'. ''I said VB is more verbose, i.e. the language, not the objects in it's api.'' C'ish- if(condition){} VB - If condition Then End If * While I perhaps agree with you about "then", end-X syntax makes it easier to match which kind of construct is being ended. Many programmers end up putting comments such as "// end of loop" anyhow. If every block ender looks exactly the same, you cannot tell them apart. ** If you can't visually tell which construct is being ended, you have nested too many and/or your method is too long. I used to really like the "end " syntax that Dylan provides. The more I used it though, the more I found it was superfluous and I'd be better off shortening the methods so I didn't need it. Ideally we'd all use indentation anyway, since that's what we really use to set off blocks. ;) ** ''Some developers complain when I make too many subroutines. Besides, move to LongFunctions if you want a function-size HolyWar fight.'' C'ish- while(condition){} VB - While condition Wend '''or''' Do While condition Then End Do C'ish- for(type thing : stuff){} VB - For Each thing as type in stuff End For Each * Some find an English-based approach easier to remember than punctuation. ** I like English-based over punctuation too. But I want consistent English-based syntax. I don't want to have to remember that For goes with Next and If goes with End If and While goes with Loop or Wend depending on dialect (WTF?). Gimme Python, not VB. * Related: TheRightWayToDoWordyBlocks. ** ''Python has the "white-space" and TabMunging issue. (See PythonWhiteSpaceDiscussion)'' C'ish- void Do''''''Work(type arg){} VB - Sub Do''''''Work(arg as type) End Sub C'ish- type Do''''''Work(type arg){} VB - Function Do''''''Work(arg as type) as type End Function * I like the type indicator coming after the variable instead of before, because the variable is more important than the type. ** Agreed. I think VB type annotations are actually better than C/C++/Java ** ''The colon in Pascal is perhaps a better alternative to "as" if we want the variable name to come first. But it is not easier to type because one has to press the shift key.'' ''It's like VB violates OnceAndOnlyOnce at the language level, constantly forcing you to say things twice, and a different way for every container, sorry, I'll take {} any day. Abstraction is good, VB is broken as a language, and promotes killing your fingers with tons of unnecessary typing.... interestingly, I could say the same for C'ish languages, lot's of unnecessary "typing", JavaScript seems to be the only C'ish language to get it right, no unnecessary "typing" or "classes".'' Sometimes it is easier to type "endif" then it is to press the shift key to get "}". The shift key is a time-consuming, risky finger movement, at least for my hands. Sometimes I accidently press the Alt or Ctrl while reaching for the shift, and wipe out a bunch of stuff. Plus, sometimes it is hard to match braces because they all look the same to the interpreter/compiler. A bad "endif" can be detected before it gets to an "endwhile" or "endsub", but a brace language keeps going potentially alllllll the way to the end of the file before parser complains. I've often seen code that looks like this: } // end loop Suggesting that the author fealt braces were not descriptive enough. (More likely the author wanted to highlight and remember a particular Loop of importance. Having "End" everywhere can become ubiquitous. It's like forcing someone to hold the door-handle up as they shut a car door so that they won't accidentally lock themselves out: allegedly a safety feature, it's just an tedious annoyance that becomes a habit you learn to ignore.} I don't see it as a big deal. Braces take up one line, and "end x" takes up one line. It is not really harder to type because one does not have to press Shift. I am sorry it bothers you, but I am not you. Let's just agree that it is a personal preference and AgreeToDisagree. ''See ShiftKeyProblem'' ---- "ThingsWeHateAboutVb" is an example of why I do not like WikiCase identifiers. They look ugly when mixed with capitalized abbreviations. ThingsWeHateAboutVB would look nicer, but might have ambiguous parsing. ''ThingsWeHateAboutVisualBasic would be even nicer. If you use WikiCase, you can't be lazy.'' ''Further, we hate VB because it inspires engineers who could otherwise indulge in productive debate to start raging and destructive flame wars against each other...'' ---- VB programmers are "engineers"? I think an engineer usually has studied engineering (i.e. electronics, mechanics, physics, maybe some computing too, etc.), I would called a VB programmer an applications programmer. See: KnowledgeAndSkill ---- See Also VisualBasic, VbClassicIdeIssues, VbClassicLanguageIssues, VbClassicStabilityIssues, VisualBasicSuitableForDevelopment, VbDotNet ---- CategoryVbClassic