diff --git a/docs/design/straight-line-code.md b/docs/design/straight-line-code.md new file mode 100644 index 0000000..0486629 --- /dev/null +++ b/docs/design/straight-line-code.md @@ -0,0 +1,45 @@ +# Straight-line code: Correct usage of exceptions: + +Using exceptions correctly depends on distinguishing control flow from errors. +Function naming and function prototype shaping is perhaps the best way to ensure +that these are separated properly. + +If these naming and prototype design conventions are followed, then a program +ought to be able to written without checking the results of operations; and the +programmer should be able to trust that exceptions will handle violations of xis +assumptions out of band. + +## Find vs Get: + +findFoo(): Looks for Foo and returns a data type which is expected both to + tolerate and communicate emptiness. + E.g: std::optional, std::shared/unique_ptr. + * Does not throw if Foo is not found because caller's expectations are + tentative. +``` +std::optional SomeManager::findFoo(std::string searchCriteria) +{ + for (item: collection) + { + if (item.property != searchCriteria) { continue; } + return item; + } +} +``` + +getFoo/retrieveFoo(): Looks for foo and throws if foo isn't found because caller + expects foo exist, and non-existence is a program error. Conceptually is a + wrapper around findFoo() that throws if !findFoo(). In practice due to + locking requirements it may often be necessary to implement getFoo() with + its own function body and not reuse findFoo(). + * Returns references or smart pointers, or similar types. +``` +Foo &SomeManager::getFoo(std::string searchCriteria) +{ + auto ret = findFoo(searchCriteria); + if (!ret) { throw("Foo not found with criteria " +searchCriteria); } + return ret.get(); +} +``` + +## \ No newline at end of file