For what it's worth, my approach here is pattern-matching. In Lathe Comforts for Racket I implement a macro `expect` which expands to Racket's `match` like so:

If Arc came with a similar pattern-matching DSL and `expect`, we could write this:

(def map1 (f xs)
(expect xs (cons x xs) ()
(cons (f x) (map1 f xs))))

The line "expect xs (cons x xs) ()" conveys "If xs isn't a cons cell, finish with an empty list. Otherwise, proceed with x and xs bound to its car and cdr."