Unravelling `if` statements
After the initial posting of my summary post about my syntactic sugar series, I received the following reply to one of my tweets:
🤔 wondering… ‘if/else’ (14 on your list) can be implemented in terms of ‘while’ (15 on your list)? something like this:
— wouter bolsterlee 🎹👨💻🌻 (@wbolster) August 15, 2022
run_else = True
while condition:
run_else = False
...
break
while run_else:
...
break
‘elif’ can be nested/recursive inside 2nd ‘while’
Now I had already dealt with else
(and elif
) when it came to if
, but the tweet did make me realize that I could actually unravel if
itself!
The key insight is that if you put a break
at the very end of a while
statement, it will exit the loop unconditionally. That means if you make the conditional guard on the while
loop be what the conditional guard would have been for an if
statement, you end up with the same outcome!
Take the following example:
if A:
B
if
statement exampleBy placing that break
statement at the end of the block, you can translate that if
statement into a while
statement:
while A:
B
break
if
into while
by using break
And since break
was already unravelled, you can simply this even further:
_done = False
while not _done and A:
B
_done = True
if
into while
without using break
The key observation is you must put the break
-substituting circuit breaker first in the conditional guard to avoid executing the conditional guard inherited from the if
statement itself. If you don't then you run the risk of side-effects in the if
guard being triggered twice (and that would never happen in a normal if
statement).
You can also use exceptions if you want to avoid using and
:
class _Done(Exception):
pass
try:
while A:
B
raise _Done
except _Done:
pass
if
using while
and try