Arc Forumnew | comments | leaders | submitlogin
Bug in ++?
8 points by akkartik 5401 days ago | 8 comments

    arc> (= n 1)
    1
    arc> (++ n)
    2
    arc> ++.n
    #<procedure: get>
Or did I miss the memo? :)


4 points by rntz 5401 days ago | link

Not a bug in '++, a bug in the ssyntax expansion process:

    arc> (ssexpand '++.n)
    .n
    arc> (ssexpand '.n)
    (get n)
Infix + triggers ssyntax for ac-andf - even+odd expands to (andf even odd), for example. However, the expander doesn't handle +'s in non-medial position very well - it just cuts them out:

    arc> (ssexpand '++foo)
    foo
Since medial + is checked before medial dot in ssyntax expansion, this leads '++.n to expand to '.n and thence to (get n).

-----

4 points by rntz 5401 days ago | link

So it turns out '+ and '++ are actually special-cased in the ssyntax expansion process. From ac.scm:

    (define (ssyntax? x)
      (and (symbol? x)
           (not (or (eqv? x '+) (eqv? x '++) (eqv? x '_)))
           (let ((name (symbol->string x)))
             (has-ssyntax-char? name (- (string-length name) 1)))))
This is somewht ugly IMO, but it does mean that merely switching the order in which '. and '+ are ssexpanded fixes this particular bug:

    diff --git a/ac.scm b/ac.scm
    index 3304953..739a4f2 100644
    --- a/ac.scm
    +++ b/ac.scm
    @@ -89,9 +89,9 @@

     (define (expand-ssyntax sym)
       ((cond ((or (insym? #\: sym) (insym? #\~ sym)) expand-compose)
    +         ((or (insym? #\. sym) (insym? #\! sym)) expand-sexpr)
              ((insym? #\+ sym) expand-and)
          ;   ((insym? #\_ sym) expand-curry)
    -         ((or (insym? #\. sym) (insym? #\! sym)) expand-sexpr)
              (#t (error "Unknown ssyntax" sym)))
        sym))
Albeit it does change the semantics of some "correct" uses of ssyntax slightly (though not in a way I'd expect anyone to rely on); for example, 'foo+bar.baz expands to '(andf foo (bar baz)) under arc3, but expands to '((andf foo bar) baz) with this patch applied.

-----

3 points by pg 5399 days ago | link

Will fix.

-----

5 points by pg 5394 days ago | link

Looks like the answer is to use & instead of +. I like the look of + better, but I can tell people are going to want to use it in names.

-----

1 point by akkartik 5401 days ago | link

Ah, thanks. So this is a known problem?

-----

1 point by waterhouse 5398 days ago | link

I've noticed that making names with + in them doesn't work the way it should. Including in the release of arc3 that I downloaded ten minutes ago, just to check if it was still there.

  arc> (def 1+ (x) (+ x 1))
  #<procedure: 1+>
  arc> (1+ 2)
  Error: "Function call on inappropriate object 1 (2)"
  arc> 1+
  1
  arc> (def one-plus (x) (+ x 1))
  #<procedure: one-plus>
  arc> (one-plus 2)
  3
As you can see, when I changed the name but left everything else the same, it worked. Therefore, the name is the problem. Here is another example.

  arc> (mac ++mod (n m (o d 1)) `(= ,n (mod (+ ,n ,d) ,m)))
  #3(tagged mac #<procedure>)
  arc> ++mod
  #<primitive:modulo>
  arc> (= x 1)
  1
  arc> (++mod x 5 10)
  Error: "modulo: expects 2 arguments, given 3: 1 5 10"
  arc> (mac inc-mod (n m (o d 1)) `(= ,n (mod (+ ,n ,d) ,m)))
  #3(tagged mac #<procedure>)
  arc> inc-mod
  #3(tagged mac #<procedure>)
  arc> (inc-mod x 5 10)
  1

-----

1 point by thaddeus 5398 days ago | link

I don't think this is a bug, I think it's a sacrifice pg is making for the sake of using the '+' as a special operator.

Only he can say for sure.

I've just substituted all my '+' names to 'up' and, in my mind, it's just as meaningful.

ie upmod or modup .....

-----

0 points by rs 5394 days ago | link

correcto!

-----