What’s up with this semicolon?


The most visual idiosyncrasy in X++ is the dangling semicolon separating the variable declarations from the actual code. But why is it there and why is it needed?


Best practices in X++ (as in most other modern languages) suggest using TitleCase when declaring (and referring to) types, and using camelCase when declaring variable types. Here is an example of what an X++ developer could write:


AccountNum accountNum;
;
accountNum = “4000”;

As X++ (unlike most other modern languages) is case insensitive, this is what the compiler will see:


accountnum accountnum;
;
accountnum = “4000”;

Suppose the dangling semicolon wasn’t there. Then the “accountnum” statement in the second line is ambigious. It could either refer to the type or to the variable. The X++ compiler assumes it is the type, and thus generates a compilation error when encountering the equal (=) sign; as you cannot assign into a type. By inserting the dangling semicolon you instruct the compiler that there will be no more variable declarations; and thus “accoutnum” is a reference to the variable and not the type.


If it was made a priority to get rid of dangling semicolons, what could be done?




  1. X++ could be made case sensitive. This would likely break all customizations and solutions available; unless it is accompanied with a code “beautifier”.


  2. The compiler could be made more intelligent by looking one more token ahead before giving up. As human beings easily can see through the ambiguity; the compiler should be able to do so too. I guess the developer solving this issue would kudos in AX-land.


The above is a draft of a blog post I wrote last week. I wrote it for two reasons: Mainly to explain the dangling semicolon issue, and secondarily to lay out bait for a developer on the X++ team. As it turned out more progress was made this weekend than the past eleven years in this corner of AX . After writing the draft above I decided to take a look under the covers in the compiler; to gauge the challenge, I guess. So I installed the latest version of VS and downloaded the latest source code for the kernel. (These are some of the freedoms you enjoy when working for Microsoft). After playing around with the grammar for a while, I came to the conclusion that the grammar is crisp and clear; the scanner is just feeding the wrong tokens to the parser. I found the spot where non-keyword tokens are evaluated. I discovered that if a token shares name with an X++ type (Class, Table, EDT, etc.) the parser assumes it is a type-token. After finding this spot it took me less than two hours to write some code that reads one token ahead and only assumes the current token is a type-token when it is followed by another non-keyword token. Sunday afternoon I had build 585 (the Release Candidate (RC0) of AX 2009) with a twist on my box: The dangling semicolon is no longer a requirement. I enjoyed the rest of the day in the sun with my family.


This morning I have created a package with my findings and sent it to the X++ team for evaluation. This change will not make it into AX 2009; but I’m confident those of us writing X++ code at Microsoft will enjoy this very soon. The rest of you will have to wait for AX6.0.

Comments (11)

  1. Petur Snaeland says:

    Big news! I for one never bought the explanations that this was necessary. Actually, since Axapta 2.1 I  never had that problem because I grew up in C/C++ and chose to use descriptive variable names like "AccountNum nextCustomerId;" in X++, which happens to avoid the issue altogether AND leaves more readable code. I hope your good colleagues will bring this out in the next AX4 and AX3 service packs too. Great initiative Michael.

  2. dewetha says:

    hopefully this makes the suppose best practice of placing a semi colon in methods above any code. including one without type declarations.

    i.e. best practice?:

    int addTwo( int _in)

    {

    ;

     return _in + 2;

    }

    now can be:

    int addTwo( int _in)

    {

     return _in + 2;

    }

    that will make teh confilct betwenn an accepted best practice and MBS layers the same.

  3. Strider says:

    I’ve allways hated the practice of naming variables after their type using camel casing. You may argue that C/C++ developers have been doing this for ages, but C is case sensitive. X++ is not!

    I strongly beleive that variable names should describe their content and semantics and not their type. It makes code much more readable for human beings!

    It’s a qood thing the semicolon is no longer necessary but apart from that you should really reconsider some of the X++ "best practices"!

  4. Martin Olsson says:

    Great work! I really really appreciate that you took the time to fix this.

  5. dewetha says:

    I like that fact that x++ is case insensitive. really, how big does a method/funtion need to be to have to start reusing names?

    I would like to see the old VB functionality that if I declare a variable and then in code,type it in lower case. it will then format it for me to what I declared. that is awesome for use guys that are lazy typists!

    i.e. declare:

    int FooBar;

    type: foobar = -1;

    compile makes it: FooBar = -1;

    since you are the GURU 😉

  6. mfp says:

    The best practice in X++ for naming of variables can be seen here:

    http://msdn.microsoft.com/en-us/library/aa892904.aspx

    As can be read here, variables should always be named logically, ie. the name should describe the contents in the variable.

    However, as EDTs are also named logically there often are clashes. Sometimes a variable is just an accountnum, and then you shouldn’t make up variable names like _accountNum, myAccountNum, etc.

    Regardless of how you name your variables the dangling semi-colon can still be an annoyance in methods without any variable declarations.

    void helloWorld()

    {

       ;

       info("Hello World");

    }

  7. Sebastian Draese says:

    the dangling semicolon is also needed,

    when the first command is an static-method call,

    void test()

    {

     ; // <— you’ll need this, because info() -> global::info()

     info("test");

    }

  8. Rakesh says:

    I come to AX from C# background and had always cursed X++ for the dangling semi-colon. Great to know that it won’t be required in near future.

  9. Carl S says:

    Sunday morning, so boring, what can I do…

    Ah! let’s have a look at AX and make some changes in the X++ grammar…

  10. Ax 2012 semi fix says:

    The problem is sort of fixed in AX 2012.

    You can leave out the semicolon in most cases. But when your first statement after declarations is a call to a .NET object the class won't compile to CIL.

    I saw this problem in Classes/AifGenericDocumentService.

    Could you give som strong hints to the compiler team to fix this as well.

    It is embarrasing to ship the product when it doesn't really compile.

  11. mfp says:

    It is correct that the dangling semicolon is still required in DAX2012 when the first line is a reference to a static .NET method.  I can see that my Russian friends over at axforum.info/…/showthread.php also discovered this and showed an example.  

    This issue has been fixed in the next version of AX.