Template Languages and "Nearly VB"

The templates I’ve been talking about require very specific language features of the VB compiler and language neutral templates do not allow any ambiguity in the code output in the initial template.

The template itself must be in VB because it’s required for embedded XML – the code blocks. The code blocks are essential for understanding which code to translate when creating an alternate language template in a pre-processor. Code in strings would be impossible (or nearly so) to translate at the template level and translating at the output level would have many issues including debugging and performance. There are tools available that translate normal source code, and you could do that, but I’m not sure why. It’s a lot of extra variables, when translating the template offers faster performance and more reproducible results. Sticking with template translation – the code block clearly indicates to the template preprocessor where to switch into translation mode.

The language output by the initial template must be VB, or “nearly VB.” Even if your primary interest is C#, a language neutral solution requires that the initial template have no ambiguity. Sticking with familiar and well supported languages is helpful because the initial output can be tested in VB, isolating problems in the template from any in the template translator/precompiler. This requires a non-ambiguous language I’ll call “Nearly VB”. If you’re strictly interested in C#, and have no interest in language neutrality, you can, of course, use VB’s XML literal code blocks to directly output C# code.

Ambiguity breaks the ability to build language neutral templates because the preprocessor has very little idea of the current context. It cannot understand whether a particular close curly bracket is an End If, a Next, an End Get or something else. Unfortunately, Visual Basic is not totally ambiguity free either, which forces the concept of “Nearly VB” rather than just normal VB. Nearly VB has one syntax change and a couple of extra rules when compared to VB.

VB is ambiguous on parentheses. It uses parentheses to include both method parameters and indices. VB is also ambiguous when it comes to case. To solve this in templates, use square brackets to indicate indices and parentheses for normal method calls. The C# compiler will help you find the problems when your C# output files fail to compile. The VB output can easily replace the square brackets with parentheses when outputting VB files.

At the moment I’m not convinced that the other meaning of square brackets – allowing identifiers to match keywords – need to be supported very well. There aren’t that many keywords and simply avoiding them seems an easier solution. You can support them if you escape the character via the \x20 escape pattern and the ASCII character (/x28). OK, that’s not very pretty, so a shorter escape sequence may make sense if people run into this very often.

Case insensitive is really another way to say “case ambiguous”. Language neutral templates require that you correctly case all symbols, the preprocessor can manage the keywords it’s translating, but you’ve got to get the symbols correct. Consider a Symbols class with constants, which also provides Intellisense while you’re creating your templates.

VB is sloppy in not forcing you to include the open/close brackets after a call to a method that does not have parameters. In a broader perspective this is ambiguous because in C# the presence or absence of the parentheses indicate whether you want to call the method or grab the delegate. While that particular ambiguity is resolvable because VB would require the AddressOf operator (or a lambda expression), I’m not tracking symbols. So I don’t know whether your symbol is a method, variable, or property. Thus, I don’t know whether the parentheses is needed. For language neutral templates, you add the parentheses on all method calls.

NOTE: I actually explored whether this problem is solvable, and I believe it is not. I don’t think it’s that much to ask you to include the parentheses correctly – it’s just a place we VB coders have historically been lazy.

So, to allow language neutral templates:

  • Use basic VB syntax

  • Use square brackets instead of parentheses for indexes

  • Maintain consistent case for all symbols

  • Include open/close parentheses for all method calls

  • Avoid keywords as symbol names or escape the surrounding brackets with the XML escape sequence

  • Rather obviously, avoid features unique to VB

I’ll do another post in a few weeks on issues around spots the two languages inherently work differently. There will be more items on this list, particularly around the management of nulls in relation to operators.

I do not dream that I’ve covered everything. The only way to ensure language neutral templates is to create them, ensure the code is are syntax correct, compile and run in VB and then create the similar code in C# and make sure you valid syntax, clean compile, and can run the finished applications. After the upcoming preprocessor has been out for a while we will have a better idea how you can break it and chink the holes where you can. But issues that involve ambiguity will have to be solved by the template author.

5 thoughts on “Template Languages and "Nearly VB"”

  1. So this adds an extra step to the previously blogged about template preprocessor. You would always have to run the preprocessor, even if you were just generating VB code since the templates are no longer “legal” vb.net code.

    As I see your proposal we have the below five usage scenarios.

    1. You want to generate both C# and VB.Net out of the gate
    1.1. You create your templates in the “Nearly VB” template language
    1.2. The preprocessor has to run before your two templates are usable
    2. You are currently only going to generate vb.net code but you want to support generating c# from your templates , just in case the need arises
    2.1. You create your templates in the “Nearly VB” template language
    2.2. The preprocessor has to run before your template is usable
    3. You are currently only going to generate c# code but you want to support generating vb.net from your templates, just in case the need arises
    3.1. You create your templates in the “Nearly VB” template language
    3.2. The preprocessor has to run before your template is usable
    4. You could not care less about c# and only want your template creators to have to know valid vb.net code
    4.1. You create your templates to output legal VB.Net (which should be slightly easier for your vb.Net guys)
    4.2. The preprocessor does not ever run against your template
    5. You could not care less about vb.net and only want your template creators to have to know c#
    5.1. Not possible with this product since we require the XML literals but…
    5.2. You create their template output using legal c# and never have to worry about the “Nearly VB” syntax
    5.3. The preprocessor does not ever run against your template

    If the application has this flexibility I think it sounds great. If we are talking about limiting people I think we are going to scare off some who could otherwise greatly benefit from this tool.

  2. Almost,

    The infrastructure of the template itself outputs the VB code, so no translation is needed to output the VB code, thus 1.2 and 2.2 in your list do not occur. You just run the original template. This also makes 4.2 slightly misleading as there is no template preprocessor for VB.

    For 3.2, you do need the preprocessor – I think the preprocessor name is confusing here but I haven’t come up with better semantics yet.

    Scenario 5 is well supported beause of the three pronged nature of the conversion. Writing C# templates is as easy as wriitng VB templates, you have the full support of the infrastrucutre methods such as OutputFunction and some of the semi-colon management if you want it, because that’s the way it happens to work.

    You do, however, have to use VB for the XML literals. If you want to write only C# and do not want to use XML literals, you are probably better off sticking with the ASP.NET style template languages including CodeSmith, MyGeneration, CodeBreeze, and T4 from Microsoft (free).

    For complex templates you can still use XSLT, however why would you? You have to learn a secodn language (either VB or XSLT) and VB is way closer to C# than XSLT.

    Thanks for the summary Baxter!

  3. So why not use VB for the templates but C# for the initial output rather than some “Nearly VB” . Doesn’t C# address every issue you’ve raised ?

    But I am curious as to what about issues that are language specific, such as declerative event wiring, optional parameters etc ?

Leave a Reply

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