"If calling 'car on a non-cons gives me a value that I can't tell was caused by an error, then if I want a leak-proof abstraction I'll do anything I can to detect the error in a separate step from calling 'car, just as I would if 'car raised an exception."
Yeah you're right, I was making no sense. Or at least I've forgotten the concrete situation I was (over) reacting to.
Wart does throw a message: 'car of non-cons: 1'. It's just a warning, it doesn't halt execution, but I'm still contradicting myself by that decision.
I'll note that in my code I frequently have to use errsafe, because the thing may not be a cons. For instance, suppose you had a table called "foo". I've been using this pattern a lot recently:
(if (foo:car x) ...)
But that will break if x isn't a cons, so I have to do this:
(if (errsafe:foo:car x) ...)
So I don't think it's necessarily a bad idea for car/cdr to return a value rather than throw an error... but I can see why some people would prefer it to throw an error. For me personally, I think my code would benefit more from car/cdr returning nil, rather than throwing an error.