Wow, these are a lot of great responses. First of all, *awesome* job Ryan. That implementation is exactly what I needed to figure out. I'm definitely starting there first.
> Are you looking for `let/ec`? I'd forgotten about that one. That has the *syntax* I want. However my issue with continuation-based approaches isn't the syntax, or even the performance. It's the semantics. What if someone writes code like this? (guarded-block (define x (random 10)) (thread (lambda () (guard (even? x) else #false) ...))) If I implemented guarded-block in terms of let/ec, then what does this code even *do*? I honestly don't know. It would probably run without error and do... something. I am extremely sure that regardless of what it did, it would be confusing and it wouldn't solve any problem I had. I just flat out don't want to allow this or any related nonsense, such as: ; Aliasing (define return guard) ; Higher-order usage (map guard (some-list ...)) ; Capturing via closure (guarded-block (define (check-foo x) (guard (foo? x) else #false)) (check-foo ...) ...) ; Capturing via mutation (set! previous-guard guard) ; Oh great, now I have to think about even more continuation jumps (dynamic-wind (lambda () (guard ...)) (lambda () ...) (lambda () ...)) There might be valid use cases for some of these, but I certainly don't understand those use cases well enough to commit to a semantics for them. As for why not use condd, cond/else, or parendown: because they don't look right. Specifically, I often write code like this: (define (f x y z) ... a few lines of checking preconditions ... ... a dozen or two lines of actual useful logic ...) I don't want to indent the useful logic a bunch. That's the most important part of the function - the preconditions are minor things that you should be able to skim over and forget about. If my functions without preconditions look wildly different from my functions with preconditions, it becomes difficult to tell what the main focus of a function is. Not to mention that going from zero preconditions to one (and from one to zero) now introduces a bunch of busywork. On naming: I like the symmetry between return-when / return-unless and when / unless, but the problem is the word "return". If I call it a return statement, people will naturally expect this to work: (define (first-owl animals) (for ([animal animals]) (return-when (owl? animal) animal))) I don't want to have to explain why that doesn't work forty times. The names guard-when and guard-unless are kind of ambiguous; does "guard-when" mean "when this condition is true, enter this guard block and escape" or does it mean "guard the function with this condition, if it fails enter the block and escape". Does "guard" mean "prevent this condition" or "ensure this condition"? Having two forms means you have to remember which one means which and figure out a way to keep them straight. I'd rather just have one form so there's only one way to do it, and you can teach yourself that "ah yes, guard always means 'make sure this is true'". -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/3607a1a0-e303-4d9d-a62e-c958712aa2c8n%40googlegroups.com.