digraph A { graph[] node [color=grey, style=filled, fillcolor=white, fontcolor=black]; edge [color=grey, fontcolor=grey]; CanError [label="can the function error out?", shape=box]; HasValue1 [label="does it return a value?", shape=box]; HasValue2 [label="does it return a value?", shape=box]; HasValue3 [label="does it return a value?", shape=box]; NeedDifferentiating [label="does the caller\nneed to distinguish between\ndifferent kinds of error?", shape=box] void; T; Outcome; DifferentiatedFail; NeedMessage [label="does the caller\nneed different error messages?", shape=box] OptionT [label="Option"]; ResultTDiffFail [label="Result"]; ResultTContextual [label="Result"]; CanError -> HasValue1 [label="no"]; HasValue1 -> T [label="yes"]; HasValue1 -> void [label="no"]; CanError -> NeedDifferentiating [label="yes"]; NeedDifferentiating -> HasValue2 [label="no"]; NeedDifferentiating -> HasValue3 [label="yes"]; HasValue2 -> Outcome [label="no"]; HasValue2 -> OptionT [label="yes"]; HasValue3 -> DifferentiatedFail [label="no"]; HasValue3 -> NeedMessage [label="yes"]; NeedMessage -> ResultTDiffFail [label="no"]; NeedMessage -> ResultTContextual [label="yes"]; }