[racket-users] Re: Escape continuations for fussy code

2021-10-21 Thread Ryan Kramer
Good question. I know I have done exactly that in the past, but I guess I 
just forgot about that pattern in my more recent code. Other possible 
reasons include "because I don't like the unnecessary parens around a 
single id" and "because I like the indentation of let* (4 chars) much 
better than let*-values (11 chars) and want to delay introducing 
let*-values until it becomes necessary."

On Wednesday, October 20, 2021 at 7:54:37 PM UTC-5 gneuner2 wrote:

> On Wed, 20 Oct 2021 09:44:42 -0700 (PDT), Ryan Kramer
>  wrote:
>
> > :
> >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.)
> > :
>
> Possibly a stupid question, but ...
>
> What causes you to /have to/ 'nest "let, then let-values, then let
> again"'? Assuming no intervening body code, a single let*-values
> could cover all of it (with the same semantics).
>
>

-- 
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/f7839fa2-c355-4165-bbe0-49e3e028ebd5n%40googlegroups.com.


[racket-users] Re: Escape continuations for fussy code

2021-10-20 Thread George Neuner
On Wed, 20 Oct 2021 09:44:42 -0700 (PDT), Ryan Kramer
 wrote:

> :
>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.)
> :

Possibly a stupid question, but ...

What causes you to /have to/  'nest "let, then let-values, then let
again"'?   Assuming no intervening body code, a single let*-values
could cover all of it (with the same semantics).

-- 
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/pjd1ngddbcqpak5ke8720uddit5h254vmk%404ax.com.


Re: [racket-users] Re: Escape continuations for fussy code

2021-10-20 Thread Ryan Kramer
 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 laurent...@gmail.com 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 jackh...@gmail.com  
> 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 
>> .
>> On Friday, October 1, 2021 at 12:53:25 PM UTC-7 hen...@topoi.pooq.com 
>> 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  
>>> wrote: 
>>> > 
>>> > > On Fri, Oct 01, 2021 at 02:22:14PM +, 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 

Re: [racket-users] Re: Escape continuations for fussy code

2021-10-03 Thread Laurent
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 jackh...@gmail.com 
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
> .
> On Friday, October 1, 2021 at 12:53:25 PM UTC-7 hen...@topoi.pooq.com
> 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 
>> wrote:
>> >
>> > > On Fri, Oct 01, 2021 at 02:22:14PM +, 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 racket-users...@googlegroups.com.
>> > 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 racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/262c0b9d-6d51-4e03-adcf-0efa3fb76f61n%40googlegroups.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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on 

Re: [racket-users] Re: Escape continuations for fussy code

2021-10-02 Thread jackh...@gmail.com
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 
.
On Friday, October 1, 2021 at 12:53:25 PM UTC-7 hen...@topoi.pooq.com 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  
> wrote:
> > 
> > > On Fri, Oct 01, 2021 at 02:22:14PM +, 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 racket-users...@googlegroups.com.
> > 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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/262c0b9d-6d51-4e03-adcf-0efa3fb76f61n%40googlegroups.com.


Re: [racket-users] Re: Escape continuations for fussy code

2021-10-01 Thread Hendrik Boom
On Fri, Oct 01, 2021 at 02:32:52PM -0400, David Storrs wrote:
> On Fri, Oct 1, 2021 at 11:58 AM Hendrik Boom  wrote:
> 
> > On Fri, Oct 01, 2021 at 02:22:14PM +, 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 racket-users+unsubscr...@googlegroups.com.
> 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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/20211001195320.4wtga4tjwgo75jhz%40topoi.pooq.com.


Re: [racket-users] Re: Escape continuations for fussy code

2021-10-01 Thread David Storrs
On Fri, Oct 1, 2021 at 11:58 AM Hendrik Boom  wrote:

> On Fri, Oct 01, 2021 at 02:22:14PM +, 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

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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKodxas7jtze%2BttcFA%2BG0ATKUFZD3rhK%2B%3Dn2U1md1zQPJSg%40mail.gmail.com.


[racket-users] Re: Escape continuations for fussy code

2021-10-01 Thread Hendrik Boom
On Fri, Oct 01, 2021 at 02:22:14PM +, 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])

the Racket package parendown (see 
https://docs.racket-lang.org/parendown/index.html ) can reduce this a 
lot:

(if (not #/ foo? x) #f
#/ begin
  (define y (bar z))
  (define z (jazz x y))
#/if (not #/ loopy? z) #f
#/ begin
  (define a (yowza z))
#/if (not (string a)) (error 'ugh)
#/begin
  (define b (bonkers a))
#/if (not (number? (hoop x b))) (error 'um)
  (define ...)
)

Or, using let instead of define

(if (not #/ foo? x) #f
#/ let ((y (bar z)))
#/ let ((z (jazz x y)))
#/ if (not #/ loopy? z) #f
#/ let ((a (yowza z)))
#/ if (not (string a)) (error 'ugh)
#/ let ((b (bonkers a)))
#/ if (not (number? (hoop x b))) (error 'um)
#/ let ((...))
  -- and presumably you wanted to do someting inside all there define's
)

Is this clearar?

There remain 
  * the ugly extra parentheses aroung each let-pair,
which is an unnecessary tradition once you use parendown,
and
  * the 'not's after the 'if's.
which could be resolved with a three-argument check operator:  
(check requirement errormessage stufftodoifok) -- essentially 
an argument-reversed if.

but this is enough to eliminate the push off the right side of the page.

A heuristic when programming this way:
  When a function takes several arguments, define it so that the 
  argument that is likely to be textually longer is at the end.

-- hendrik

> 
> That's an awful lot of whitespace. We're getting dragged to the
> right. Pretty soon we're dealing with lines that have three dozen
> spaces at the front or more.
> 
> At times, it can even get a bit silly just how deeply nested code
> can get. It can even degrade program comprehension for you &
> others. It can even impede your own coding by requiring you to
> scroll up to mentally re-construct the state you're in.
> 
> This isn't necessarily a problem with Racket. I think it reflects
> of the inherent fussiness of some problems. And certainly, you
> can reformat the code differently to make the problem somewhat
> less severe.
> 
> Nonetheless, I certainly have found myself envying those working
> in other languages where they can just bail out of a complicated
> computation by just returning a value. I mean, sure, I could
> raise an exception and bail out that way, right? It turns out
> there's a way: escape continuations. They permit a kind of
> C-style return-y programming in Racket. I've got an article (
> https://click.convertkit-mail.com/92u52qdvngtnh535n9s9/3ohphkhq39xwevtr/aHR0cHM6Ly9saXNwLnNoL2VzY2FwZS1jb250aW51YXRpb25zLWZvci1mdXNzeS1jb2RlLw==
> ) up introducing escape continuations and give a simple
> real-world example from web programming.
> 
> Happy hacking,
> 
> Jesse
> 
> Unsubscribe (
> https://unsubscribe.convertkit-mail.com/92u52qdvngtnh535n9s9 ) |
> Update your profile (
> https://preferences.convertkit-mail.com/92u52qdvngtnh535n9s9 ) |
> Moltkestrasse 3d, Mainz, RP 55118

-- 
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/20211001155821.hdbqgzfkn6gfjw67%40topoi.pooq.com.