Terminology – Are VB.NET to C# Converters Actually Compilers?

compilerdefinitionterminology

Whenever I see programs or scripts that convert between high-level programming languages they are always labelled as converters.

"VB.NET to C# converter" on Google results in expected, useful hits.

However "VB.NET to C# compiler" on Google results in things like comparisons between the C# and VB.NET compilers and other hits that are not quite what you'd be looking for.

Webopedia defines Compiler as

A program that translates source code into object code

Eric Lipper in an answer to: "How do I create my own programming language and a compiler for it" suggests:

One of the best ways to get started writing a compiler is by writing a high-level-language-to-high-level-language compiler.

Is a VB.NET to C# converter really just a compiler? If not, What separates the converter from also being a compiler?

Best Answer

Depending on how you look at it, maybe the difference between a "converter" and a "compiler" kind of comes down to the objectives involved in one versus the other.

Do a "converter" and a "compiler" both perform lexical analysis and convert one flavor of code into another? Sure they do. But with totally different objectives.

You're going to use a "converter" to transform source code from one portable high-level language syntax to another portable high-level language syntax, so that you can maintain your source code in a different language, right?

The goal is that you end up with your source code base in C# instead of VB.NET. Maybe you just don't like VB.NET syntax, maybe all of your other source code is in C# and you want a uniform code base, maybe you have some VB.NET code which is perfectly fine except that you want to have your product run on mono. Maybe all sorts of things. Actually, it looks like there is a VB compiler in the works for Mono. Why, I really can't imagine. VB was great back in the day. R.I.P., VB.

So the work result of a converter, in the context we seem to be talking about, is maintainable, portable high-level source code that you'll put into your source code repository and make your team embrace, extend and maintain.

On the other hand, the work result of a compiler is executable, probably optimized and almost certainly non-maintainable and non-portable code that targets a specific CPU. The work result of a compiler is executable code.

Granted, I'm conflating the concepts of compilers and linkers here. But so did at least one of the commenters who referred to the C#/VB.NET compilers producing IL, which then needs to be "compiled" into executable code. :-)

.NET has a sort of fancy extra layer, where the "compiler" transforms your C# or VB (or F# or Eiffel or JScript or managed C++ or...) code into an IL assembly (an .exe or .dll file), and then when you "run" that code, the .NET JIT (Just-In-Time compiler) intervenes, magically and transparently converting your IL into native non-portable code for whatever CPU it finds itself running on. Or you can use ngen to convert your IL assembly into a native image for a particular CPU ahead of time (though the benefits may not be as dramatic as you hope).

So, via whatever circuitous route, the work product that is ultimately squirted out by a VB.NET to C# converter will be to take a source code file containing something like:

Dim i As Integer
For i = 1 To 100
   ' do something
Next

And convert it to something like this:

for( int i = 1; i <= 100; i++ )
    {
    // do something
    }

You'll store that resulting C# source code in your source code repository and use a compiler to turn that into executable code for distribution to your customer. And you get to program in C# instead of VB.

Note, by the way, some of the subtle difference in instinctive thinking that accompanies VB programming versus C# (C/C++) programming, where that loop iteration started at 1 instead of zero.

IL is really just a sort of CPU-agnostic assembly language. Unless you have some esoteric low-level, system-programmer reason to be maintaining code in IL, you just aren't ever going to be storing the stuff in your source code repository. Other times you might fiddle with IL are when you're actually a language programmer on the Microsoft .NET team or the Mono team or some other language team that makes a .NET compiler for a specific language (FORTRAN or COBOL, anyone?), or you are deep into debugging some weird edge case and use a disassembler on your own code, or you're trying to resolve a technical argument with another developer on your team who you know is crazily wrong about something (never happens, right?), or you're inspecting somebody else's IL assembly to try to figure out how it works or whether it is safe to call it in a certain way.

That isn't so different from the uses of traditional CPU-specific assembly language (or assembler for discrete systems like the old mainframes and mini's before there really were all-in-one silicon CPU's). "High level" languages like LISP, COBOL, FORTRAN and C (which was originally billed as a sort of portable assembly language) were developed to make code easier for mere humans to grasp, and to make it possible to compile the same code to run on more than one type of computer. So a C compiler takes "high-level" C source code and turns it into assembly language for whatever CPU you're compiling for, and then you use a linker (which is usually automatically invoked by your compiler) to further transform that into actual binary code that you can shove straight through the CPU. But the compiler results aren't the thing that you keep around as "source" code, right?

Well, I do remember a case years ago where a team of developers had a set of "magic *.obj files" that they had to link against because the original source code had been lost somehow. But I digress...

It is entirely reasonable to assume that some .NET converters might actually work by "compiling" code into IL, then "decompiling" the resulting IL back into another language. At least a few of the IL disassemblers floating around do essentially that (including .NET Reflector and ILSpy). But the objective is still different from what a "compiler" does, right?

So I contend that a converter is not really just a compiler by another name.