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])
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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20211001155821.hdbqgzfkn6gfjw67%40topoi.pooq.com.

