[racket-dev] split-for-body from syntax/for-body

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Sep 6 12:09:11 EDT 2013

The issue is `begin` splicing. The `result` form could be a `begin`
form that contains definitions that are referenced by a preceding
forms.

For example, given

 (define (fish? v) (or (red? v) (blue? v)))
 (begin
  (define (red? v) ....)
  (define (blue? v) ....)
  5)

With `begin` splicing, that turns into

 (define (fish? v) (or (red? v) (blue? v)))
 (define (red? v) ....)
 (define (blue? v) ....)
 5

which is different than

 (define (fish? v) (or (red? v) (blue? v)))
 (let ()
   (define (red? v) ....)
   (define (blue? v) ....)
   5)

At Fri, 6 Sep 2013 11:15:50 -0400, Carl Eastlund wrote:
> Is this function ever particularly necessary?  Its intended use seems to be
> like so:
> 
> (define-syntax (for/print stx)
>   (syntax-parse stx
>     [(_ clauses . body)
>      (with-syntax ([([pre ...] [post ...]) (split-for-body #'body)])
>        (syntax
>          (for clauses
>            pre ...
>            (printf "~v/n" (let () post ...)))))]))
> 
> That way any #:break or #:final from the body ends up in pre ..., where the
> enclosing for loop will interpret them, and post ... will only include
> normal definitions and expressions.
> 
> But it seems to me there's a much easier way that should always work:
> 
> (define-syntax-rule (for/print clauses pre ... result)
>   (for clauses
>     pre ...
>     (printf "~v\n" result)))
> 
> This not only puts all #:break and #:final clauses in pre ..., it should
> guarantee result is an expression.  Perhaps one should still write (let ()
> result) in case result is (begin defn expr), but that's still simpler than
> using split-for-body.
> 
> My question is -- have I overlooked some clever subtlety here that makes
> split-for-body necessary, or is it usually easier to just decompose pre ...
> result rather than bothering with split-for-body?
> 
> Carl Eastlund
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.