both tail-recursive and non-tail-recursive version