Skip to content

Handling runtime errors/exceptions #212

Open
@nshaffer

Description

@nshaffer

This issue is to discuss approaches to handle runtime errors and exceptions in stdlib. I have in mind scenarios such as

  • An iterative solver algorithm fails to converge
  • A negative number is passed to a routine that requires a nonnegative one
  • Not enough memory for an array allocation

These are conditions which cannot be identified at compile time, but if left alone will either cause user code to crash or be erroneous. Currently in stdlib, we have check, which can print error messages and optionally terminate execution. I think it is not sufficient for general-purpose runtime checking. To me, there are a few major considerations when thinking about runtime checking

  1. Users must be given the opportunity to recover from the error if at all possible. This is especially important for library code, which may be difficult to debug depending on the installation/distribution. It is also generally rude for library code to kill execution without giving the user any say in the matter.

  2. It should be possible to recover from runtime errors without sacrificing purity. If a routine is manifestly pure, then it should not have to sacrifice the pure attribute just to have some error checking. If I write a factorial function, making it pure and handling negative arguments should not have to be an either/or proposition.

  3. Checking and handling errors should not be unduly burdensome to users. If a function call requires one line, and handling its possible error conditions requires ten, users will simply not bother with error checking.

This list of criteria is not exhaustive, but they are the three that are most important to me. That stated, here are the runtime checking approaches I am most familiar with and how they stack up:

  1. Return error code and message as optional out-params.

    • Does not play nicely with pure functions (pure subroutines OK, though)
    • Intrinsic functions do not do this (but statements do, e.g., iostat, iomsg)
    • Passes the buck to the user to interpret and handle the error code/message
  2. Die with error stop

    • As of f2018, can be used in pure functions
    • Kind of rude for library code to kill execution without chance of recovery
  3. Return a special value

    • This is what intrinsics usually do, e.g., index returning -1
    • Some algorithms may not have a natural "obviously wrong" value (maybe NaN?)
    • Works with pure functions/subroutines
  4. Raise an exception

    • Maybe in 2045?

Of these, my preference is strongly toward approach 3 whenever possible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    implementationImplementation in experimental and submission of a PRmetaRelated to this repositorytopic: utilitiescontainers, strings, files, OS/environment integration, unit testing, assertions, logging, ...

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions