Arc Forumnew | comments | leaders | submitlogin
1 point by fallintothis 5599 days ago | link | parent

But of course you can't access tables by index.

You can if they're indexed by integers.

  arc> (on x (obj 0 'a 1 'b 2 'c 3 'd) (prs index x) (prn))
  0 a
  1 b
  2 c
  3 d
  nil
But using each on a table doesn't guarantee this ordering on the keys.

  arc> (each (k v) (obj 0 'a 1 'b 2 'c 3 'd) (prs k v) (prn))
  2 c
  1 b
  0 a
  3 d
  #hash((3 . d) (0 . a) (1 . b) (2 . c))
I wonder why you'd want index bound if you aren't iterating through integer keys in order. Do you have an example? Seems like there should be one, but I can't think of it.


1 point by akkartik 5599 days ago | link

Yeah here's a use case. I wrote a macro called everyp to overlay atop each with a progress indicator. It prints out the number of iterations at the start and a heartbeat every n iterations. I found this bug when I tried to everyp (implemented using on) over a table.

-----

1 point by fallintothis 5599 days ago | link

Interesting. Arc has essentially that, but implements it directly with each:

  (mac noisy-each (n var val . body)
    (w/uniq (gn gc)
      `(with (,gn ,n ,gc 0)
         (each ,var ,val
           (when (multiple (++ ,gc) ,gn)
             (pr ".") 
             (flushout)
             )
           ,@body)
         (prn)
         (flushout))))
I suppose it depends on if you want index to be captured. Since on is used in your version, index is bound within the macro call. So if

  (everyp 2 c "abcd"
    (prn c)
    (++ index))
expands to

  (on c "abcd"
    (when (multiple index 2)
      (prn "heartbeat"))
    (prn c)
    (++ index))
it prints

  heartbeat
  a
  heartbeat
  c
because on captures index. This might be unexpected if you just want heartbeats in an otherwise normal each.

-----

1 point by akkartik 5599 days ago | link

Ah, thanks for the reminder about noisy-each.

-----