Skip to content

Instantly share code, notes, and snippets.

@eernstg
Created April 5, 2018 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eernstg/e6351d655334455c511288345c5fbaec to your computer and use it in GitHub Desktop.
Save eernstg/e6351d655334455c511288345c5fbaec to your computer and use it in GitHub Desktop.
bool b = false;
void doWork(int i) => print("Do work ($i)");
void bailOut(int i) => print("Bail out ($i)");
void acquire() => print("Acquire the resource");
void release() => print("Release the resource");
// Consider: We want to simplify the following control flow.
void foo(List<bool> b) {
print("---------------------");
acquire();
doWork(0);
if (b[0]) {
bailOut(0);
release();
return;
}
doWork(1);
if (b[1]) {
bailOut(1);
release();
return;
}
doWork(2);
if (b[2]) {
bailOut(2);
release();
return;
}
doWork(3);
release();
doWork(4);
}
// Simplification using a local function to abstract out common elements.
// Problem: We seem to want non-local returns. Also, we create closures
// for each `bailOut`, and they will be allocated even if left unused.
void foo1(List<bool> b) {
bool failed(bool b, void then()) {
if (!b) return b;
then();
release();
return true; // "Should" have returned from `foo1`.
}
print("---------------------");
acquire();
doWork(0);
if (failed(b[0], () { bailOut(0); })) return;
doWork(1);
if (failed(b[1], () { bailOut(1); })) return;
doWork(2);
if (failed(b[2], () { bailOut(2); })) return;
doWork(3);
release();
doWork(4);
}
// Simplification purely via control flow reorganization.
void foo2(List<bool> b) {
print("---------------------");
acquire();
doWork(0);
if (b[0]) bailOut(0); else {
doWork(1);
if (b[1]) bailOut(1); else {
doWork(2);
if (b[2]) bailOut(2); else {
doWork(3);
doWork(4); // Work 4 and release can be swapped: independent.
}
}
}
release();
}
void run(void f(List<bool> b)) {
f([false,false,false]);
f([false,false,true]);
f([false,true,false]);
f([true,false,false]);
}
main() {
run(foo);
print("");
run(foo2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment