(Only half joking with the poll options, too.)

  • @lambaliciousOP
    link
    English
    14 days ago

    Consider, say, the printf family of functions. The side-effect of their invocation is quite notorious and clear: print something to the screen, or write it to a file, etc. This kind of thing is not expressable (and should not be expressed as) as a return type. But these functions do have a return value: a status code indicating whether the write-to-medium was successful or else why. It’s so easy to discard this information and end up eg.: ignorin a write that didn’t happen because there was not enough room, or writing more bytes than the destination buffer could afford to take (hellooooo, buffer overflow!).

    There are lots of functions (probably entire categories, but I’m not that strong on type theory) where the “result” is vastly different from the “return” or can not be expressed as such. Foremost cases I can come up with are I/O, stuff on complex types where types also represent actions or components with side effects (eg.: GUIs), and pretty much anything about inserting or removing elements from containers. In those cases, if the two things differ but the return is also important, it’d be nice to have a mechanism to make sure that it can’t be accidentally ignored (explicit, intentional ignoring is fine; that’s what we have (void)(expr...) in the language).

    Another reason for having this capability is having a function with a composite return-result type, such as a std::expected<T,E> where you want to help make sure the composition is handled correctly by the caller.