1. Rationale
    1. API
      1. checker
      2. checker?
      3. assert*
      4. named-lambda
      5. <<<
      6. <<
      7. >>>
      8. >>
      9. <<<%
      10. <<%
      11. >>>%
      12. >>%
      13. true?
      14. false?
      15. checks
    2. Examples
  2. Requirements
  3. Last update
  4. Author
  5. Repository
  6. License
  7. Version history

Rationale

Pre- and postconditions made easy --------------------------------- This egg implements some routines, which are outsourced from simple-exceptions. In particular macros << and >>, which accept an argument or result, checks it against zero or more predicates and returns it in case of success unchanged. Otherwise it prints a meaningful error message, showing i.a. the offending predicate and the argument's or result's name. Some are implemented as macros instead of procedures, because I didn't want an extra parameter with the argument's or result's name. Procedure versions of those macros are given as well. In reimplementing those routines, I changed the syntax a bit, so be careful, if you used the equally named routines from simple-expressions.

The precondition and postcondition checks are denoted with some consecutive symbols < and > respectively. There are macro and procedure versions, the latter denoted with a trailing % and needing an additional parameter, the name of the value to be checked. All those routines work the same, they differ only in the error message, they produce in case some predicate returns #f. The routines named with three symbols < or > differ from those with two only by an additional parameter naming the location of the checks.

API

checker

[procedure] (checker sym .. ok? ....)

creates a checker routine, i.e. a unuary procedure, which returns its argument unchanged, provided it passes all ok? tests. If not, an error is generated with location sym, whose default is 'checker.

checker?

[procedure] (checker? xpr)

type predicate.

assert*

[syntax] (assert* loc xpr . xprs)

checks, if its arguments xpr . xprs are not #f.

named-lambda

[syntax] (named-lambda (name . args) xpr . xprs)

can be used in place of lambda, possibly improving error messages

<<<

[syntax] (<<< loc arg arg? ...)

Precondition test. Check a procedure argument, arg, against each predicate arg? ... in sequence and pass it to the procedure in case of success. loc names the location in the error message.

<<

[syntax] (<< arg arg? ...)

Precondition test. Check a procedure argument, arg, against each predicate arg? ... in sequence and pass it to the procedure in case of success.

>>>

[syntax] (>>> loc result result? ...)

Postcondition test. Check a return value of a function, result, against each predicate result? ...in sequence and return it in case of success. loc names the location in case of error.

>>

[syntax] (>> result result? ...)

Postcondition test. Check a return value of a function, result, against each predicate result? ...in sequence and return it in case of success.

<<<%

[procedure] (<<<% loc arg-name arg . tests)

Precondition test. Procedure version of <<<, arg needs to be named.

<<%

[procedure] (<<% arg-name arg . tests)

Precondition test. Procedure version of <<, arg needs to be named.

>>>%

[procedure] (>>>% loc result-name result . tests)

Postcondition test. Procedure version of >>>, result needs to be named.

>>%

[procedure] (>>% result-name result . tests)

Postcondition test. Procedure version of <<, result needs to be named.

true?

[procedure] (true? xpr)

always true

false?

[procedure] (false? xpr)

always false

checks

[procedure] (checks)
[procedure] (checks sym)

with sym: documentation of exported symbol without sym: list of exported symbols

Examples


(import checks)

(checker? checkit)
;-> #t

(checker? checkme)
;-> #t

(checker? string?)
;-> #f

(checkit 5)
;-> 5

(checkme 5)
;-> 5

(condition-case (checkme -1) ((exn) #f))
;-> #f

(condition-case ((checker 'bar string?) 5) ((exn) #f))
;-> #f

(assert* 'x (integer? x))
;-> #t

(assert* 'x (integer? x) (odd? x))
;-> #t

(condition-case (assert* 'x (integer? x) (even? x)) ((exn assert) #f))
;-> #f

x
;-> 5

(>> x)
;-> 5

(<< x)
;-> 5

(>> x integer? odd?)
;-> 5

(>>% 'x x integer? odd?)
;-> 5

(<< x integer? odd?)
;-> 5

(<<% 'x x integer? odd?)
;-> 5

(<<< 'loc x integer? odd?)
;-> 5

(>>> 'loc x integer? odd?)
;-> 5

(<<<% 'loc 'x x integer? odd?)
;-> 5

(>>>% 'loc 'x x integer? odd?)
;-> 5

(condition-case (<<% 'x x integer? even?) ((exn argument) #f))
;-> #f

(condition-case (<<<% 'loc 'x x integer? even?) ((exn argument) #f))
;-> #f

(condition-case (>> x integer? even?) ((exn result) #f))
;-> #f

(<< ((lambda () #f)) boolean?)
;-> #f

((named-lambda (! n) (if (zero? n) 1 (* n (! (- n 1))))) 5)
;-> 120

Requirements

simple-exceptions

Last update

Feb 13, 2021

Author

Juergen Lorenz

Repository

This egg is hosted on the CHICKEN Subversion repository:

https://anonymous@code.call-cc.org/svn/chicken-eggs/release/5/checks

If you want to check out the source code repository of this egg and you are not familiar with Subversion, see this page.

License

Copyright (c) 2014-2021, Juergen Lorenz All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version history

1.4
checkers added
1.3
dependency on simple-exceptions added
1.2
code cleaned
1.1.0
documentation of named-lambda fixed
1.1
procedure versions added
1.0
extracted and modified from simple-exceptions