<div dir="ltr">They have to be separate internal definition contexts in order for #:break and #:final to be able to stop execution before the definitions themselves get run.<br></div><div class="gmail_extra"><br clear="all">

<div>Carl Eastlund</div>
<br><br><div class="gmail_quote">On Fri, Sep 6, 2013 at 2:31 PM, Stephen Chang <span dir="ltr">&lt;<a href="mailto:stchang@ccs.neu.edu" target="_blank">stchang@ccs.neu.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">&gt; &quot;Among the bodys, besides stopping the iteration and preventing later body evaluations, a #:break guard-expr or #:final guard-expr clause starts a new internal-definition context.&quot;<br>
<br>
</div>I had the same thought process as Carl. I now understand the behavior<br>
but I don&#39;t understand why it&#39;s needed? It seems kind of arbitrary<br>
since no other form allows multiple internal def contexts in the body<br>
like this. Is there a practical example?<br>
<div class="HOEnZb"><div class="h5"><br>
On Fri, Sep 6, 2013 at 12:58 PM, Carl Eastlund &lt;<a href="mailto:cce@ccs.neu.edu">cce@ccs.neu.edu</a>&gt; wrote:<br>
&gt; Okay, I see what&#39;s going on here.  It&#39;s very subtle though, and probably<br>
&gt; deserves some explanation in split-for-body&#39;s documentation.<br>
&gt;<br>
&gt; My first thought on seeing my non-fix version break here is that I can make<br>
&gt; split-for-body break the same way.  The problem is that my non-fix separates<br>
&gt; the definition of fish? from the definitions of red? and blue?, which it<br>
&gt; depends on.  I can make split-for-body separate them the same way, by<br>
&gt; putting a #:break or #:final clause in between the definition of fish? and<br>
&gt; the begin form.<br>
&gt;<br>
&gt; The problem with doing so is a subtle point about for loops that is only<br>
&gt; mentioned in the last sentence of the last paragraph of the documentation of<br>
&gt; for itself:<br>
&gt;<br>
&gt;   &quot;Among the bodys, besides stopping the iteration and preventing later body<br>
&gt; evaluations, a #:break guard-expr or #:final guard-expr clause starts a new<br>
&gt; internal-definition context.&quot;<br>
&gt;<br>
&gt; So that&#39;s what split-for-body is preserving, the boundaries between internal<br>
&gt; definition contexts.  That&#39;s not at all what I had expected it was doing; I<br>
&gt; had no idea the body of a for loop constituted multiple such contexts.<br>
&gt;<br>
&gt; Anyway, thanks for the clarification, I now understand why abstractions over<br>
&gt; for loops need to use split-for-body.<br>
&gt;<br>
&gt; Carl Eastlund<br>
&gt;<br>
&gt;<br>
&gt; On Fri, Sep 6, 2013 at 12:38 PM, Matthew Flatt &lt;<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Sorry that I forgot to add the `let` while turning the code you sent<br>
&gt;&gt; into a full example. Here&#39;s another try.<br>
&gt;&gt;<br>
&gt;&gt; #lang racket/base<br>
&gt;&gt; (require (for-syntax racket/base<br>
&gt;&gt;                      syntax/parse<br>
&gt;&gt;                      syntax/for-body))<br>
&gt;&gt;<br>
&gt;&gt; (define-syntax (for/print/good stx)<br>
&gt;&gt;   (syntax-parse stx<br>
&gt;&gt;     [(_ clauses . body)<br>
&gt;&gt;      (with-syntax ([([pre ...] [post ...]) (split-for-body stx #&#39;body)])<br>
&gt;&gt;        (syntax<br>
&gt;&gt;         (for clauses<br>
&gt;&gt;           pre ...<br>
&gt;&gt;           (printf &quot;~v\n&quot; (let () post ...)))))]))<br>
&gt;&gt;<br>
&gt;&gt; (define-syntax-rule (for/print/fixed/not clauses pre ... result)<br>
&gt;&gt;   (for clauses<br>
&gt;&gt;     pre ...<br>
&gt;&gt;     (printf &quot;~v\n&quot; (let () result))))<br>
&gt;&gt;<br>
&gt;&gt; (for/print/fixed/not ([i 1])<br>
&gt;&gt;   (define (fish? v) (or (red? v) (blue? v)))<br>
&gt;&gt;   (begin<br>
&gt;&gt;     (define (red? v) (eq? v &#39;red))<br>
&gt;&gt;     (define (blue? v) (eq? v &#39;blue))<br>
&gt;&gt;     (fish? i)))<br>
&gt;&gt;<br>
&gt;&gt; At Fri, 6 Sep 2013 12:30:17 -0400, Carl Eastlund wrote:<br>
&gt;&gt; &gt; You&#39;re proving that (let () ...) is necessary, which I have explicitly<br>
&gt;&gt; &gt; agreed with since the original email, but you have not yet demonstrated<br>
&gt;&gt; &gt; that split-for-body is necessary.  Here is the fix I have described<br>
&gt;&gt; &gt; twice<br>
&gt;&gt; &gt; already, now explicitly put into the define-syntax-rule solution:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; (define-syntax-rule (for/print/fixed clauses pre .. result)<br>
&gt;&gt; &gt;   (for clauses<br>
&gt;&gt; &gt;     pre ...<br>
&gt;&gt; &gt;     (printf &quot;~v\n&quot; (let () result))))<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Carl Eastlund<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; On Fri, Sep 6, 2013 at 12:25 PM, Matthew Flatt &lt;<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; #lang racket/base<br>
&gt;&gt; &gt; &gt; (require (for-syntax racket/base<br>
&gt;&gt; &gt; &gt;                      syntax/parse<br>
&gt;&gt; &gt; &gt;                      syntax/for-body))<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; (define-syntax (for/print/good stx)<br>
&gt;&gt; &gt; &gt;   (syntax-parse stx<br>
&gt;&gt; &gt; &gt;     [(_ clauses . body)<br>
&gt;&gt; &gt; &gt;      (with-syntax ([([pre ...] [post ...]) (split-for-body stx<br>
&gt;&gt; &gt; &gt; #&#39;body)])<br>
&gt;&gt; &gt; &gt;        (syntax<br>
&gt;&gt; &gt; &gt;         (for clauses<br>
&gt;&gt; &gt; &gt;           pre ...<br>
&gt;&gt; &gt; &gt;           (printf &quot;~v\n&quot; (let () post ...)))))]))<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; (define-syntax-rule (for/print/bad clauses pre ... result)<br>
&gt;&gt; &gt; &gt;   (for clauses<br>
&gt;&gt; &gt; &gt;     pre ...<br>
&gt;&gt; &gt; &gt;     (printf &quot;~v\n&quot; result)))<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; ;; Try changing to for/print/bad:<br>
&gt;&gt; &gt; &gt; (for/print/good ([i 1])<br>
&gt;&gt; &gt; &gt;   (define (fish? v) (or (red? v) (blue? v)))<br>
&gt;&gt; &gt; &gt;   (begin<br>
&gt;&gt; &gt; &gt;     (define (red? v) (eq? v &#39;red))<br>
&gt;&gt; &gt; &gt;     (define (blue? v) (eq? v &#39;blue))<br>
&gt;&gt; &gt; &gt;     (fish? i)))<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; At Fri, 6 Sep 2013 12:17:56 -0400, Carl Eastlund wrote:<br>
&gt;&gt; &gt; &gt; &gt; Right, that&#39;s the issue with needing the (let () result) in my<br>
&gt;&gt; &gt; &gt; &gt; define-syntax-rule version.  I still didn&#39;t need split-for-body,<br>
&gt;&gt; &gt; &gt; &gt; which<br>
&gt;&gt; &gt; &gt; &gt; doesn&#39;t guarantee there are no definitions in the post ... part.<br>
&gt;&gt; &gt; &gt; &gt; All it<br>
&gt;&gt; &gt; &gt; &gt; guarantees to eliminate are #:final and #:break.<br>
&gt;&gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; Carl Eastlund<br>
&gt;&gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; On Fri, Sep 6, 2013 at 12:09 PM, Matthew Flatt &lt;<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>&gt;<br>
&gt;&gt; &gt; &gt; wrote:<br>
&gt;&gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; The issue is `begin` splicing. The `result` form could be a<br>
&gt;&gt; &gt; &gt; &gt; &gt; `begin`<br>
&gt;&gt; &gt; &gt; &gt; &gt; form that contains definitions that are referenced by a preceding<br>
&gt;&gt; &gt; &gt; &gt; &gt; forms.<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; For example, given<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (define (fish? v) (or (red? v) (blue? v)))<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (begin<br>
&gt;&gt; &gt; &gt; &gt; &gt;   (define (red? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;   (define (blue? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;   5)<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; With `begin` splicing, that turns into<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (define (fish? v) (or (red? v) (blue? v)))<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (define (red? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (define (blue? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;  5<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; which is different than<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (define (fish? v) (or (red? v) (blue? v)))<br>
&gt;&gt; &gt; &gt; &gt; &gt;  (let ()<br>
&gt;&gt; &gt; &gt; &gt; &gt;    (define (red? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;    (define (blue? v) ....)<br>
&gt;&gt; &gt; &gt; &gt; &gt;    5)<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; At Fri, 6 Sep 2013 11:15:50 -0400, Carl Eastlund wrote:<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; Is this function ever particularly necessary?  Its intended use<br>
&gt;&gt; &gt; &gt; seems to<br>
&gt;&gt; &gt; &gt; &gt; &gt; be<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; like so:<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; (define-syntax (for/print stx)<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;   (syntax-parse stx<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;     [(_ clauses . body)<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;      (with-syntax ([([pre ...] [post ...]) (split-for-body<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; #&#39;body)])<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;        (syntax<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;          (for clauses<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;            pre ...<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;            (printf &quot;~v/n&quot; (let () post ...)))))]))<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; That way any #:break or #:final from the body ends up in pre<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; ...,<br>
&gt;&gt; &gt; &gt; where<br>
&gt;&gt; &gt; &gt; &gt; &gt; the<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; enclosing for loop will interpret them, and post ... will only<br>
&gt;&gt; &gt; &gt; include<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; normal definitions and expressions.<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; But it seems to me there&#39;s a much easier way that should always<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; work:<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; (define-syntax-rule (for/print clauses pre ... result)<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;   (for clauses<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;     pre ...<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;     (printf &quot;~v\n&quot; result)))<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; This not only puts all #:break and #:final clauses in pre ...,<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; it<br>
&gt;&gt; &gt; &gt; should<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; guarantee result is an expression.  Perhaps one should still<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; write<br>
&gt;&gt; &gt; &gt; (let<br>
&gt;&gt; &gt; &gt; &gt; &gt; ()<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; result) in case result is (begin defn expr), but that&#39;s still<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; simpler<br>
&gt;&gt; &gt; &gt; &gt; &gt; than<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; using split-for-body.<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; My question is -- have I overlooked some clever subtlety here<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; that<br>
&gt;&gt; &gt; &gt; makes<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; split-for-body necessary, or is it usually easier to just<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; decompose<br>
&gt;&gt; &gt; &gt; pre<br>
&gt;&gt; &gt; &gt; &gt; &gt; ...<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; result rather than bothering with split-for-body?<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; Carl Eastlund<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt; _________________________<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;   Racket Developers list:<br>
&gt;&gt; &gt; &gt; &gt; &gt; &gt;   <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt; &gt; &gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt; _________________________<br>
&gt;   Racket Developers list:<br>
&gt;   <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
&gt;<br>
<br>
</div></div></blockquote></div><br></div>