Let's say I have a macro (define/custom (name (arg type) ...) body ...) that among other things expands to (define (name arg ...) body ...). That's easy.
Now, I want to allow not only (arg type) to be passed as parameter, but simply arg. Alright, so I write a second clause, where (define/custom (name arg ...) body ...) is expanded to (define (name arg ...) body ...). Also easy.
But with such solution, either all arguments are with type, or none of them are. How can I allow mixing the two options in same syntax list (or whatever the ... is called)? How can I make, so that eg. (define/custom (name arg1 (arg2 type2)) #f) gets appropriately expanded to (define (name arg1 arg2) #f)? The intuition is to use a helper macro, which would expand (helper a) to a, and (helper (a b)) to a, and make (define/custom (name arg_or_arg+type ...) body ...) expand to (define (name (helper arg_or_arg+type) ...) body ...), but as you probably knew and guesses where this is coming, this doesn't work, because define expansion takes place before helper expansion.
You can do this with a helper macro that loops through each "arg-or-arg+type" and transforms them into
(arg type)to be consistent.First, I recommend defining a core version of the macro that only works on the consistent
(arg type)version of things:Then you can define helper macro that deals with 2 lists of input args: one for consistent
(arg type)things, and another for "arg-or-arg+type" things. Example usage might look like:As it loops through
arg-or-arg+type ..., it will move them into the(arg type) ...list. Whenarg-or-arg+type ...is empty, it's done and puts all the(arg type)things into a call todefine/custom-core.This relies on
argbeing equivalent to(arg any).Then, all that's left is the outward-facing
define/custommacro to call the helper macro. It can pass an emptyarg+typelist and pass the args into thearg-or-arg+typeplace for the helper to deal with.