Written by

Senior Applications Developer at InterSystems
Question Cole Wennerholm · Apr 2, 2024

What is the Difference Between do $Increment and if $Increment?

I'm currently making some changes to legacy code and I've noticed that it uses "i $i("  all over the place. Testing in terminal seems like this does the same thing as "do $i()". Is there a difference between these two (and if not is there some interesting history around this)?

Comments

Pravin Barton · Apr 2, 2024

In older versions, trying to run "do $i(a)" would throw a <SYNTAX> error. You could instead use "if $i(a)" or "set a = $i(a)" to do the same thing. The "do $i(a)" was added with IRIS 2019.1 because it's a nicer-looking syntax. So you can treat them as identical, and the only reason to care either way is if you want to write code that is backwards-compatible with older Caché / IRIS versions.

0
Cole Wennerholm  Apr 2, 2024 to Pravin Barton

I also found one slight difference between the two:
 

ED>set a = -1

ED>d $I(a, 1) zw "test"
"test"

ED>zw a
a=0

vs.

ED>set a = -1

ED>i $I(a, 1) zw "test"

ED>zw a
a=0

0
Julius Kavay  Apr 2, 2024 to Cole Wennerholm

It's not a "slight difference", it's a real difference, because you are using two different commands (a DO and an IF command)

set a = -1// sets the variable a to -1do$increment(a,1) zw"test"// increments <a> by 1, <a> is now 0// the $increment() returns (the value of <a>)// but the DO command do not expects a return value// so the returned 0 is disposed// hereinafter the next command on the line (zw) is executedif$increment(a,1) zw"test"// increments <a> by 1, <a> is now 0// the $increment() returns (the value of <a>) which is 0// the IF command takes the returned value (0) but the value is// "FALSE", hence the rest of the line is skipped (old style IF)

If yo want to use the IF command and want both commands to be executed and have them on one line then:

// you have several options, a few of them//if$increment(a,1) { } zw"test"// empty IF-statementif$increment(a,1)!1zw"test"// an IF with a forced outcomeif$increment(a,1)=a zw"test"// if a=$increment(a,1) WON'T WORK !!!//// The only limit is only your imagination...

By the way, it's not a good idea using commands/functions with abbrevations and at the same time using mixed cases. In your examples I had to take a second look to realize, the one is a capital "i" and not a lowercase "L"

if$I(a,1) // increment a by 1if$l(a,1) // return the subfieldcount from <a>, delimited by the character "1"
0
Enrico Parisi · Apr 2, 2024

Often the if command is used for $increment because that is the "cheapest"/lightest way to increment a (local/global) variable.
In other words, it's a kind of performance optimization when using $increment.

Personally I use all the times I use $increment and I don't need the incremented value back.

0
Alexey Maslov  Apr 10, 2024 to Enrico Parisi

In other words, it's a kind of performance optimization when using $increment

I was surprised when discovered that $increment with locals is not so well optimized as it can be and as it is for globals. A small proof:

USER> set top=1E7,^||a=0,t=$zhfor i=1:1:top {set ^||a=$get(^||a)+1} w$fn($zh-t*1E6/top,"",3)
0.265
USER> set top=1E7,^||a=0,t=$zhfor i=1:1:top {do$i(^||a)} w$fn($zh-t*1E6/top,"",3)
0.176
USER> set top=1E7,a=0,t=$zhfor i=1:1:top {set a=$get(a)+1} w$fn($zh-t*1E6/top,"",3)
0.050
USER> set top=1E7,a=0,t=$zhfor i=1:1:top {do$i(a)} w$fn($zh-t*1E6/top,"",3)
0.056

I intentionally inserted $get() call just to make samples functionality closer to each other.

It's rather difficult to get for what reason $i(a) is not just the same as `set a=$get(a)+1` as it's nothing to do with TP and other globals related stuff here?

Maybe nobody was interested in deeper optimization of $i() in this context...

0
Joel Solon · Apr 9, 2024

$increment is (or used to be) unique in that it was the only function that changed its argument. It reminded me of learning about "destructive functions" in LISP a long time ago. No matter where/how you use it, it increments. So "set a = $increment(a)" is redundant, but still OK to use. As you saw, developers started to use "if $increment(a)" alone, because that was shorter but also works fine, even thought it looks strange. I wasn't aware of "do $increment(a)" being allowed, which does look nicer, so I also learned something new from this thread, thanks.

And let's not forget to mention the popular and useful "set a($increment(a)) =  something"

0
David Hockenbroch · Apr 9, 2024

You can use the if $i to do some stuff within loops too. For example, if you enter the following to commands in a terminal:

set a = 5
for{if $i(a,-1){w a,!}else{quit}}

This will subtract 1 from a and write its value until it reaches 0, then quit the loop. Of course you could just as easily use for a=4:-1:1 {w a,!} to produce the same output a little more nicely, so you don't see that as much.

0