The biggest win, which actually results from a semantic change, is that it becomes possible to cleanly apply a macro to a variable number of arguments. Consider
(apply and (acons x) (car x) lst)
as opposed to
(and (acons x) (car x) @lst)
. The first version is broken: it will be forced to evaluate (acons x), (car x), and lst before applying and to them, which breaks the semantics of and: (acons x) no longer guards against (car x) trying to take the car of a non-list, as everything is evaluated before being passed to apply.
On the other hand, the second version works: the list is spliced in and then the and macro is run as normal. The semantics are preserved here because @, like a macro, expands the code first; nothing is evaluated, and then the and macro runs on its arguments as usual, short-circuiting if (acons x) fails. The variable being spliced is still evaluated, but that is the point of this notation.
As a concrete example (though I think this is generally useful/powerful), partial application then becomes merely
(def par (fn . args)
(fn newargs (fn @args @newargs)))
. If apply were used instead of the splicing @, this would actually break on certain macros as noted above, both causing the abstraction to leak and preventing someone from partially applying and, or, etc.
I had assumed that (and (acons x) (car x) @lst) would expand to (and (acons x) (car x) lst.0 lst.1 ... lst.N), and only then would it expand to (if (acons x) (if (car x) (if lst.0 ...))). In other words, @s are expanded as though they were the outermost macro, not the innermost. That should remove the problem of 'and having to be psychic. Your point about efficiency, however, is a very good one.
As mentioned, the macro expands at compile time, but the value of lst is not available until runtime.
In order to expand a call to 'and with 6 sub expressions into (if e0 (if e1 (if e2 (if e3 (if e4 e5))))), all 6 expressions must be visible at compile time.
Splicing in a list of arguments to a macro will simply never work (except by compiling the code from scratch each time you run it, i.e. limiting yourself to the most inefficient of interpreter techniques)