git @ Cat's Eye Technologies Robin / master stdlib / recover.robin
master

Tree @master (Download .tar.gz)

recover.robin @masterraw · history · blame

;'<<SPEC'

<!--
Copyright (c) 2012-2024, Chris Pressey, Cat's Eye Technologies.
This file is distributed under a 2-clause BSD license.  See LICENSES/ dir.
SPDX-License-Identifier: LicenseRef-BSD-2-Clause-X-Robin
-->

### `recover` ###

    -> Tests for functionality "Evaluate Robin Expression (with literal and bind and list)"

`recover` handles abort values.  It takes 5 arguments.  It
evaluates the first argument to a value.

If the value is not an abort value, a new environment is
created where the value is bound to the name provided in the
second argument, and the third argument is evaluated in this
environment.

On the other hand, if the value is an abort value, a new
environment is created where the payload of the abort value is
bound to the name provided in the fourth argument, and in this
environment the fifth argument is evaluated.

    | (recover
    |   (literal (nice-value 999999))
    |   value (list value #t)
    |   error (list error #f))
    = ((nice-value 999999) #t)

    | (recover
    |   (abort (literal (nasty-value 999999)))
    |   value (list value #t)
    |   error (list error #f))
    = ((nasty-value 999999) #f)

If an abort value is returned from an operator that is applied
in the context of a `recover`, it will still be recovered.

    | (recover
    |   ((fexpr (args env) (abort (literal (nasty-value 1111)))) joe)
    |   value (list value #t)
    |   error (list error #f))
    = ((nasty-value 1111) #f)

If an abort value is returned from an intrinsic operator, it will still
be recovered.

    | (recover
    |   (subtract 4 (literal joe))
    |   value (list value #t)
    |   error (list error #f))
    = ((expected-number joe) #f)

Abort values are just values, so the innermost `recover` will handle
an abort value.

    | (recover
    |   (recover
    |     (abort (literal (nasty-value 999999)))
    |     value (list value #t)
    |     error (list error #f))
    |   value (list value #t)
    |   error (list error #f))
    = (((nasty-value 999999) #f) #t)

If an inner `recover` returns an abort value itself, an outer `recover` can
handle the abort value it returned.

    | (recover
    |   (recover
    |     (abort (literal (nasty-value 999999)))
    |     value (list value #t)
    |     error (abort error))
    |   value (list value #t)
    |   error (list error 123))
    = ((nasty-value 999999) 123)

`recover` expects its first argument to be a symbol.

    | (recover (3 4) (list error #f) 42)
    ? abort (illegal-arguments ((3 4) (list error #f) 42))

`recover` expects exactly five arguments.

    | (recover error (list error #f))
    ? abort (illegal-arguments (error (list error #f)))

    | (recover error (list error #f) 42 43)
    ? abort (illegal-arguments (error (list error #f) 42 43))

    | (recover error (list error #f) 42 43 44 45)
    ? abort (illegal-arguments (error (list error #f) 42 43 44 45))

`recover` handles abort values, and this does not include the environment
in which the abort value was produced.

    | (recover
    |   (bind flop 1
    |     (abort 2))
    |   value (prepend 123 (prepend value ()))
    |   error (prepend flop (prepend error ())))
    ? abort (unbound-identifier flop)

`recover` handles abort values, and this does not include the environment
in which the abort value was produced.

    | (bind flop (fexpr (args env) (bind x (eval env (head args)) (abort x)))
    |   (list
    |     (recover (flop 44) value value error (list 55 error))
    |     (recover (flop 44) value value error (list 66 error))))
    = ((55 44) (66 44))

'<<SPEC'

(require recover)