If that function is good or bad depends on the problem to solve at hand. I.e. when you are iterating through a list you will probably use (dolist (x mylist)...) which would adjust to the length automatically. If you would want to pick the last element you would use (last mylist) or (mylist -1) etc..
What I want to say is, in most cases the length of a list is not really of concern when the code you write can adapt to it and refer to positions in relative terms. When the length is important and you do random access into different positions in the list then arrays with bounds error control may be the better solution.
Regarding car/cdr recursion. This type of pattern is very common in traditional LISP but not seen frequently in newLISP code. newLISP code tends to use recursion a lot less and relies much more on iterative code.
But still if your program solution needs it you can employ cdr/car recursion with the equivalent first/rest and you can adjust the default stack size of 1024 to any number you wish. I.e. for the Ackerman benchmark to 100000 here:
http://newlisp.org/benchmarks/ackermann.newlisp.txt . I think apart from this benchmark I have never felt the need.
To sum it up: newLISPs programming style is somewhere in the middle between traditional, more functional LISP style and the more procedural style of scripting languages like Perl or Python.
Last not least, welcome to the group Dmi, I hope you have fun with newLISP and it can help you with you programming tasks.
Lutz