Having cp_r return the paths copied is kind of a neat idea. The split path wouldn't be my first choice, since I think wherever possible, when we're dealing with commonly used utility functions, you should be able to understand why the interface is the way it is without having to know too much about what the callers are doing (to maximize reusability.) And all of the other functions that deal with paths, work with strings, so it's weird that we'd use a different representation here (list of path components) -- it means the output of cp_r couldn't be passed into other path manipulation functions.

__All of that said__ I think this is totally fine! When writing code like this I think we should do whatever is expedient and not stress about it too much. It's really easy to refactor later. I don't think there's any need to change it, I just wanted to share my thinking.