Many developers coming from other languages, comes with an expectation that AL is behaving like C# or Python. In this video, I show how if statements are evaluated.

This is another video in my series for AL beginners.
In this video, Erik explores a common gotcha for developers working with AL: the language does not use lazy (short-circuit) evaluation in compound conditional statements. This can be surprising, especially for developers coming from languages like C#, Java, or other modern languages where short-circuit evaluation is standard. Erik walks through a side-by-side comparison in C# and AL to demonstrate the difference, explains the historical reason behind it, and offers practical advice for writing safe AL code.
The Question That Started It All
A colleague from eFocus approached Erik with a puzzling issue: an if statement in AL wasn’t behaving the way he expected. The compound condition was evaluating all parts of the expression, even when the first part was already false. This led to an interesting conversation about how AL handles conditional expressions — and it’s quite different from what many developers are used to.
Lazy Evaluation in C#
To set the stage, Erik first demonstrates lazy (short-circuit) evaluation in C#. He creates two simple functions that write to the console and return boolean values:
static bool F1()
{
Console.WriteLine("F1");
return false;
}
static bool F2()
{
Console.WriteLine("F2");
return true;
}
Then he writes a compound if statement:
if (F1() && F2())
Console.WriteLine("Success");
Console.WriteLine("Done");
When both functions return true, the output is:
F1
F2
Success
Done
But when F1() returns false and F2() returns true, the output is simply:
F1
Done
This is lazy evaluation (also known as short-circuit evaluation). The C# runtime is smart enough to realize that if the first operand of an and expression is false, the entire expression can never be true — so it doesn’t bother evaluating F2() at all.
The Same Test in AL
Erik then recreates the same scenario in AL. He defines two procedures:
procedure F1(): Boolean
begin
Message('F1');
exit(false);
end;
procedure F2(): Boolean
begin
Message('F2');
exit(true);
end;
And writes the compound condition:
if F1() and F2() then
Message('Success');
When both return true, the result is as expected: F1, F2, Success.
But here’s the critical difference: when F1() returns false and F2() returns true, the output is:
F1
F2
No “Success” — but both functions were still called. AL evaluated the entire compound expression even though the result was already determined after the first operand. This is not lazy evaluation.
Why Doesn’t AL Use Lazy Evaluation?
This is the natural follow-up question, and it’s a good one. After all, AL is cross-compiled to C#, and we just showed that C# does support short-circuit evaluation. So why doesn’t AL take advantage of it?
The answer is legacy code.
Erik pulls up an old Dynamics NAV 5.0 database (circa 2009) and demonstrates the exact same behavior in C/AL — the predecessor to AL. The old language also evaluated all parts of a compound condition, regardless of the outcome of the first part.
If Microsoft were to introduce lazy evaluation in AL now, it would break existing code that depends (intentionally or not) on all conditions being evaluated. While in theory you should never rely on non-lazy evaluation, in practice there is a massive amount of legacy code out there, and changing this behavior would be dangerous.
The Workaround: Nested If Statements
The solution in AL is straightforward — use nested if statements to achieve the compounding behavior you want:
if F1() then
if F2() then
Message('Success');
This ensures that F2() is only evaluated if F1() returns true, giving you the short-circuit behavior explicitly.
Beware of Conditions with Side Effects
Erik also raises an important design consideration: be careful with conditions that have side effects. In AL, many common operations used in conditions actually modify state. For example:
if Rec.FindSet() then
// FindSet modifies the record variable
if Rec.Next() = 0 then
// Next moves the cursor on the table
Calling Next() moves the record cursor. If you put such a call inside a compound if statement, the cursor moves regardless of whether the overall condition is true or false — because AL evaluates everything. This can lead to subtle and hard-to-diagnose bugs.
The key takeaway: differentiate between pure conditions (ones that simply check a value) and conditions with side effects (ones that modify state). When in doubt, separate them into nested if statements or evaluate them into local variables before the condition.
Summary
AL does not perform lazy (short-circuit) evaluation of compound conditional expressions. Every part of a compound and or or expression is evaluated, even when the result is already determined. This behavior is inherited from C/AL and preserved for backward compatibility with decades of existing code. To work around this:
- Use nested
ifstatements when you need short-circuit behavior. - Avoid putting conditions with side effects (like
FindSet(),Next(), orInsert()) inside compound conditionals unless you explicitly want all of them to execute. - Be aware of this behavior when coming from other languages — it’s one of those quirks that can trip up developers new to AL.
Even though AL is considered a modern language and compiles to C#, its roots in C/AL mean that some behaviors are preserved for very good reasons. Understanding this aspect of the language helps you write more predictable and reliable Business Central extensions.