Arc Forumnew | comments | leaders | submitlogin
2 points by rocketnia 5503 days ago | link | parent

One thing that bugs me sometimes with negative indexing is that 0 doesn't always wrap around the way I expect it to. This comes up when I'm trying to write code like (cut seq start (- (some-calculation))). Here's a hack that gives the behavior I expect:

  (let old-cut cut
    (def cut (seq start (o end len.seq))
      (let length len.seq
        (if (< start 0)    (++ start length))
        (if (< end start)  (++ end length))
        (unless (<= 0 start end length)
          (err:+ "cut: The sign-adjusted indices were out of range or "
                 "backwards."))
        (old-cut seq start end))))
  
  ;? (include "arctap.arc")
  ;?
  ;? (test-iso "cut should work for negative start and 0 end"
  ;?   '(2 3 4)
  ;?   (cut '(1 2 3 4) -3 -0))
  ;?
  ;? (test-iso "cut should work for positive start and 0 end"
  ;?   '(2 3 4) 
  ;?   (cut '(1 2 3 4) 1 -0))
  ;?
  ;? (test-iso "cut should assume 0 start and 0 end are same position"
  ;?   '()
  ;?   (cut '(1 2 3 4) 0 -0))
(I haven't actually used arctap.arc yet, so I'm just parroting you in that section and hoping it helps.)

Unfortunately, if I have code that does something like (cut '(1 2 3 4) ref!start-trim (- ref!end-trim)), then this approach fails too (because of that double-zero assumption). In that case, I suppose I'd just resort to writing another function as a workaround.

  (def cut-sides (seq front back)
    (cut seq front (- len.seq back)))


1 point by akkartik 5502 days ago | link

I like your approach; here's mine in similar style:

    (let old-cut cut
      (def cut (seq start (o end))
        (old-cut seq
                 (if (start < 0)
                   (+ (len seq) start)
                   start)
                 end)))
I'm having a hard time assessing the use case, though. Are you trying to avoid +1, etc.?

Also, sometimes the calculations are just as easy to do in positive indices.

-----

1 point by rocketnia 5502 days ago | link

I've searched through lots of the code I've written, and as it turns out, I haven't found one case where being having 0 as a "negative" index would have helped. :-p So while I still like it better my way, I don't have a real use case to show.

From another standpoint, maybe it's just that I don't want to rely on the behavior of something like (cut '(1 2 3 4) 3 1), where the indices are reversed. If I can exempt (cut '(1 2 3 4) -3 0) from that error/undefined zone (in a way that's smoothly consistent with cut's other behavior), then cut may be slightly more useful to me at some point. But yeah, I don't know exactly when it would pay off or whether some other behavior would be better.

-----