In principle I like this #:ec idea, but I would feel more comfortable if you explored the whole range of for loops and their interactions with this new feature. -- Matthias
On Jun 28, 2014, at 6:54 AM, Jay Kominek wrote: > On Fri, Jun 27, 2014 at 8:40 PM, J. Ian Johnson <i...@ccs.neu.edu> wrote: >> One is that #:when in for-clauses allows you to skip iterations, but you >> want it in the body. This is a cosmetic difference that you can get around >> by doing #:when (begin imperative-stuff-before-guard guard). If you want ecs >> to escape an entire for loop, that's what #:break is for. If you want ecs to >> escape even more for loops, well, that is an unplanned but a possibly useful >> feature for nested for loops. > > Yes, #:when gets frustratingly close, but if > imperative-stuff-before-guard does something expensive (fetches the > ith web page, or what have you), I've got to repeat it in the body if > I actually want to use the value. Same issue with #:break and all the > other guards. > > If I end up wanting #:when, #:break, and the body of the expression to > all make use of some expensive value, I'm stuck reproducing it. (Or > setting up some previous loop to make a bunch of promises that I can > force... bleh.) > > Would I have more luck selling folks on some sort of #:let [id > val-expr] construct that could mix in with the sequences? That'd get > me most of what I was going for, and it is probably(?) a lot more > obvious how it should behave. > >> The other is that this is not Rackety and thus not natively supported for >> the same reason there are no "return" statements. The for macros are so much >> more than Python's for - they can produce values. Don't throw everything >> into the void :) > > Sorry, I should've put more than a moment's effort into my example. I > specifically tried to ensure that this can do more than Python's break > & continue! In fact, this allows poor boring "for" who normally > produces nothing but void to produce a useful value. Here are some > more examples, again contrived because I'm trying to keep them short, > but hopefully making more apparent the advantage over simple break & > continue: > > (for (#:ec break > [x (in-range 0 10)]) > (when (= x 2) > (break "found it!")) > (printf "~a~n" x)) > > 0 > 1 > "found it!" > > > (for/fold ([x 0] [y 0]) > (#:ec break > [i (in-range 0 10)] > #:ec continue) > (when (= i 3) > (continue (+ x 1000) (+ y 1000))) > (when (= i 7) > (break (exact->inexact x) y)) > (values (add1 x) (add1 y))) > > 1006.0 > 1006 > > The inner escape continuation passes its values along to the next > iteration, while the outer one can return values for the entire > expression. And of course, it can be interleaved between sequences, > just like #:when and friends. > > I was allowing the use of the continuations without arguments so that > there'd be a more obvious translation from languages with wimpy > control statements, but they raise the issue of what values should be > used by default. > > (And to reiterate the current inadequacies, it doesn't behave at all > properly with for/list, for/vector or for/set.) > > Thanks for looking. > > -- > Jay Kominek > > _________________________ > Racket Developers list: > http://lists.racket-lang.org/dev _________________________ Racket Developers list: http://lists.racket-lang.org/dev