Hi Experts
As far as I see, NAV doesn't stop evaluating an AND statement after the first wrong expression.
Example:
IF expression1 AND expression2 THEN...
Imho, expression2 is evalutated even expression1 is FALSE.
The question:
If expression2 is an expensive function, for example with DB access, is it better to write like that?
IF expression1 THEN
IF expression2 THEN
This way expression2 is only evaluated if expression1 is TRUE.
I guess this is a bit of a philosophic question, but anyway I shall be glad to get some info about your experience and/or best practice.
Kind regards
Thomas
0
Answers
I also discovered that when I started to code in NAV in 2013.
So NAV does NOT do short-circuit evaluation (https://en.wikipedia.org/wiki/Short-circuit_evaluation).
As a developer you need to be aware of this, so you don't make mistakes like:
IF(Customer.GET('xxx') AND CallSomeFunction(Customer))...
In NAV CallSomeFunction WILL be called even if Customer does not exist. In (most?) other programming languages it will not be called.
So the correct NAV code should probably read:
IF Customer.GET('xxx') THEN
IF CallSomeFunction(Customer)...
Off cause you can construct lots of similar examples.
It will probably never be changed as it potentially will break lots of existing (partner) code...
if (<expression 1> OR <expression 2>)
Even when <expression 1> is evaluated as true, NAV will still evaluate <expression 2>.
That is also not always the case if short-circuit evaluation is used...
Thanks for confirmation of the behaviour. The OR stuff is also worth noticing.
What is your experience concerning "ANDing" of performance demanding expressions?
Thanks
Thomas
In such a case GetCustomerBalance() fill be always fired, and since this one can be a bit heavy it may have visible impact.
There are 2 general ways of coding this: or (my favourite for replaing long AND... AND ... AND... conditions)
My favourite is my favourite because it is shorter than IF.. THEN IF THEN .. ELSE ...ELSE..., which helps especially if there many parts in the condition expression, it clearly defines execution order, and it helps avoiding repetitions.
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
The CASE statement by Slawek above does not do the right thing. It should be
Shortcut evaluation of OR does not work with IN, but you can do it with CASE like so:
As you can see, the AND replaced with CASE is a little awkward because Then and Else cases are reversed. So I tend to use IN, but only when I need shortcut evaluation.
I really prefer CASE over OR as soon as there are more then 2 or 3 terms involved, even if I don't need the shortcut evaluation.
But the example below is also incorrect: Using a comma in CASE conditions in just like using IN [expr1, expr2] - both conditions are evaluated, which means, if you used functions in them, both will be executed. And this is exactly what we want to avoid by using CASE
To get exact equivalent of and to get 'short-circut evaluation' using CASE it needs to be this way: or this
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
The fact that two very senior developers were able to both write bugs into a very simple piece of code shows why we keep it simple.
BTW: it is also the case with the classic client.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
Good for now.
Thanks again.
Heinz
You may easily test this out verifying the side effects of the functions, or tracing the code in the debugger.
My code using IN was wrong, though, as was my statement about using IN for OR shortcut evaluation. For both approaches, CASE, and IN, the logic is the same.
To get an AND shortcut evaluation you test for FALSE and reverse the THEN end ELSE parts in respect to the simple IF statement.
To get an OR shortcut evaluation you simply test for TRUE.
The AND case, therefore is really awkward and unintuitive, but if you need the ELSE part, it might still be preferable to David's simple cascade of IF statements, which definitely is more readable, as long as there are not too many terms in the AND expression, and as long there is no ELSE part you would not want to repeat several times for each nested IF.
The colon after the first value set {[NOT] Customer.GET('somecust') : } causes nothing to be executed if it triggers (actually it causes a syntax error, a possibly empty statement followed by a semicolon is required after it). What should happen, though, is DoSomethingElse() to be executed.
I created a simple Codeunit for everyone interested to verify these shortcut AND evaluations:
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03