Probably a dumb question, but I'll ask anyhow as I haven't been able to find a definitive answer. Given:
I realize the IF version can only use a simple conditional, but aside from that, is one form preferable over the other? Are there any subtle differences that aren't obvious?
The biggest difference is that the "While..." option is newer (and, as you noted, allows any expression) and the simple conditional "IF" used to be the only way to do this. The latter was not removed when the former was added so as to not break existing rules, so either is still available, and whichever one you want to use should continue to work as long as it meets your needs.
I don't think I've encountered that IF..Repeat statement in Hubitat before, but I assume an IF statement would only be evaluated one initial time and then any Repeat instructions would continue to execute indefinitely (or as otherwise programmed). A While statement will be re-evaluated on every repeat cycle, thus a change in the condition evaluated for the While loop can break the Repeats on its own, while for the IF logic it would be necessary to break or expire the Repeats through some other means.
One could certainly interpret it that way, but that's not how it appears to behave.
It would be good to have an official statement as to whether both constructs (using the same conditional) generate the exact same code, or whether there is some subtle difference, even if it only affects some weird edge case.
This is why I linked to the docs in my post above. (That being said, it's also very easy to test if you don't believe them or me. )
Rule Machine does not "generate code." While very complex, it's ultimately an app like any other that does what you've configured in the UI using the techniques available to developers on the platform (that much is, like any app, in Groovy, but that's where it stops, also like any app).
Neither of the above. I do believe you and my limited tests agree with the docs.
It is highly unlikely RM is storing the rule in its human-readable text representation. Most likely it is generating java or groovy, in addition to an AST or some other format. Maybe the json that you get when exporting the rule is actually the internal format.
In any case, it would be highly inefficient to parse text or even an AST every time the rule is fired, so some sort of executable "code" is almost certainly being generated when a rule is saved.
Not to beat a dead horse, I was just wondering whether the two forms generate the exact same "code" or there may be some subtle difference. We've all seen plenty of threads where someone ran into some weird edge case. Those things aren't always obvious or revealed through testing and not always documented.
It's not (at least not for any purpose beyond caching). That's how it's displaying the selections you have made. Those are stored in the settings map in the app, the same way any app can do it and as is visible on the App Status page (though without the Groovy code to actually use them, again like any app, it won't always be meaningful to a human just looking at them).
I think the fact that RM displays a summary of your actions in a sort of pseudocode misleads some into thinking that this is actual code RM "runs" somehow, but it's not--it all goes back to the same app features, mostly the settings and state stores, available to all developers.
So the question really can't be answered; there is no "code" that gets generated making a rule, and the settings are naturally going to be different because you chose a different setting (input) value. But the outcome should be the same; one of these is just a newer feature.