First of all, I'm noticing your expansion is suspicious in a couple of ways.
The case itself should be a piece of generated code:
-# mac (foo x) :case nil
+# mac (foo x) :case `nil
- `(if nil
+ `(if ,`nil
I made this same change back in http://arclanguage.org/item?id=18050 where I said "What you really needed was this." It might have looked like I was only talking about the expansion result, but the usage syntax changes too.
Also, this seems to be unrelated to the issue you're having, but I just realized you need to be careful about variable scope. What if the original definition said "mac (foo x)" but the extension said "mac (foo y)"? I recommend putting in a form that binds the right variables:
(Careful though, because this (with ...) form will add a layer of indirection to caller_scope.)
---
To address the issue you're encountering, yes, every case will expand at every call site, even if there's no intuitive need for it to expand there. It can't branch on a decision that hasn't been made until run time, unless you're willing to use the full power of fexprs. (I assume you're trying to maintain a semblance of stage separation, or you wouldn't distinguish macros from functions.)
Keeping this stuff in mind, you can write your code so that it doesn't give you that error:
# Simplified expansion of:
# mac (foo x)
# `(+ ,x 1)
#
# mac (foo x) :case `nil
# if acons.x
# `(list ,car.x)
# `(err "I hope this code will never be reached.")
mac (foo x)
`(if ,(with (x x)
`nil)
,(with (x x)
(if (acons x)
`(list ,(car x))
`(err "I hope this code will never be reached.")))
,`(+ ,x 1))
"What if the original definition said "mac (foo x)" but the extension said "mac (foo y)"? I recommend putting in a form that binds the right variables"
Whoops, that (with ...) stuff isn't ideal because it leaves the outer variables in scope. That is, if the original definition has a parameter called "list", an extension will see that binding even if it uses a different name for the same parameter, so it might try to call the global 'list and be surprised.
I suppose I recommend doing this instead, where g123-args is a gensym:
mac (foo . g123-args)
`(if ,(apply (fn (x)
`nil)
g123-args)
,(apply (fn (x)
(if (acons x)
`(list ,(car x))
`(err "I hope this code will never be reached.")))
g123-args)
,(apply (fn (x)
`(+ ,x 1))
g123-args))
Er, and there's one more change I should probably make here so you can actually use this for what you're trying to do.
let g1-old foo
(mac (foo . g2-args)
`(if ,(apply (fn (x)
`nil)
g2-args)
,(apply (fn (x)
(if (acons x)
`(list ,(car x))
`(err "I hope this code will never be reached.")))
g2-args)
(,g1-old ,@g2-args)
; or in Arc, ",(apply rep.g1-old g2-args)"
)