Oh well, since everyone is at it, here's my version that no-one asked for. It's similar to parendown, but uses a more standard (but also specific) macro `cond/else` from https://github.com/Metaxal/bazaar/blob/master/cond-else.rkt :
(*cond/else* [(*not* (foo? x)) #f] #:else (*define* y (bar x)) (*define* z (jazz x y)) #:cond [(*not* (loopy? z)) #f] #:else (*define* a (yowza z)) #:cond [(*not* (string? a)) (error 'ugh)] #:else (*define* b (bonkers a)) #:cond [(number? (hoop x b)) (*define* ...)] #:else (*error* 'um)) I find the different coloration of the keywords helpful to parse the code too. Now waiting for more original solutions to this problem :-) On Sat, Oct 2, 2021 at 9:09 PM [email protected] <[email protected]> wrote: > Here's my solution: > > (define/guard (f x) > (guard (foo? x) else > #false) > (define y (bar x)) > (define z (jazz x y)) > (guard (loopy? z) else > #false) > (define a (yowza z)) > (guard (string? a) else > (error 'ugh)) > (define b (bonkers a)) > (guard (number? (hoop x b)) else > (error 'um)) > (define ...)) > > It uses a `guard` macro I wrote and talked about in this thread > <https://groups.google.com/g/racket-users/c/H-EppBmQ7oU>. > On Friday, October 1, 2021 at 12:53:25 PM UTC-7 [email protected] > wrote: > >> On Fri, Oct 01, 2021 at 02:32:52PM -0400, David Storrs wrote: >> > On Fri, Oct 1, 2021 at 11:58 AM Hendrik Boom <[email protected]> >> wrote: >> > >> > > On Fri, Oct 01, 2021 at 02:22:14PM +0000, Jesse Alama wrote: >> > > > Hello, >> > > > >> > > > Have you ever wished you could do a C-style return in the middle >> > > > of a block of Racket code? When you're in the heat of things with >> > > > a complicated problem where input values need a fair amount of >> > > > multi-stage extraction and validation, using cond quickly pulls >> > > > code to the right. My procedure is: >> > > > >> > > > * cond/case. In each branch: >> > > > * Define some new values safe in the knowledge of where you are >> > > > (extract) and perhaps check them, if necessasry (validate) >> > > > * Make sure you have an else branch. >> > > > * return to 1 and repeat as many times as necessary. >> > > > >> > > > The result: >> > > > >> > > > (cond [(foo? x) >> > > > (define y (bar x)) >> > > > (define z (jazz x y)) >> > > > (cond [(loopy? z) >> > > > (define a (yowza z)) >> > > > (cond [(string? a) >> > > > (define b (bonkers a)) >> > > > (cond [(number? (hoop x b)) >> > > > (define ...)] >> > > > [else >> > > > (error 'um)])] >> > > > [else >> > > > (error 'ugh)])] >> > > > [else #f])] >> > > > [else #f]) >> > > >> > > >> > I'm presuming that this code should either return #f, return a >> calculated >> > value, or raise an exception. If so, here's a version that runs in >> plain >> > racket that I find pretty easy to read. It has the advantage that the >> > 'return #f' parts aren't way far away from what causes them. >> > >> > (with-handlers ([false? identity] ; return #f >> > [any/c raise]) ; re-raise everything else >> > (let* ([x (if (foo? x) >> > x >> > (raise #f))] >> > [z (jazz x (bar x))] >> > [a (if (loopy? z) >> > (yowza z) >> > (raise #f))] >> > [b (if (string? a) >> > (bonkers a) >> > (error 'ugh))]) >> > (if (number? (hoop x b)) >> > 'all-good >> > (error 'um)))) >> >> Yes. But different semantics if bar, yowza, and bonkers have side >> effects. >> If they don't, they're quite equivalent. >> >> -- hendrik >> >> > >> > If instead you want to return the exn that comes from error instead of >> > re-raising it then you can do that by removing the false? clause from >> the >> > with-handlers. NOTE: You should re-raise exn:break since otherwise the >> > user cannot ^C the program. >> > >> > (with-handlers ([exn:break? raise] >> > [any/c identity]) >> > ...put the let* code here...) >> > >> > -- >> > 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 [email protected]. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/racket-users/CAE8gKodxas7jtze%2BttcFA%2BG0ATKUFZD3rhK%2B%3Dn2U1md1zQPJSg%40mail.gmail.com. >> >> > -- > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/racket-users/262c0b9d-6d51-4e03-adcf-0efa3fb76f61n%40googlegroups.com > <https://groups.google.com/d/msgid/racket-users/262c0b9d-6d51-4e03-adcf-0efa3fb76f61n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CABNTSaGYaDZrYpUVbpXOccvPTvwhXKu7wDkVSvbHtqu47OtvKg%40mail.gmail.com.

