Question
· Dec 15, 2017

cache operator

In if condition what is the difference between specifying the single operator and double operator? For example, what is the  difference between (&& and &) or (|| and !)

Discussion (9)0
Log in or sign up to continue

right from the documentation

You can combine multiple Boolean logical expressions by using logical operators. Like all Caché expressions, they are evaluated in strict left-to-right order. There are two types of logical operators: regular logical operators (& and !) and short-circuit logical operators (&& and ||).

When regular logical operators are used to combine logical expressions, Caché evaluates all of the specified expressions, even when the Boolean result is known before all of the expressions have been evaluated. This assures that all expressions are valid.

When short-circuit logical operators are used to combine logical expressions, Caché evaluates only as many expressions as are needed to determine the Boolean result. For example, if there are multiple AND tests, the first expression that returns 0 determines the overall Boolean result. Any logical expressions to the right of this expression are not evaluated. This allows you to avoid unnecessary time-consuming expression evaluations.

Some commands allow you to specify a comma-separated list as an argument value. In this case, Caché handles each listed argument like an independent command statement. Therefore, IF x=7,y=4,z=2 is parsed as IF x=7 THEN IF y=4 THEN IF z=2, which is functionally identical to the short-circuit logical operators statement IF (x=7)&&(y=4)&&(z=2).

(& and !) can be used almost everywhere, but not recommended because both operands will be calculated. And sometimes it can cause some unexpected behaviour. Look at my example

USER>set a=1 if a!$i(a) zw a
a=2

even when the first expression already truth second one also calculated and increased the value

USER>set a=1 if a||$i(a) zw a
a=1

In this case, the first expression already truthy, and in OR condition it's enough to make full logical expression truthy as well, and not need to calculate the second expression.

Another example - lets say you want to delete several files and check that all is fine:

ClassMethod MassDelete()
{
  #dim sc As %Status = $$$OK

  // Deletes the file. Returns true if it succeeds and false otherwise.
  // Pass return by reference to obtain the low level return value in case of errors
  #define del(%file,%return) ##class(%File).Delete(%file,%return)

  set file1 = "file1.txt"
  set file2 = "file2.txt"
  if (('$$$del(file1, .return1)) | ('$$$del(file2, .return2))) {
    set sc = $$$ERROR($$$GeneralError, "Files '%1', '%2' deletion failed with codes: %3, %4", file1, file2, $get(return1), $get(return2))
  }
  quit sc
}

In case of "||" if the first delete was successful , the second delete would not be called. Use '|' to attempt both deletes