I guess I'll pile on too. My approach was `let++` which I rename to `let*`
because (I think) it is backwards compatible. The pattern for early exit is
`#:break (when test-expr result-expr)` so the previous example would look
like this:
(let* (#:break (when (not (foo? x))
#f)
[y (bar x)]
[z (jazz x y)]
#:break (when (not (loopy? z))
#f)
[a (yowza z)]
#:break (when (not (string? a))
'ugh)
[b (bonkers a)]
#:break (when (not (number? (hoop x b)))
'um))
(list x y z a b))
In practice, this allowed me to rewrite a lot of functions that were highly
nested into a single let++ form.
The other feature of let++ is that it also supports let-values. (Having to
nest "let, then let-values, then let again" was another reason my code
would get too indented for my taste.)
Implementation: https://github.com/default-kramer/fission-flare/blob/
master/src/util/let%2B%2B.rkt
Example: https://github.com/default-kramer/fission-flare/blob/
d6e71353dbd53e0d00d71e0e7911caca6455c4db/src/core/state.rkt#L266
On Sunday, October 3, 2021 at 9:45:28 AM UTC-5 [email protected] wrote:
> 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/d550bbe5-39f6-48f6-9c16-01e7683eb816n%40googlegroups.com.