patternMinor
Are if statements unnecessary if a program is represented as an explicit state machine?
Viewed 0 times
representedunnecessaryarestatementsprogramexplicitstatemachine
Problem
This question occurred to me some time ago when I was thinking about whether or not
Consider a program that manages a single bank account (for the sake of simplicity). The bank account could be defined as something like
Since the program has no way to known in which state it currently is unless it performs validations using
However, over the course of time, the program will pass through a finite set of states that can be known beforehand. In this particular case, a state is defined solely by the value of the
If we assign each state a number, say state {0,1,2,....} with a 1-1 correspondence to the above set of states, and assign to each operation a number identifier as well (say
Consider that
In the case of withdrawal, it would be like:
if statements are fundamental in computation.Consider a program that manages a single bank account (for the sake of simplicity). The bank account could be defined as something like
Account
{
int balance; // current amount of Money
boolean withdraw(int n)
{
if (balance >= n)
{
balance = balance -n;
return true;
}
else
return false;
}
void deposit(int n)
{
amount = amount + n;
}
}Since the program has no way to known in which state it currently is unless it performs validations using
if statements, as in the withdraw operation, if statements are unavoidable.However, over the course of time, the program will pass through a finite set of states that can be known beforehand. In this particular case, a state is defined solely by the value of the
balance variable, hence we would have states: {balance = 0 , balance = 1, balance = 2...}.If we assign each state a number, say state {0,1,2,....} with a 1-1 correspondence to the above set of states, and assign to each operation a number identifier as well (say
deposit = 0 and withdraw = 1), we could model the program as an explicit transition between states and therefore remove every if statement from the code.Consider that
state = 0 is the state where balance = 0 and we want to perform a deposit of 50 dollars, if we coded every single possible execution of the deposit function, we could just define the deposit function asvoid deposit (int n)
{
deposit[state][n]; // índex deposit instance for state = 0, amount = n;
}deposit[][] would be a matrix of pointers for a set of functions that represent each possible execution of deposit, likedeposit[0][0] -> balance = balance + 0; state = 0;
deposit[0][1] -> balance = balance + 1; state = 1;
....In the case of withdrawal, it would be like:
Solution
Literal
with
On the other hand, doing so has no clear advantages and many disadvantages. The gigantic-table-of-functions approach leads to huge redundancy, is very hard to maintain and is very hard for compilers and CPUs to optimize. If you're lucky, the
At a fundamental level, some form of conditional execution is necessary. If you have no kind of conditional statement at all, then you can only perform a class of very limited programs called "straight-line programs". These are, perhaps surprisingly, useful as a model of computation because they have a fairly simple correspondence with circuits: they correspond to the simplest notion of algorithm, i.e., take your input data and perform a fixed sequence of operations on it. For example, when you compute the length of a 2D vector, you're using a straight-line program: square the $x$-coordinate, square the $y$-coordinate, add the two squares, take the square root (at least, assuming that all those arithmetic operations, including square root, are taken as being built in to your langauge).
if statements are not fundamental. As you've shown, it's possible to remove them by writing your program as a state machine, though at the gigantic cost of having to have a different version of the widthdraw() function for every possible starting balance and withdrawal amount. You can also avoid literal if statements by replacingif (condition) {
foo
} else {
bar
}with
b1 := condition
b2 := not(b1)
while (b1) {
foo
b1 := false
}
while (b2) {
bar
b2 := false
}On the other hand, doing so has no clear advantages and many disadvantages. The gigantic-table-of-functions approach leads to huge redundancy, is very hard to maintain and is very hard for compilers and CPUs to optimize. If you're lucky, the
while loop hack might compile to the same code as the simple code with if statements but it's much harder to read and much more prone to programmers mistakenly thinking they can optimize it.At a fundamental level, some form of conditional execution is necessary. If you have no kind of conditional statement at all, then you can only perform a class of very limited programs called "straight-line programs". These are, perhaps surprisingly, useful as a model of computation because they have a fairly simple correspondence with circuits: they correspond to the simplest notion of algorithm, i.e., take your input data and perform a fixed sequence of operations on it. For example, when you compute the length of a 2D vector, you're using a straight-line program: square the $x$-coordinate, square the $y$-coordinate, add the two squares, take the square root (at least, assuming that all those arithmetic operations, including square root, are taken as being built in to your langauge).
Code Snippets
if (condition) {
foo
} else {
bar
}b1 := condition
b2 := not(b1)
while (b1) {
foo
b1 := false
}
while (b2) {
bar
b2 := false
}Context
StackExchange Computer Science Q#32310, answer score: 4
Revisions (0)
No revisions yet.