Self-mutilation with .NET: Visual Basic on Linux

The worst way of using .NET on Windows is using C++/CLI. It connects the worst of both worlds: terrible archaisms of Win32 and somehow out-of-place bindings to .NET. But using C++ undoubtedly requires some actual skills and/or practice and quite often results in some actually acceptable code. This is not something we’re looking for here. So we need to find other candidates for the most annoying .NET activity. There are some strong candidates:

  • using F# (the language is sick, but it still requires some skills)
  • targeting an ancient version of the framework (like 1.1, which can’t be installed without warning above Windows 2003)
  • targeting an unreleased version of .NET 1.2/2.0 from Windows Longhorn (that’s more like it, but it might be a little too much)
  • using Visual Basic

The last option seems to be in a perfect balance between a really backwards and painful technology and a solution that actually makes sense. Visual Basic does work: it is functionally parallel with C# and still be can used as a code basis for all .NET applications, ranging from WPF to ASP.NET MVC (though strongly discouraged). It is often said that the bad opinion that VB.NET has is unjustified and outdated, because it originates in criticisms of Visual Basic 6.0 (“VB.COM”) and the disadvantages of VB6 are missing in VB.NET, but nobody cared to check it out. VB.NET, despite being marked as a direct successor of VB6 (versioned 7.0) is a drastically different language, fully object-oriented and much more powerful. Yet it doesn’t make it less strange: it’s not similar to anything else out there, it has its own ways of doing many things and requires a significant change in the way of thinking, especially from the people that previously used C#, Java or any other language with the slightest spark of sanity (Module1.bas, anybody?). Some people even look on VB.NET with disgust, and many others say that switching to VB.NET hurts their brain. Well, unless Visual Basic was your first programming language. Then, no matter what, you just love it. This is my case – I’m using Visual Basic since 2002.

That’s why we need to make it worse – since Visual Basic seems to work correctly, we need to pick some clinically retarded use case for it. Recent release of DotNet CoreCLR on github gave me an idea: let’s use Mono on Linux! Now, the .NET stack opened by Microsoft has not been integrated into Mono (yet), so even using the newest version of it gives us the in-house VB.NET compiler, instead of some fresh one. Moreover, the Mono stack is, despite some opinions, not the popular piece of Linux software, so it’s often neglected and kept in some ancient versions. This is the case in Fedora: it currently offers 2.10, which lags behind upstream very much – few years, to be fair. Xamarin releases half-official packages for Fedora with the latest 4.0.1 release, so I picked and installed it, only to discover that the VB.NET compiler in both 2.x and 4.0 is the same and nobody worked on it for the last 5+ years. This is gonna be great.

Visual Basic.Net Compiler version (Mono 4.0.1 – tarball)
Copyright (C) 2004-2010 Rolf Bjarne Kvinge. All rights reserved.

First, we need to create some “Hello World” to find out if Visual Basic support in Mono even works at all. It would seem that the logical way to do this is to use the Mono equivalent of Visual Studio: MonoDevelop. But this is not true. Bugzilla suggests that for the latest few years, the Visual Basic support in MonoDevelop is broken, even though it is shown in the Project type selector. It’s said to be related with the lack of support for targeting 4.5 for VB.NET. It’s actually much worse than that – manual fixing of the targeted framework does load the project, but it never produces any binaries. Not to mention that the apparent support for VB.NET ends on 2.0. That means no LINQ, no async and no parallel extensions. Since the IDE turned out to be useless, we need to go oldschool and use an ordinary text editor with syntax highlighting. I picked my favourite Geany. Initially, it didn’t colorize my code, because it doesn’t understand the “.vb” extension. Fortunately, it does support the VB syntax, so quick fiddling with the settings enabled the syntax coloring for the Visual Basic code. All set, so let’s write a simple program:

Module Hello
Sub Main()
End Sub
End Module

That’s it. Let’s compile it with the vbnc command. It compiles successfully and run with mono displays the aforementioned hello prompt.

Now, the single biggest mistake one can make now, is to assume that since Hello World compiled, the VB.NET is working. This is barely true. It’s a common mistake, present in many tutorials: this big jump from basic code into the more complex problems. So instead of believing that vbnc is not terrbile, let’s try and build something bigger. The most useless and needlessly complicated Visual Basic code I’ve ever created is the burnout flame temperature calculator I was forced to write at the university. I hate it so much, it’s the best candidate for that. It compiles without errors (naturally) or warnings on Visual Studio 2010 and up. I wonder how will the vbnc version 0.0.0 deal with the code? Not well, and that’s a really bad sign, the program is really simple:

Could not find the error message corresponding with the error code: 42021
/home/kamilek/Dokumenty/tp-is-2.4/Magic2.bas (3,20) : warning VBNC42021: 42021
/home/kamilek/Dokumenty/tp-is-2.4/Magic.bas (28,15) : warning VBNC42020: Variable declaration without an ‘As’ clause; Object type assumed.
/home/kamilek/Dokumenty/tp-is-2.4/ModuleCalcSolid.bas (12,17) : warning VBNC42020: Variable declaration without an ‘As’ clause; Object type assumed.
/home/kamilek/Dokumenty/tp-is-2.4/ModuleCalcSolid.bas (13,16) : warning VBNC42020: Variable declaration without an ‘As’ clause; Object type assumed.
/home/kamilek/Dokumenty/tp-is-2.4/ModuleHeat.bas (5,30) : warning VBNC42020: Variable declaration without an ‘As’ clause; Object type assumed.
/home/kamilek/Dokumenty/tp-is-2.4/ModuleRequiredAir.bas (15,15) : warning VBNC42020: Variable declaration without an ‘As’ clause; Object type assumed.
/home/kamilek/Dokumenty/tp-is-2.4/ClassAnswer.bas (24,23) : error VBNC30451: ‘vv’ is not declared. It may be inaccessible due to its protection level.
/home/kamilek/Dokumenty/tp-is-2.4/ClassAnswer.bas (28,23) : error VBNC30451: ‘vv’ is not declared. It may be inaccessible due to its protection level.
/home/kamilek/Dokumenty/tp-is-2.4/Magic2.bas (14,23) : error VBNC30451: ‘xs’ is not declared. It may be inaccessible due to its protection level.
/home/kamilek/Dokumenty/tp-is-2.4/Magic2.bas (18,23) : error VBNC30451: ‘xs’ is not declared. It may be inaccessible due to its protection level.
There were 4 errors and 6 warnings.
Compilation took 00:00:00.6190650

There are no error messages implemented! Is this some kind of a joke? All right, let’s start with the error messages. There are all the same error: accessing a non-existent variable. Moreover, they all turn out to be located in the same piece of code: a “For each” loop. Mono (or rather vbnc apparently doesn’t support the default types for the iterators in the For each sequence. It should. There is absolutely no problem with it using the official .NET Framework compiler. It’s an easy fix, just assign a type to the iterator. You can do it correctly: The String type for Keys and the Double type for Values, as it’s a Dictionary of String, Double. But you can also do it the retarded way, by declaring the iterator as Object. It actually works! This is because the real Mono stack is implemented correctly and indeed does not care about the type of an iterator in For each. It’s the problem solely with that dreaded vbnc. So, let’s fix everything the retarded way. Now the warnings.

The warnings in fact make more sense than the errors. They basically boil down to the same thing: default typing. There is no type set for two Doubles (the division of two other Doubles), so the compiler assumes the type on its own. And it does that terribly by taking the type of “Object”. Somehow the program works, it’s magically enough to assign any type for it to work, as long as it’s big enough to contain Double. Object does that quite right. We’ve made the program work and it’s not Hello World. But, let’s not fall for the same trap: flame heat calculators are not where .NET is used, they’re meaningless. Let’s try some business stuff. Like threads! Here: “How to: Write a Simple Parallel.For Loop” by Microsoft.Now let the fail begin.

Compilation ends with 62 errors and this is the code straight from MSDN. More precisely, this is what happens: That does not mean anything good. It, in fact, means that nothing works. It goes only worse after that. There is no way to run anything remotely complex or modern (above 2.0) in current Mono. The project doesn’t even say much about the future: Visual Basic support in Mono but there is a work item about taking from the open .NET imlementation from Microsoft on GitHub. Months passed and there is no sight of any progress. I know that nobody actually uses Visual Basic, but there still are some crazy people that actually do. Also, no matter what happens, VB.NET will always be my lanuage of first choice, becuase it was my first language and I just like it.

Anyway, the Visual Basic via Mono on Linux easily wins the contest for the worst way of using .NET ever.


Next time: web services with COBOL!

Leave a Reply

Your email address will not be published. Required fields are marked *