While it is true that the standard doesn't mandate it, any implementation worth its salt allows you to do tail calls. It's the same with threads; "if you want to write portable Lisp code" you can't expect threads in CL "in general" either. In practice, real-world CL implementations can do threads just fine.