define/  return
1 Return
return
2 Uncontracted definitions
define/  return
3 Contracted definitions
4 Notes
9.1

define/return🔗ℹ

Hans Dijkema <hans@dijkewijk.nl>

 (require define-return) package: define-return

The define-return library provides definition forms with an explicit early return. This is useful in small defensive functions, and especially around FFI bindings, where null pointers, error codes, unsupported states, or failed preconditions should leave the function immediately.

The early return is implemented with an internal exception. A return raises that exception, and the definition forms catch it around the function body. The contracted form additionally checks early-returned values against the result contract.

See define-return/contract for the contracted version of this module.

1 Return🔗ℹ

syntax

(return val)

Returns val from the nearest dynamically enclosing define/return or define/contract/return body.

The form is not a general escape continuation. It raises an internal return exception. When used outside a body installed by this library, that exception escapes.

2 Uncontracted definitions🔗ℹ

syntax

(define/return def body ...)

Like define, but body may use return to leave the definition early.

(define/return (status->symbol code)
  (unless (number? code)
    (return 'not-a-number))
  (when (= code 0) (return 'ok))
  (when (< code 0) (return 'failed))
  (when (> code 5) (return 'out-of-range))
  (cond
    ((= code 1) 'normal)
    ((>= code 2) (string->symbol (format "code-~a" (* code code))))))

The final expression is used when no early return is taken.

(status->symbol 0)    ; => 'ok
(status->symbol -1)   ; => 'failed
(status->symbol 10)   ; => 'out-of-range
(status->symbol "Hi") ; => 'not-a-number
(status->symbol 1)    ; => 'normal
(status->symbol 3)    ; => 'code-9

3 Contracted definitions🔗ℹ

See define-return/contract.

4 Notes🔗ℹ

The mechanism is intentionally small. It uses with-handlers and an internal exception type; it does not introduce prompts, continuations, or a new calling convention.

For define/contract/return, the normal function contract remains the job of define/contract. The extra returner only exists for the path where return leaves the body through an exception handler. That path would otherwise bypass the ordinary result position of the function body.

The contracted form does not try to parse arbitrary contract syntax. It splits the inline contract form syntactically and reuses its last element as the early-return result contract. This works well for ordinary result contracts such as number?, symbol?, (or/c symbol? number?), and the result position of ->* contracts.