1 Definitions
bcond
2 Acknowledgments
3 Copyright and License
Version: 5.0.99.2

Bcond: An Extended cond Form

Version 1.0, November 2010

Richard Cobbe <cobbe at ccs dot neu dot edu>

 (require (planet cobbe/bcond:1/bcond))

This module defines a single form, bcond, that extends the built-in cond form with the ability to specify (non-recursive) bindings among the cond clauses, much like Haskell’s do construct allows let bindings mixed in with the computations.

1 Definitions

(bcond bcond-clause ...)
 
bcond-clause = [test-expr body-expr ...]
  | [test-expr]
  | [test-expr => proc-expr]
  | [else body-expr ...]
  | [let id expr]
  | [let-values (id ...) expr]
An extended conditional form, based on cond.

Evaluation of bcond proceeds exactly as for cond, with the following exceptions:

[else body-expr ...]

If execution reaches this clause, then the result of the bcond expression is the result of (begin body-expr ...), which is evaluated in tail-position with respect to the bcond form. Unlike cond, however, this clause does not have to be the last clause in the form. (Although it is impossible for subsequent clauses to be evaluated, we deliberately allow this freedom to simplify the implementation of macros that expand into bcond.)

[let id expr]

This bcond-clause binds id to the value of expr in all following bcond-clauses. The right-hand side expr is not evaluated unless evaluation falls through all preceding clauses. The expression expr is not in tail position.

[let-values (id ...) expr]

This bcond-clause evaluates expr, which must produce one value for each id, and then binds the ids to the values of expr in all following bcond-clauses. As with let clauses, expr is not in tail position, and it is not evaluated unless all preceding clauses fall through.

Examples:

  > (define (my-filter f l)
      (bcond
        [(null? l) null]
        [let x (car l)]
        [(f x) (cons x (my-filter f (cdr l)))]
        [else (my-filter f (cdr l))]))
  > (my-filter even? '(1 2 3 4 5))

  '(2 4)

In this example, bcond allows us to bind x to the first element of l without having to split the conditional into multiple expressions.

2 Acknowledgments

Many thanks to Ryan Culpepper for developing syntax-parse and helping troubleshoot problems with my first attempt at using it.

3 Copyright and License

This work is copyrighted and distributed under the terms of the Modified BSD License, included below.

Copyright (c) 2010, Richard Cobbe.

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.

  • The name of Richard Cobbe may not 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 RICHARD COBBE 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.