The reason why the first example works is that `(foo (,a . ,b)) is syntax for (quasiquote (foo ((unquote a) unquote b))), which doesn't contain dotted lists.
I'll try my hand at fixing this when I have the time.
This does weird things to quasiquote in medial position (see below), but IMO
doing that is suspect, and it fixes both the "can't use dotted lists in
quasiquoted expressions" bug and the "dotted unquote only works sometimes" bug:
For those interested, more detail follows on the corner cases of quasiquotation
in the underlying mzscheme. As it turns out, mzscheme (possibly schemes in
general) has reallyweird quasiquoting rules. Consider the following:
; we begin with normal examples
> (define x 'X)
> (define X 'value)
> `(a ,x)
(a X)
> `(a `(b ,,x))
(a (quasiquote (b (unquote X))))
; quasiquoting in dotted position has interesting results:
> `(a . `(b ,x))
(a quasiquote (b (unquote x)))
> `(a . `(b ,,x))
(a quasiquote (b (unquote X)))
> (eval `(list . `(b ,,x)))
quasiquote: bad syntax in: quasiquote
; unquoting in terminal position results in splicing, as expected
> '`(a . ,x)
(quasiquote (a unquote x))
> `(a . ,x)
(a . X)
> `(a . ,(list x))
(a X)
; unquotes in medial positions error, which is good:
> `(a unquote x X)
stdin::1874: unquote: expects exactly one expression at: (#<syntax::1879> #<syntax::1887> #<syntax::1889>) in: (quasiquote (a unquote x X))
; however, the same is not true of quasiquotes in medial position.
> `(a quasiquote b c)
(a quasiquote b c)
; in fact, quasiquotes in medial position require increased unquoting of
; subsequent elements - quasiquoting in dotted position, above, is a special
; case of this
> `(a quasiquote ,x ,x)
(a quasiquote (unquote x) (unquote x))
> `(a quasiquote ,,x)
(a quasiquote (unquote X))
; however, if the list following quasiquote is dotted, this does not happen...
> `(a quasiquote ,x . y)
(a quasiquote X . y)
; ... UNLESS the dot comes immediately after the quasiquote
> `(a quasiquote . ,,x)
(a quasiquote unquote X)
Since arc quasiquotation compiles down into scheme quasiquotation, I'm unsure of
the best way to handle all this at the arc level. What should all of these
corner cases mean in arc? Moreover, consider that all uses of medial quasiquote
(eg '(list quasiquote 2)) result in syntax errors when evaluated in scheme, but
in arc, evaluating eg '(list quasiquote 2) is not a syntax error, and will
depend upon the value of 'quasiquote; in fact, the same is true of most special
forms:
The answer is that arc quasiquotation gets compiles down to scheme quasiquotation, and mzscheme's quasiquote handler understands (... unquote bar) to be equivalent to (... (unquote-splicing bar)). Since the arc compiler doesn't understand unquotes of this style, you'll only get the correct results when the expression unquoted is the same in arc and scheme - ie: it's either a literal, or it's a local variable. For example:
; this works because the local 'x in arc is compiled to 'x in scheme as well
arc> (let x 0 `(a . ,x))
(a . 0)
; this works because '+ in scheme adds numbers just as in arc
arc> (let x 0 `(a . ,(+ x 1)))
(a . 1)
; the following examples do not work
arc> (let x '(b) `(a . ,(join x '(c))))
Error: "reference to undefined identifier: join"
arc> (let x '(b) `(a . ,(+ x '(c))))
Error: "+: expects type <number> as 1st argument, given: (b . nil); other arguments were: (c)"
arc> (= x '(b))
(b)
arc> `(a . ,x)
Error: "reference to undefined identifier: x"
It's funny how a surface bug turns out to lead to something deeper in this way. I feel like Alice down the rabbit hole.