[racket-dev] split-for-body from syntax/for-body
Sorry that I forgot to add the `let` while turning the code you sent
into a full example. Here's another try.
#lang racket/base
(require (for-syntax racket/base
syntax/parse
syntax/for-body))
(define-syntax (for/print/good stx)
(syntax-parse stx
[(_ clauses . body)
(with-syntax ([([pre ...] [post ...]) (split-for-body stx #'body)])
(syntax
(for clauses
pre ...
(printf "~v\n" (let () post ...)))))]))
(define-syntax-rule (for/print/fixed/not clauses pre ... result)
(for clauses
pre ...
(printf "~v\n" (let () result))))
(for/print/fixed/not ([i 1])
(define (fish? v) (or (red? v) (blue? v)))
(begin
(define (red? v) (eq? v 'red))
(define (blue? v) (eq? v 'blue))
(fish? i)))
At Fri, 6 Sep 2013 12:30:17 -0400, Carl Eastlund wrote:
> You're proving that (let () ...) is necessary, which I have explicitly
> agreed with since the original email, but you have not yet demonstrated
> that split-for-body is necessary. Here is the fix I have described twice
> already, now explicitly put into the define-syntax-rule solution:
>
> (define-syntax-rule (for/print/fixed clauses pre .. result)
> (for clauses
> pre ...
> (printf "~v\n" (let () result))))
>
> Carl Eastlund
>
>
> On Fri, Sep 6, 2013 at 12:25 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>
> >
> > #lang racket/base
> > (require (for-syntax racket/base
> > syntax/parse
> > syntax/for-body))
> >
> > (define-syntax (for/print/good stx)
> > (syntax-parse stx
> > [(_ clauses . body)
> > (with-syntax ([([pre ...] [post ...]) (split-for-body stx #'body)])
> > (syntax
> > (for clauses
> > pre ...
> > (printf "~v\n" (let () post ...)))))]))
> >
> > (define-syntax-rule (for/print/bad clauses pre ... result)
> > (for clauses
> > pre ...
> > (printf "~v\n" result)))
> >
> > ;; Try changing to for/print/bad:
> > (for/print/good ([i 1])
> > (define (fish? v) (or (red? v) (blue? v)))
> > (begin
> > (define (red? v) (eq? v 'red))
> > (define (blue? v) (eq? v 'blue))
> > (fish? i)))
> >
> >
> > At Fri, 6 Sep 2013 12:17:56 -0400, Carl Eastlund wrote:
> > > Right, that's the issue with needing the (let () result) in my
> > > define-syntax-rule version. I still didn't need split-for-body, which
> > > doesn't guarantee there are no definitions in the post ... part. All it
> > > guarantees to eliminate are #:final and #:break.
> > >
> > > Carl Eastlund
> > >
> > >
> > > On Fri, Sep 6, 2013 at 12:09 PM, Matthew Flatt <mflatt at cs.utah.edu>
> > wrote:
> > >
> > > > 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
> > > >
> > > >
> >
> >