diff --git a/community/knowledge/performance/case-true-of-for-long-condition-chains.bad.al b/community/knowledge/performance/case-true-of-for-long-condition-chains.bad.al index 464d442..bdd0dfa 100644 --- a/community/knowledge/performance/case-true-of-for-long-condition-chains.bad.al +++ b/community/knowledge/performance/case-true-of-for-long-condition-chains.bad.al @@ -21,7 +21,8 @@ codeunit 50543 "Perf Sample CaseChain Bad" begin // The wrong escape from the ladder: flattening it into 'and' trades the // nesting for a defect, because every operand is still evaluated. Item - // fields are read even when the Get failed. + // fields are read even when the Get failed. The parentheses are not + // optional either — 'and' binds tighter than '=' and '<>' in AL. exit((SalesLine.Type = SalesLine.Type::Item) and (SalesLine."No." <> '') and (SalesLine."Qty. to Ship" > 0) and Item.Get(SalesLine."No.") and (not Item.Blocked)); end; diff --git a/community/knowledge/performance/case-true-of-for-long-condition-chains.good.al b/community/knowledge/performance/case-true-of-for-long-condition-chains.good.al index 08918c5..433cf7c 100644 --- a/community/knowledge/performance/case-true-of-for-long-condition-chains.good.al +++ b/community/knowledge/performance/case-true-of-for-long-condition-chains.good.al @@ -8,11 +8,11 @@ codeunit 50542 "Perf Sample CaseChain Good" // so each condition is reached only when the previous one passed — and // Item.Get is never called for a non-item line. case false of - (SalesLine.Type = SalesLine.Type::Item), - (SalesLine."No." <> ''), - (SalesLine."Qty. to Ship" > 0), + SalesLine.Type = SalesLine.Type::Item, + SalesLine."No." <> '', + SalesLine."Qty. to Ship" > 0, Item.Get(SalesLine."No."), - (not Item.Blocked): + not Item.Blocked: exit(false); end; exit(true); diff --git a/community/knowledge/performance/case-true-of-for-long-condition-chains.md b/community/knowledge/performance/case-true-of-for-long-condition-chains.md index 0e68efd..4dc19a8 100644 --- a/community/knowledge/performance/case-true-of-for-long-condition-chains.md +++ b/community/knowledge/performance/case-true-of-for-long-condition-chains.md @@ -15,7 +15,7 @@ Because AL gives no short-circuit guarantee for `and` and `or`, a chain of condi ## Best Practice -Sequence two or three dependent conditions with nested `if`. Beyond that, switch to `case`: use `case false of` for a chain of guards where every condition must hold, letting control fall past `end` when all of them pass; use `case true of` for first-match dispatch, where each later probe runs only if the earlier ones did not match. Conditions that share an action are comma-separated into a single value set, one per line, so the chain reads as one ordered list with one failure action instead of repeating that action per condition. This keeps every condition at one indentation level, makes evaluation order explicit rather than implied by nesting, and preserves the stop-at-first-match behaviour. It also aligns with the AL programming convention that more than two alternatives belong in a `case` statement rather than an `if-then-else`. +Sequence two or three dependent conditions with nested `if`. Beyond that, switch to `case`: use `case false of` for a chain of guards where every condition must hold, letting control fall past `end` when all of them pass; use `case true of` for first-match dispatch, where each later probe runs only if the earlier ones did not match. Conditions that share an action are comma-separated into a single value set, one per line, so the chain reads as one ordered list with one failure action instead of repeating that action per condition. A value set also needs no parentheses around a comparison, unlike an operand of `and` or `or`: the AL operator hierarchy places `and` and `or` above the comparison operators, so parentheses are mandatory there and the chain fills up with them. This keeps every condition at one indentation level, makes evaluation order explicit rather than implied by nesting, and preserves the stop-at-first-match behaviour. It also aligns with the AL programming convention that more than two alternatives belong in a `case` statement rather than an `if-then-else`. See sample: `case-true-of-for-long-condition-chains.good.al`.