Arc Forumnew | comments | leaders | submitlogin
ASK: Generic reverse function
3 points by archie 2899 days ago | 1 comment
Hi guys!

What's the most idiomatic way to write reverse function in arc that behaves correctly with both lists and strings as input (ie some kind of function that "generically" works well on every "collection" type ?

For example, I want (reverse "qwert") to return "trewq" as well as (reverse (list 1 2 3)) to return (3 2 1).



2 points by rocketnia 2899 days ago | link

If you just want to define a function in one place, this is pretty idiomatic:

  (def reverse (x)
    (if alist.x
      rev.x
      (case type.x
        string  (string:rev:coerce x 'cons)
                (err:+ "Called reverse with " (tostring write.x)))))
If you want to write the different cases in different places in the code, here's the way Anarki (https://github.com/arclanguage/anarki) currently defines `rev`:

  ; in arc.arc
  
  (def rev (xs)
  "Returns a list containing the elements of 'xs' back to front."
    (loop (xs xs acc nil)
      (if (no xs)
        acc
        (recur cdr.xs
               (cons car.xs acc)))))
  
  
  ; in lib/strings.arc
  
  (defextend rev (x)  (isa x 'string)
    (as string (rev:as cons x)))
The community has made several little definition utilities for doing predicate dispatch in Arc, and `defextend` is a good example of those, so it's pretty idiomatic.

-----