Arc Forumnew | comments | leaders | submitlogin
1 point by rntz 5384 days ago | link | parent

Another bug: 'indent-pairs can't handle being presented with a list containing only one element. For an example in the wild, see the source of 'rand-choice:

    arc> src.rand-choice
    (from "arc.arc")
    (mac rand-choice exprs
      `(case (rand ,(len exprs))
         Error: "car: expects argument of type <pair>; given 1"
More succinctly:

    arc> (ppr '(case foo ,@(bar baz quux xyzzy plugh very long)))
    (case foo
      Error: "car: expects argument of type <pair>; given 1"
The error lies in 'indent-pairs:

    (def indent-pairs (xs (o col 0))
      (let l (apply max (map len:tostring:print:car (keep [cdr _] pair.xs)))
        (on x pair.xs
            (if (~is index 0)
                (do (prn)
                    (sp col)))
            (let str (tostring:print car.x)
              (if cdr.x
                  (do pr.str
                      (sp:- l len.str -1)
                      (ppr cadr.x (+ col 1 l) t))
                  (do (sp (+ l 1)) ;offending expression
                      pr.str))))))
If 'xs is a list with only one element, then (pair xs) returns a list whose sole element is itself a list of one element. 'l is then the result of applying 'max to an empty list, which is nil. (+ l 1) then becomes (+ nil 1), which errors. One simple solution is to add a preceding 0 to the application of max.

    --- ppr-old.arc 2009-07-28 21:10:49.000000000 +0200
    +++ ppr.arc     2009-07-28 21:10:52.000000000 +0200
    @@ -54 +54 @@
    -  (let l (apply max (map len:tostring:print:car (keep [cdr _] pair.xs)))
    +  (let l (apply max 0 (map len:tostring:print:car (keep [cdr _] pair.xs)))