Posts: 360
Threads: 36
Joined: Mar 2023
Reputation:
28
01-20-2025, 01:19 AM
(This post was last modified: 01-20-2025, 01:19 AM by NakedApe.)
I'm definitely grooving on the new _IIF command! So easy and concise.
IF a = 5 then b = 10 else b = 5 becomes b = _IIF(a=5, 10, 5). What's not to like?! Thanks, dev team.
Posts: 316
Threads: 16
Joined: Apr 2022
Reputation:
43
I just recently upgraded to the newest version. I have to say I like _IIF as well.
It nests well too as a function from my recent guitar fret board ap demonstrates:
FUNCTION NoteName$ (n AS tone)
'IF n.ac THEN ' If note enharmonic
' IF Vtog%(shrp_flt) THEN ' If in flat mode
' NoteName$ = n.bf
' ELSE ' If in sharp mode
' NoteName$ = n.bs
' END IF
'ELSE ' If note NOT enharmonic
' NoteName$ = n.nt
'END IF
NoteName$ = _IIF(n.ac, _IIF(Vtog%(shrp_flt), n.bf, n.bs), n.nt)
END FUNCTION 'NoteName$
Nine lines of a compound IF...THEN block distilled down to one is not too shabby.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 485
Threads: 24
Joined: May 2022
Reputation:
91
Yes, it's nice. The best part is that it's short-circuiting, so you may get a small performance boost depending on your use case.
That said, I wouldn't overuse it. Excessive use or deep nesting of _IIF can lead to code that's harder to read and maintain.
Posts: 316
Threads: 16
Joined: Apr 2022
Reputation:
43
(05-13-2025, 10:51 PM)a740g Wrote: Yes, it's nice. The best part is that it's short-circuiting, so you may get a small performance boost depending on your use case.
That said, I wouldn't overuse it. Excessive use or deep nesting of _IIF can lead to code that's harder to read and maintain. Agreed, I can see where it can get pretty confusing. Part of my coding schtick is to see how small I can write my code, and I've done some incredibly convoluted, multi-line, branchless boolean expressions in that pursuit. The _IIF command at least allows me to dispense with the possibility of making sign errors that loomed large in doing the branchless stuff.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 1,215
Threads: 162
Joined: Apr 2022
Reputation:
34
05-13-2025, 11:48 PM
(This post was last modified: 05-13-2025, 11:50 PM by madscijr.)
I'm well acquainted with nested IIFs, particularly in Excel formulas! LOL!
(The formula version is "IF", but VBA macros use the familiar IIF spelling.)
Luckily, Excel allows you to add linebreaks and indenting, albeit manually, to your formulas, to help keep track of what's happening, and even preserves this formatting.
Should you find yourself in a similar situation in QB64PE (i.e., trying to debug someone else's nested _IIF code, not your own code, because you won't be abusing _IIF that way! LoL), you can probably use a similar method using the line continuation character "_" to help make things more readable.
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
Honestly, I like this old code better than the _IIF statement:
'IF n.ac THEN ' If note enharmonic
' IF Vtog%(shrp_flt) THEN ' If in flat mode
' NoteName$ = n.bf
' ELSE ' If in sharp mode
' NoteName$ = n.bs
' END IF
'ELSE ' If note NOT enharmonic
' NoteName$ = n.nt
'END IF
Things are spread out on multiple lines and each segment is commented to help understand what it's supposed to be doing. I'd personally find the above much easier to maintain and work with after a 6 month break, where I might find myself having to go back and rework the code for some error or new enhancement, than I would the _IFF alternative.
NoteName$ = _IIF(n.ac, _IIF(Vtog%(shrp_flt), n.bf, n.bs), n.nt)
There's a lot less code there for you to write and work with, but also a lot less explanation of what's going on with that code. It's just user defined types which you might not remember what every element stands for in the future, and arrays and indexes, and... a huge question mark which says, "WTF WAS THIS DOING?!!"
It may save you a few bytes disk space and compact the code down a byte or two, but you have to consider if it's going to be worth the hit to readability and maintenance with the future of the code. Over the years, I've thrown together a LOT of quick and sloppy code, and been proud of it at the time, only to have to almost rewrite the whole thing from scratch a couple years later just because I couldn't figure out my own damn flow and logic with stuff. LOL!
My opinion with _IFF is that it's convenient, but it's a tool that I'd personally tend to use for fairly obvious stuff which isn't hard to decipher and doesn't need any comments to sort out. It's something I personally find just too murky to understand for complex stuff. If you need comments, in my opinion, it's probably best to use an IF structure and lay out those comments at the various blocks as you've did with the original code.
Your future self will thank you.  At least, mine usually does.
Posts: 1,215
Threads: 162
Joined: Apr 2022
Reputation:
34
05-14-2025, 05:31 AM
(This post was last modified: 05-14-2025, 05:35 AM by madscijr.)
I agree with you on the complex stuff. There are lots of places where _IIF works to simplify things, mainly in constructing strings and as a way to neatly wrap up logic. Here are a few examples:
Code: (Select All) sItemList = sItemList + _IIF(Len(sItemList) = 0, "", ",") + NextItem$
arrKeys(c_bKey_CrsrUp) = _IIF(_BUTTON(c_bKey_CrsrUp) = 0, FALSE, TRUE)
PRINT "GetColorDictionary%(arrColorValue()) RETURNS " + _IIF(bResult, "TRUE", "FALSE")
iErrorCount = iErrorCount + _IIF(SaveLongDictionaryCaseSensitive%(arrLongDict(), "1", cRed&), 0, 1)
GetColorDictionary% = _IIF(iErrorCount = 0, TRUE, FALSE)
sValue = _IIF(m_arrControlMap(iPlayer, iWhichInput).repeat, "Y", "N")
PRINT LEFT$(cstr$(_IIF(GetBit%(iNum%, iLoop), iValue, 0)) + " ", 3)
GetBit% = _IIF(MyValue% = MyValue% AND BitValue%, TRUE, FALSE)
sChanged = sChanged + _IIF(Len(sChanged) = 0, "", Chr$(10)) + " " + sLine
sNext = sNext + _IIF(HasBit%(iByte, iBit), "1", "0")
json_IsLargeNumber = _IIF(InStr(json_Value, "."), Len(json_Value) >= 17, Len(json_Value) >= 16)
sText = sText + _IIF(iLastKeyDown > 0, VirtualKeyCodeToString$(iLastKeyDown) + " (" + _Trim$(Str$(iLastKeyDown)) + ")", "")
sText = sText + _IIF(arrMouse(iIndex).LeftDown, "1", " ")
sText = sText + _IIF(arrMouse(iIndex).MiddleDown, "2", " ")
sText = sText + _IIF(arrMouse(iIndex).RightDown, "3", " ")
IsWeapon% = _IIF(iPos > 0, TRUE, FALSE)
IsArmor% = _IIF(iPos > 0, TRUE, FALSE)
Print "chars missing : " + _IIF(Len(missing$) = 0, "(none)", Chr$(34) + chars$ + Chr$(34))
Print "Rotated by " + cstr$(D) + " degrees" + _IIF(iMissing = 0, "", " (" + cstr$(iMissing) + " points missing)") + ":"
' an example of a nested IIF (only one level!):
Print _IIF(pDir% = cRight, "cRight", _IIF(pDir% = cLeft, "cLeft", "?")) + " ";
sMessage = sMessage + _IIF(Len(sMessage) = 0, "", " AND ") + cstr$(iPlayerLoop + 1)
sTest = "_DEFAULTCOLOR " + _IIF(_DEFAULTCOLOR = arrColor(iLoop1).value, "=", "!=") + " fgcolor" + _
sValue = _IIF(m_arrControlMap(iPlayer, iWhichInput).repeat, "Y", "N")
sLine = sLine + _IIF (iLoopX > 1, chr$(9), "") + cstr$(pixelColor&)
sLine = sLine + _IIF(pixelColor& = 0, ".", "#")
print "iWarningCount=" + cstr$(iWarningCount) + _IIF(bDoCount, " <- COUNTDOWN TO BOOM!", "")
bValue = _IIF(m_iRoundsPerGame = 0, TRUE, FALSE)
PrintString 10, 18, _IIF(bValue, "Infinite", cstr$(m_iRoundsPerGame))
sMessage = _IIF(m_arrShip(iShip1).Left_IsPressed, "LEFT ", "") ' + etc etc
sMessage = sMessage + _IIF(Len(sMessage) = 0, "", " AND ") + cstr$(iPlayerLoop + 1)
Locate m_iInstrStartRow+6, m_iInstrStartCol: Print "[ / ] TOGGLES MOVEMENT = " + _IIF(m_arrPlayer(1).IsMoving, "TRUE", "FALSE")
Locate m_iInstrStartRow+7, m_iInstrStartCol: Print "INS / DEL TOGGLES REPEAT KEYS = " + _IIF(bEnableRepeatingKeys, "TRUE", "FALSE")
Color TextColor, cEmpty: Locate iLine, 36: Print Left$(_IIf(ChromaKeyEnabled, "ON", "OFF") + " ", 4);
mem50 = _IIF(Sgn(mem53) = -1, 128, 0)
getBit = _IIF((Value And (2 ^ BitNo)) = 0, 0, 1)
pg! = Abs(bDiff&) / Abs(gDiff&) * _IIf(g1& < g2&, 1, -1)
Posts: 616
Threads: 109
Joined: Apr 2022
Reputation:
45
Nested _IIF functions can get hard to read.
I would rewrite
Code: (Select All) NoteName$ = _IIF(n.ac, _IIF(Vtog%(shrp_flt), n.bf, n.bs), n.nt)
As
Code: (Select All) NoteName$ = _IIF( n.ac, _
_IIF( Vtog%( shrp_flt ), n.bf, n.bs), _
n.nt )
That said, I still prefer nested _IFF's than nested IF-THEN-ELSE structure because:
The IF-THEN-ELSE structure really requires me to read the whole thing to figure out what it is doing.
The single assignment statement with nested _IIF's: I know as soon as I read "NoteName$ =" that I'm dealing with an assignment statement that will assign some value to NoteName$. I find that helps me avoid playing less of the game of "What is Waldo doing?" (i.e. it is immediately clear what the code is doing without needing any comments to tell me what the code is doing, which is awesome because not needing the comment reduces sensory overload via the game of "Where's Waldo". Yeah, I don't have much love for Waldo ...)
Posts: 1,215
Threads: 162
Joined: Apr 2022
Reputation:
34
(05-14-2025, 12:56 PM)CharlieJV Wrote: Nested _IIF functions can get hard to read.
I would rewrite
Exactly my point - in QB64PE, as with Excel, you can simply format it better to make it readable.
(The same is true for any command, not just IIF. I see a ton of code posted on here with multiple commands on one line done for convenience, where a simple line break + indenting makes it a lot easier to follow.)
(05-14-2025, 12:56 PM)CharlieJV Wrote: That said, I still prefer nested _IFF's than nested IF-THEN-ELSE structure because:
The IF-THEN-ELSE structure really requires me to read the whole thing to figure out what it is doing.
The single assignment statement with nested _IIF's: I know as soon as I read "NoteName$ =" that I'm dealing with an assignment statement that will assign some value to NoteName$.
I've found the same thing - using IIF to neatly wrap up logic makes code easier to understand.
(05-14-2025, 12:56 PM)CharlieJV Wrote: Yeah, I don't have much love for Waldo ...)
Sit down, Waldo!
Poor Waldo!
LoL
|