Showing posts with label keywords in ax7. Show all posts
Showing posts with label keywords in ax7. Show all posts

Thursday, 11 February 2016

X++ in AX7: The var keyword

This is the new language feature that is generating most discussions. Just like C# you can now use the var keyword when declaring variables. It has the exact same semantics, and any guideline you will find on how to use it in C# will also apply in X++.
 
In C# the var keyword was introduced to enable scenarios where declaring the type was impossible, near-impossible or irrelevant, like with anonymous types and generics. Writing less was naturally well received by a lot of developers, and the use of var blossomed. It is also a great topic for steering up a debate. There are lots of guidelines and opinions. They cover the entire range from one extreme: "Always use it, it makes code easier to read" to the opposite extreme: "Never use it, it makes code harder to read".
 
X++ does not support anonymous types or generics in AX7 - so the real need for the var keyword is not present - yet it is supported, and already heavily used. Like in C# the use of var is as strongly typed as when the type is explicitly provided.
 
Personally, I'm recommending using var in only two cases:
When the type is obvious.
In X++ there is a lot of repetition. The var keyword can help avoid some of this clutter while making the code easier to read, without any information gets lost to the reader.
For example:

MyClass myClass = new MyClass();  
In AX7 I would write:
var myClass = new MyClass();  


When the type is irrelevant.

Sometimes you don't care about the type. If you don't care the reader most likely doesn't either. 
For example:


ListEnumerator enumerator = myCollection.getEnumerator();
In AX7 I would write:
var enumerator = myCollection.getEnumerator();   



 There are a number of X++ specific reasons to not use var (i.e. doesn't apply to C#)

Limited support Visual Studio.

In the X++ editor in Visual Studio, you can use F12 to go to the declaration of a type. However, the X++ editor is still not as smart as the X++ compiler. At the time of this writing you are losing this drill through capability when not explicitly specifying the type of the variable. The same applies for IntelliSense – when using the var keyword, IntelliSense is not available (yet).
Higher risk of runtime errors.

Just like the C# compiler, the X++ compiler will determine the type from the assignment to the variable and enforce all the same rules and restrictions.

 So you might think that the use of var doesn't lead to more runtime errors. There is a catch in X++ - you should be aware of. The X++ compiler doesn't enforce any validation of method invocations on object or common. So if the X++ compiler determines the type to be object or common, then you lost your safety net. It is not always obvious.




Consider this code:

CustTable custTable = Xml2Record(xml);

custTable.someInvalidMethod(); // Compile error  

Using var, the code becomes:

var custTable = Xml2Record(xml);  

custTable.someInvalidMethod(); // No compile error, as Xml2Record() returns a common  

X++ in AX7: The var keyword

This is the new language feature that is generating most discussions. Just like C# you can now use the var keyword when declaring variables. It has the exact same semantics, and any guideline you will find on how to use it in C# will also apply in X++.
 
In C# the var keyword was introduced to enable scenarios where declaring the type was impossible, near-impossible or irrelevant, like with anonymous types and generics. Writing less was naturally well received by a lot of developers, and the use of var blossomed. It is also a great topic for steering up a debate. There are lots of guidelines and opinions. They cover the entire range from one extreme: "Always use it, it makes code easier to read" to the opposite extreme: "Never use it, it makes code harder to read".
 
X++ does not support anonymous types or generics in AX7 - so the real need for the var keyword is not present - yet it is supported, and already heavily used. Like in C# the use of var is as strongly typed as when the type is explicitly provided.
 
Personally, I'm recommending using var in only two cases:
When the type is obvious.
In X++ there is a lot of repetition. The var keyword can help avoid some of this clutter while making the code easier to read, without any information gets lost to the reader.
For example:

MyClass myClass = new MyClass();  
In AX7 I would write:
var myClass = new MyClass();  


When the type is irrelevant.

Sometimes you don't care about the type. If you don't care the reader most likely doesn't either. 
For example:


ListEnumerator enumerator = myCollection.getEnumerator();
In AX7 I would write:
var enumerator = myCollection.getEnumerator();   



 There are a number of X++ specific reasons to not use var (i.e. doesn't apply to C#)

Limited support Visual Studio.

In the X++ editor in Visual Studio, you can use F12 to go to the declaration of a type. However, the X++ editor is still not as smart as the X++ compiler. At the time of this writing you are losing this drill through capability when not explicitly specifying the type of the variable. The same applies for IntelliSense – when using the var keyword, IntelliSense is not available (yet).
Higher risk of runtime errors.

Just like the C# compiler, the X++ compiler will determine the type from the assignment to the variable and enforce all the same rules and restrictions.

 So you might think that the use of var doesn't lead to more runtime errors. There is a catch in X++ - you should be aware of. The X++ compiler doesn't enforce any validation of method invocations on object or common. So if the X++ compiler determines the type to be object or common, then you lost your safety net. It is not always obvious.




Consider this code:

CustTable custTable = Xml2Record(xml);

custTable.someInvalidMethod(); // Compile error  

Using var, the code becomes:

var custTable = Xml2Record(xml);  

custTable.someInvalidMethod(); // No compile error, as Xml2Record() returns a common  

Sunday, 31 January 2016

X++ in AX7: Const keyword

In AX7 X++ now supports the const keyword. Semantically it is identical to const in C#.
In short; it allows you to define members on a class and variables in a method that can only be initialized during the declaration. The compiler will replace references to these constants with the literal value. In other words, the constant value must be known at compile time.


This is a killer feature! It replaces most use cases of macros.


void constsAreCool()
{
    #define.magicNumber("AX 2012");
    const str MagicNumber = "AX7";
    info(#magicNumber);
    info(MagicNumber);
}  





There are many benefits:
  1. IntelliSense in the editor.
  2. Support for "Go to definition" in the editor.
  3. Full control of the type for the constant.
  4. Faster compilation – macros are notorious hard for the compiler to handle.
  5. None of the macro idiosyncrasies – like the ability to redefine/override.
Now when you couple this with public and static members, then you can create classes with constants to replace macro libraries.


static class TimeConstants
{
    static const public int DaysPerWeek = 7;
    static const public int HoursPerDay = 24;
    static const public int HoursPerWeek = TimeConstants::DaysPerWeek * TimeConstants::HoursPerDay;
}  




It is best practice to use PascalCasing when naming const variables, regardless of if they are private, protected or public.



Notice how the constants in the class are referenced:
TimeConstants::HoursPerWeek  


This is much clearer than macros:
#TimeConstants
int x = #HoursPerWeek  



For example; you are no longer in doubt where the definition is coming from.

X++ in AX7: Const keyword

In AX7 X++ now supports the const keyword. Semantically it is identical to const in C#.
In short; it allows you to define members on a class and variables in a method that can only be initialized during the declaration. The compiler will replace references to these constants with the literal value. In other words, the constant value must be known at compile time.


This is a killer feature! It replaces most use cases of macros.


void constsAreCool()
{
    #define.magicNumber("AX 2012");
    const str MagicNumber = "AX7";
    info(#magicNumber);
    info(MagicNumber);
}  





There are many benefits:
  1. IntelliSense in the editor.
  2. Support for "Go to definition" in the editor.
  3. Full control of the type for the constant.
  4. Faster compilation – macros are notorious hard for the compiler to handle.
  5. None of the macro idiosyncrasies – like the ability to redefine/override.
Now when you couple this with public and static members, then you can create classes with constants to replace macro libraries.


static class TimeConstants
{
    static const public int DaysPerWeek = 7;
    static const public int HoursPerDay = 24;
    static const public int HoursPerWeek = TimeConstants::DaysPerWeek * TimeConstants::HoursPerDay;
}  




It is best practice to use PascalCasing when naming const variables, regardless of if they are private, protected or public.



Notice how the constants in the class are referenced:
TimeConstants::HoursPerWeek  


This is much clearer than macros:
#TimeConstants
int x = #HoursPerWeek  



For example; you are no longer in doubt where the definition is coming from.