Arc Forumnew | comments | leaders | submitlogin
2 points by rntz 5623 days ago | link | parent

The fix I'm using for the time being is this:

    diff --git a/ac.scm b/ac.scm
    index 3304953..5263d28 100644
    --- a/ac.scm
    +++ b/ac.scm
    @@ -238,7 +238,7 @@
             ((and (pair? x) (eqv? (car x) 'quasiquote))
              (list 'quasiquote (ac-qq1 (+ level 1) (cadr x) env)))
             ((pair? x)
    -         (map (lambda (x) (ac-qq1 level x env)) x))
    +         (cons (ac-qq1 level (car x) env) (ac-qq1 level (cdr x) env)))
             (#t x)))

     ; (if) -> nil
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:

    arc> `(foo . bar)
    (foo . bar)
    arc> `(foo . ,(join '(x) '(y)))
    (foo x y)
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 really weird 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:

    arc> (let quasiquote 0 (list quasiquote 1))
    (0 1)
    arc> (let assign 0 (list assign 1))
    (0 1)
Intuitively, binding values to special forms seems highly suspect, but there you have it.