A new scheme user trying to use syntax-rules to define something like the Haskell where keyword.

Sometimes this is useful since when we do programming, we first design in the high level, where all the names left undefined. In later steps, we define those names and complete the program. where keyword preserves the order of definition which keeps the last name defined first.

The idea is simple. I start with a define-syntax

(define-syntax do
   (syntax-rules (where let)

The desired pattern is (do *body* (where *definitions*)), so we first due with the case when there are no definitions.

     [(_ body (where ())) body]

If the body is a let binding, I take out one where definition and append to the let bindings, and recurs. (This implies the where definitions appear in front of any existing let definitions in the result, and the order of where definitions will be reversed).

     [(_ (let (v ...) body) (where (w0 w ...))) 
      (do (let (w0 v ...) body) (where (w ...)))]

Finally, if the body is not a let binding, I need to take out one definition and make a let binding.

     [(_ body (where (w0 w ...))) 
      (do (let (w0) body) (where (w ...)))]

Now terminate the definition.


This definition works fine:

(do (x y z) (where ([x +] [y 1] [z 2])))


  1. The naming. Are there a better name for do?

  2. Support for similar bindings like let*, letrec, let*-values etc. All of those seems to share the same pattern and so I can just replicate the code to do so but there are quite a few variations (6 in total if I was right). So are there any way to eliminate the code duplication?

  3. Are there any other ideas to improve the code?

  • \$\begingroup\$ I'll comment on the first point only. Yes, don't use the name do. Scheme has a built-in macro called do, which is for writing loops. \$\endgroup\$ Aug 5, 2015 at 4:29


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.