You are welcome to use, reproduce and modify this macro without restriction. Attribution is optional.
My blog post also talks about how the macro works. This is not the most well-explained macro tutorial on the web, but it is a tutorial I wish I had seen a few months ago when I was just barely dipping my toes into syntax-parse. In particular, my post shows how to use ~datum, ..., recursive macros, and describes the inscrutable error if you forget to (require (for-syntax racket/base syntax/parse)), which are all things I really struggled with initially.
In the future I might write another similar post where I show how and why to use #:with, macros in Typed Racket, and #,@#'.
given the prevalence of macros like this, should Rhombus's multi-arm conditional forms allow intermediate defines?
You might want to use (let () expr ...) for your clauses to permit internal definitions (try (cond/define [else (define x 1) (add1 x)]) and compare with Racket's cond).
The pattern matching on define and else could be ~literal, since Racket has bindings for both.
You might want to allow empty (cond/define) as your base case so that (cond/define [1 2]) and similar from Racket work.
It is a good idea. I had written such a macro that is integrated in Scheme+ (cf. 1), the macro is 'condx' named because it allows eXecution of code between each 'cond' clause.
Here is the code of my macro:
(define-syntax condx
(syntax-rules (exec else)
((_) '()) ;; allow no else clause
((_ (else e ...))
(let () e ...))
((_ (exec s ...) d1 ...)
(let () s ... (condx d1 ...)))
((_ (t e ...) tail ...)
(if t
(let () e ...)
(condx tail ...)))))
note that it did not use syntax features because i did not knew too much about that at the time i wrote it, also i wanted to be compatible with Scheme, notonly Racket.
and a running example is:
(define x 1)
(condx ((= x 7) 'never)
(exec
(define y 3)
(set! x 7))
((= y 1) 'definitely_not)
(exec
(set! y 10)
(define z 2))
((= x 7) (+ x y z))
(else 'you_should_not_be_here))
19
condx is a bit different of cond/define but they both have the same goal: make code easier to read, avoid nested cond or let .
Another solution to avoid nested 'cond' and 'if' is to have some 'return' features from a Scheme procedure.
This is for the reason i developped 'return' and return recursively 'return-rec' and the 'def' macro for defining procedures using 'return' or 'return-rec'.
Then you can do all the coding only with 'if' and 'return' without using 'cond', explanation can be found on this page (2) and examples too.
[G]iven the prevalence of macros like this, should Rhombus's multi-arm conditional forms allow intermediate defines?
I’m not sure what that should look like, since we don’t allow arbitrary groups among alts. Putting the intermediate groups inside an alt makes the (apparent) scoping quite confusing. (And intermediate definitions among branches really aren’t usual at all.)