Arc Forumnew | comments | leaders | submitlogin
3 points by Oscar-Belletti 3033 days ago | link | parent

The iter macro doesn't work: when it reaches the last iteration it calls next which increases i to (len list) and then tries to get that element, causing an error.

Edit:

The iter macro has another problem: it evaluates list to many times:

    arc>(= counter 0)
    arc>(iter a (map [do (++ counter) _] '(1 2 3 4)) (pr a))
    1234nil
    arc>(/ counter 4)
    11
Note: to make the iter macro not throw any errors I modified the while:

    (while (< ,i (len ,list))
      (= ,var (,list ,i))
      ,@body
      (++ ,i))))))


3 points by mpr 2995 days ago | link

Thanks for pointing that out. I think I fixed both those problems here.

    (mac iter (var list . body)
      (let i (uniq)
        `(if (is nil ,list)
           nil
           (withs (els ,list
                   ,i 0
                   ,var (els ,i)
                   next (fn () (++ ,i)))
             (while (< ,i (len els))
               (= ,var (els ,i))
               ,@body
               (next))))))

-----

3 points by Oscar-Belletti 2994 days ago | link

Now the next function returns the next index and not the next element. iter still evaluates list two times and els can cause variable capture.

    arc> (mac iter (var list . body)
          (let i (uniq)
            `(if (is nil ,list)
               nil
               (withs (els ,list
                       ,i 0
                       ,var (els ,i)
                       next (fn () (++ ,i)))
                 (while (< ,i (len els))
                   (= ,var (els ,i))
                   ,@body
                   (next))))))
    #(tagged mac #<procedure: iter>)
    arc> (iter a '(1 2 3) (prn a))
    1
    2
    3
    nil
    arc> (iter els '(1 2 3) (prn els))
    Error: "car: contract violation\n  expected: pair?\n  given: 1"
    arc> (iter a '(a b c d) (prn a ", " (next)))
    a, 1
    c, 3
    nil
This should fix the problems:

    (mac iter (var lst . body)
        (w/uniq (i elst)
          `(let ,elst ,lst
            (if (is ,elst nil)
              nil
              (withs (,i 0
                      ,var (,elst ,i)
                      next (fn ()
                             (++ ,i)
                             (= ,var (,elst ,i))))
                (while (< ,i (len ,elst))
                  (= ,var (,elst ,i))
                  ,@body
                  (++ ,i)))))))

-----

3 points by mpr 2994 days ago | link

Thanks again!

-----

2 points by Oscar-Belletti 2993 days ago | link

My pleasure

-----