So I'm feeling much happier, thanks to those that asked: I got over my emo quite fast, and am doing my best to become the programmer I want to be.
I can't really blame my tools here: none of the things I'm about to grumble about are related to my badness at programming, they're just annoyances that I felt the need to vent about. Mostly with Microsoft software and languages, but that's to be expected since I have suddenly started working with them all, so they're all new to me. Not so much a reflection on the company as on the fact that my work is focused on their products at the moment.
Remember back in the 80s when you were first playing with computers and there was a language called Basic? Well, that language, believe it or not, is still alive and... I guess I can't say "alive and well", but its rotting corpse is still stinking up anything that Microsoft touches, so people still have to code in it. Me too, now. Apparently VB.NET is "better", but I've not used it yet so can't comment.
I have instead been working with three versions: VB6, VBA (which is like VB6, but is embedded in Office applications), and VBScript (which is like the bastard child of both).
Basically, this language seems to be a wrapper around the windows scripting host, made as much in the style of VB as they could. Or at least, as much as they could be bothered to. Which means it has all the flaws of VB6 above and more...
Not a lot to say here, other than I hate the tab management there and there's no way to change it.
The epitome of MS Suckage.
There are in fact a few IDEs that I'm using. For VBA, I tend to have to use MS Office's internal editor. For VB6 I have to use "Visual Basic 6" which I'm guessing is some earlier version of Visual Studio by another name, and for VBScript, I use a different Visual Studio, with a macro to hook into the script and debug it, since that's not a built-in ability.
But I'll lump them all together as one.
Probably the most-scorned webserver out there. Why? Well...
To be fair to this, it... no, sorry, it stinks like a bad day at a fishmarket.
VB Programmers themselves seem prone to some habits that bug me.
I can't really blame my tools here: none of the things I'm about to grumble about are related to my badness at programming, they're just annoyances that I felt the need to vent about. Mostly with Microsoft software and languages, but that's to be expected since I have suddenly started working with them all, so they're all new to me. Not so much a reflection on the company as on the fact that my work is focused on their products at the moment.
Visual Basic
Remember back in the 80s when you were first playing with computers and there was a language called Basic? Well, that language, believe it or not, is still alive and... I guess I can't say "alive and well", but its rotting corpse is still stinking up anything that Microsoft touches, so people still have to code in it. Me too, now. Apparently VB.NET is "better", but I've not used it yet so can't comment.
I have instead been working with three versions: VB6, VBA (which is like VB6, but is embedded in Office applications), and VBScript (which is like the bastard child of both).
- Functions vs Subs is a great area for niggles. For those who remember "GoSub"... this is nothing like that. Instead, if a function doesn't return a value, then it's a "sub" not a "function". This varies a little between versions, and is apparently scrapped completely in VB.NET, but the annoyance comes because they both have different calling conventions. You put brackets around the parameters for a function, not for a sub, but this only matters if there's more than one parameter since brackets are also grouping constructs. Legal: mysub (param); Legal: myfn(param); Legal: myfn(param, param2); Legal: mysub param, param2; Illegal: mysub(param, param2); Illegal: myfn param. It's more consistent than it looks at first glance, but still stupid.
- Functions can only be used where an rvalue is expected: that is, where a value is being assigned. So you can't call a function and just not assign it to anything: you must DIM a variable, then assign that variable to the function.
- They also have different creation conventions: functions are "Function name(params) some codeExit Functionsome code End Function", subs are "Sub name(params) some codeExit Subsome code End Sub"... which means that if you decide to return a value from a sub, you have to change the start, end, and any exits from that sub, rather than just adding a return line.
- Which leads us to the crazy mechanism for returning from fns. Instead of a "return" command like all reasonable languages, it requires that you assign (with or without "Set", depending on the return type of your function, see below) to a "Magic" variable that you never created with the same name as your function. So if you change the name of your function, or you copy one function to make another, you need to change the code in two places. Obviously, when creating a bunch of similar functions, this is really prone to cut-n-paste bugs.
- VB has the "Set" command. Assign an object to a variable, you use "Set". Assign a non-object to a variable, you don't. This seems arbitrary, and gets worse: arrays, dates and strings are not objects, for example: collections and recordsets are. If you have a variable which could store either an object or a native type (called a "Variant" in Microsoft-speak), then which do you use? Who can tell? And if the variable has been strongly typed, why is it even needed? Allegedly this silliness is gone in VB.NET.
- You've got "End For", "End Sub", "End Function", "End While"... so how do you end a "Do" block? I know what you're thinking: "Done". And you'd be wrong, it's "Loop"!
- You've got "Exit For", "Exit Sub", "Exit Function"... so how do you think you exit a while loop? That's right! You don't! No command for that. But there is "Exit Do", so you can do "DO WHILE test:codeEXIT DOcode LOOP " (yeah, "Exit Do" not "Exit Loop").
- There's no system for block quoting, which makes SQL queries uglier than you would ever think possible. The best you can do is use '" & _' at the end of a line, then '" ' at the start of the next line, to continue a string.
- Both '&' and '+' work to concatenate strings, but '&' should be used as "var + var" may add them numerically, or concatenate, depending on type.
- There's no &=. A minor niggle, perhaps, until it comes to building strings, when it just gets ugly. In fact, the general construct, +=, *=, etc, is unknown in the language.
- It's space-sensitive in places that you wouldn't expect it to be. '"str" & var' is fine. '"str"&var' is unfine. Because '&var' is a dereference, I suspect. But a real language (take perl for instance) would take context into account. A dereference makes no sense where a string concatenation does, and vice versa, so whitespace should not matter.
VBScript
Basically, this language seems to be a wrapper around the windows scripting host, made as much in the style of VB as they could. Or at least, as much as they could be bothered to. Which means it has all the flaws of VB6 above and more...
- There's no struct. This alone is clearly enough to move VBScript from "real language" to "toy". You can't, for example, return more than one piece of information from a function in a nice structure, and instead have to use ugly kludges like modifying the function parameters in the function.
- There's no ternary operator. VB uses the "iif()" function, and it's easy enough o build your own in VBScript... but why isn't it a builtin?
- Awful error messages. This, I think, comes from it being a halfassed wrapper around the scripting service. So it gives errors at that level, rather than at the code level. "Type Mismatch" is VBScriptese for "Function not found", for example.
- VBScript has no optional parameters to functions. In VB you can say "Function myfunction(optional param1)"... not in VBScript. This is made more confusing by the fact that the scripting host definitely permits it for JScript and Javascript, so it's not like it was impossible for them or anything. They just didn't do it.
- VBScript has no strict typing. In VB you can say "Function myfunction(param1 as String)" or "Dim myvar as String"... not in VBScript.
- Because of this, the strongly typed versions of functions seem to be missing: Chr() exists, Chr$() does not.
Internet Explorer
Not a lot to say here, other than I hate the tab management there and there's no way to change it.
- Start a search, go to a new address, and it opens in the current tab rather than a new one. Which is silly: if I type a URL or a search it's to find more about what I'm currently writing about in the current tab. I don't want to browse away from that form!
- And although it can remember tab sessions, it wont let you close the last tab... so you have to open a new tab and then close that one, if you don't want the site you're on to reopen the next time you open the browser.
Vista
The epitome of MS Suckage.
- Explorer opens when I click links in Furcadia and other apps. Even setting IE to be the default, then Firefox to the default again, doesn't fix this.
- In XP and below that's easy to fix. Explorer -> Tools -> Folder Options -> File Types -> N/A: Internet Shortcut -> Advanced -> Open -> Edit. Piece of cake. In Vista, that tab is missing and has been replaced with Start->Control Panel->Default Programs, which is a collection of the ugly vista-style webpages that have replaced proper dialogs. They have removed anything that used to be under the "Advanced" button, so basically file associations are crippled, can't be created, edited, or renamed, unless you edit the registry or use a third party app.
- Filetypes can still be reassigned, though. Except when I tried that, reassigning the .URL filetype to Firefox, the application hung and wouldn't let me.
- I made a commitment to keep UAC turned on and try to put up with it, because I was entirely sold on the theory, at least. If implemented at least semi-reasonably, it is as good and sensible as having to type your root password in Linux for sensitive tasks. But, THREE confirmation dialogs just to delete one shortcut from my start menu? This was the point at which I turned UAC off. That is unacceptably broken. No Linux programmer would do that, I would not be permitted to write code so broken, and I will not accept it on my machine.
- The reboot when turning UAC off took hours. Literally. I played a game on my other machine while I waited. Eventually I caved in and just hit the power switch.
- With UAC off, I no longer have access to write to folders on my own machine! I can't make a folder in "C:\Program files"!
- Windows security centre will always display as red in your taskbar if you turn off UAC.
Visual Studio
There are in fact a few IDEs that I'm using. For VBA, I tend to have to use MS Office's internal editor. For VB6 I have to use "Visual Basic 6" which I'm guessing is some earlier version of Visual Studio by another name, and for VBScript, I use a different Visual Studio, with a macro to hook into the script and debug it, since that's not a built-in ability.
But I'll lump them all together as one.
- F3 while searching. This is just stupid and infuriating. If the selection is on the search box and I hit F3, then nothing happens. If it's on the text, then I search for the next occurrence.
- No line numbers by the text. And this is meant to be an IDE for programming.
- Most measurements are in TWIPs, except those that aren't. That is, multiples of 1/1440th of an inch. Not pixels, not anything intelligent that would transfer to mobile computing, projected screens, etc. But makey-uppy measurements based on an assumption of how many pixels per inch the average screen is (updated in each windows version), an arbitrary constant (1/1440), an an imperial measurement. Awesome! And you can't change to any other system of measurement, no. In small fonts mode, 15 twips = 1 pixel. But of course, you can't rely on that or anything.
- When I said "except those that aren't", I of course meant that there are other measurements that are in a different scale that cannot be converted to TWIPs. Like borders seem to be in pixels, font sizes are in points (tip: 1 point = 20 TWIPS).
- In all versions of this editor, the file explorer isn't a real explorer, so to unlock a file in CVS you also have to have a real explorer window open.
- If you open a file from that real explorer window, though, it won't open it as a file in the current project, but instead as a file in a new copy of Visual Studio that it opens up for the purpose. There's no rightclick option to open it in the current project, even.
- If you open a file that's readonly, either because you are debugging it, or because it is locked in the CVS, then some IDEs will allow you to edit and just silently not let you know they couldn't save; others will not allow you to edit at all; others will allow you to edit, then let you know that you can't when you try to save, then undo all your changes without prompting... some will change their behaviour between these extremes depending whether you are debugging at the time. Some will open a file a second time, in another tab, for debugging, then when you quit debugging, save or close the wrong one. It's all very Russian roulette and unintuitive, and the only safe way seems to be to make sure you never try to accidentally edit a locked file, and always save before changing into or out of debugging mode.
- Some let you copy forms. Some don't. Want a form that works just like that other form? Create a new form, copy the code, copy the components, then in the GUI form designer tool, go through all the settings of the two forms and manually copy each one. Because, a "copy form" button would have been evil, or something.
- Microsoft software seems to hate to remember paths. So you're working in a database or project, and want to add a new file, save a file you just added, or import or export a table from the database. Should it default to showing you: 1) a random directory it just decided to make in your documents folder, 2) a random directory it just decided to make under its own application path, or 3) the folder that it knows you are working in? Answers on a post card. For extra points, try to guess which of the three it will pick the second time you do it, when you've effectively set your preferences.
IIS
Probably the most-scorned webserver out there. Why? Well...
- IIS is single threaded, and runs the scripting host in that thread. So, an infinite loop means the server falls over. Compare that to PHP+Apache where it just means that after a few seconds, the thread serving that page times it out and closes it, and you can see why VBScript+IIS is not recommended for serious web applications. Allegedly this is fixed in .NET or something. In my opinion, any job involving work on a system which contains VB, IIS, or Access as components, should include pricing to move it to a real database and a DB-friendly language, at least anywhere that security is an issue.
MS Access
To be fair to this, it... no, sorry, it stinks like a bad day at a fishmarket.
- You can't quote integer fields. Which means you need to know which fields are integer and which are string, when escaping your data, or be vulnerable to injection attacks. In MySQL you can just replace all quotes with escaped quotes, then slap values in quotes, and you're safe from naive attacks.
- Access is inconsistent with its wildcards. When typing the query into Access, it expects '*' as a wildcard. When getting the query from VB it expects the ANSI standard '%'. This causes problems when debugging, trying to copy a query from the debugger to run it in access...
- Access is inconsistent with its date fields. Though I've not run into this much it seems that sometimes it allows '#dd/mm/yyyy#", sometimes it allows "'dd/mm/yyyy'", sometimes both, with no immediately apparent reason, though I suspect that sometimes it wants ANSI compatibility, and sometimes VB-compatibility. Personally, I try to pass VB Date fields in instead, which avoids the problem.
- Booleans are known as "yes/no fields" and accept "yes" and "no" as well as "true" and "false". Some foolish programmers actually use this "feature", which will naturally cause problems when porting their code to a real database.
- Access too is guilty of bad error messages, and this time doesn't have the excuse that it's got a scripting engine behind it. "No value given for one or more required parameters" means "field not found" for example, not that one of your comparisons or assignments is null or something.
- This one bit me recently. "null + 5" is null in Access, 5 in MySQL. So in MySQL, it's safe to do: "UPDATE TABLE SET counterField = counterField + 1 WHERE idfield = blah". In Access, it's also "safe", in that it doesn't throw an error. But in Access, your counter will never increment if the field's default value is null! The correct solution is to set all null values to 0, but that's not always possible. The alternative is to SELECT counterField WHERE idfield = blah, then put that in a vb variable, set it to 0 if it's null, then "UPDATE TABLE SET counterField = " & kludgeyVariable & " WHERE idfield = blah"
- VBA is tied into access, as is the form and query design. Tied so tightly that they are all one glob, and you can't just pull one part out (the data in the database) and migrate it to a proper program: you'd need to redo everything from scratch, forms, code, and database, at the same time. This is an ugly form of lock-in, and one in which many companies are stuck.
- The SQL interface is the worst bit though. Want to type a SQL query? OK, open the DB in Access, which will then lock the database so that your code can't use it. Go to the list of stored queries, and click to create a new one. Click OK to use the query builder, cancel the list of tables to include in the GUI, click the dropdown on the view button, select SQL view, and delete the default query "SELECT;" in that view. Now you can enter your query. If the result will be a table, select table view in view dropdown, to run the query and see the results. Otherwise, click the red exclamation mark button to run the query. Remember to close the database before returning to your debugger or it will still be locked, even if you have opened it readonly (as a workaround, you can copy the database, and run queries on that while you are debugging the real one). Compare this to MySQL where you just type "mysql" at the commandline, then run your query, and can have those results open on your screen without locking the database.
- But it gets worse. If the database is a readonly file (CVS checked out, wrong version for your database, etc) then you cannot create stored queries, because that would mean changing the file... so you can't run SQL queries through Access AT ALL!
The Programmers
VB Programmers themselves seem prone to some habits that bug me.
- Lvalues on the left in comparisons. This is generally understood to be evil. 'IF "" = var THEN...' is safe in any language. 'IF var = "" THEN...' is OK in VB and a subtle bug in most other languages; it will always branch the same way, regardless of the value of 'var'; and it will set 'var' to the empty string. There is no excuse to use this unpleasant form of the construct in vb though, since it forms bad habits, and often makes the meaning of the code less clear. In some cases ("IF var = 1 THEN var = 2 ENDIF") it is arguably clearer. Not in any non-trivial cases though:
("IF varA = 12 AND varB = 59 THEN varC = 3 ENDIF")
("IF 12 = varA AND 59 = varB THEN varC = 3 ENDIF")
In the latter, assignments and compares are clearly distinguished, and the things that are being compared TO are clearer: 12 and 59 are the important things here, not varA and varB. Generally it's best to have the thing you're testing FOR to be as far left s possible so the eye doesn't need to search for it. - Sticking everything into the database. The idea here is that you get away from hardcoding stuff because that is allegedly unutterably evil. But if the business requirement is for, say, one report to be done in one way, and all others to be done in another, you have some tradeoffs to make. You have several options. 1) In a single place in the code, hardcode that report ID to be different, and format and comment it well to be obvious. To me this is the simplest, clearest, most maintainable option, which can easily be scaled to other options if necessary. 2) Make the code the same for all reports by sticking the query for each report into the database as a string. But the query string is now unformatted, uncommented, and duplicated for all others, so when a new requirement is added to the normal ones, you have to edit every single instance of it in the database. If the requirements change in a way that can't be dealt with just by changing the query, you still need to change the code anyway. 3) Stick the option to make that variation as a checkbox on the report generating form. The code no longer has hardcoded IDs, but the report creation tool rapidly becomes cluttered with controls that are only ever set to "yes" for a single report, which eventually become obsolete fossils but still need to be maintained as it is too much work to remove boolean fields from the database, checkboxes from the forms, and all code that refers to either; simply not maintainable.
- Calling database result sets "tables". They're not. Access sort of blurs the line, with stored queries being able to be referred to as tables, and with a simple table name being able to be used as a query without a preceding "SELECT * FROM ". The recordset object even allows you to use it as an LValue, then call it's update() method, and it'll modify the table! But they're very different. This causes confusion in code which is referring to reading in a recordset and writing out to a html table, for example. Just call a recordset a recordset.

Only that argument falls flat when it's Windows *itself* which is bugging you all the bloody time.
Vista is pants. Complete and utter pants. I've tinkered with it on a couple of machines and can find no reason at all, whatsoever to choose it over XP. OK, so there's a proper 64-bit version but that's hardly an issue with hardware right now.
For work (and for personal tinkering) I've been playing with Ubuntu for the last few months, just remembering some UNIX stuff from uni and getting a feel for it again. Games aside, I'd be more than happy to use Ubuntu as my main OS on a desktop/laptop. There are a couple of apps I'd miss, but nothing I can't replace with similarly-specced open source alternatives.
Vista has killed Microsoft for me. Simple as that.