Hello Dan,
I am not sure whether you refer to my implementation of stack safe recursion or to some other, and I don't know what you really mean by "which point the recursive code was called". The only cases where I encountered this problem was when using stack based recursion, where the stack trace was not long enough to show the origin of the call. This obviously does not happen with stack safe recursion, since it is implemented on the heap. If it were to happen, you would get an OOME rather that a stack overflow.
This said, we often read that the main advantage of recursion is that it allows to handle recursive problems in a very simple way, using code that exactly conforms to the problem description. This is in my opinion not always a good thing and it does not mean that it should be implemented recursively. In the book, I describe a very simple way to implement recursion in a stack safe manner. On the other hand, I do not promote using recursion everywhere. Functional Programming generally abstracts recursion into folds. This gives two benefits:
- it allows hiding the implementation, which can then be realized by any suitable means, even imperative ones.
- It makes new
patterns to appear. I once wrote that most computations could be expressed as folds. For example, getting a value from an
Optional is a fold. Of course, it has nothing to do with recursion. This is because recursion is often an implementation detail. Saying that the sum of a list is 0 if the list is empty and head + sum(tail) otherwise might seem elegant, but it is just the description of an implementation of a specific case. It is in my opinion much better to express it as a fold, which make clearly apparent that there are three elements: the identity, the function, and the fold operation. This is not obvious with the recursive description, and this is why recursion is sometimes called the "goto of functional programming".
In a more general way, I want to make it clear that what I expose in the book is not what programmers should do, but what they can do. Solving all problems explicitly using stack safe recursion in Java would certainly not be a good thing.
Regarding the problem of OOP vs FP, I don't think this is very important. It's not what the language is that is important, but what you do with it. I don't care if some aspects of OOP are not compatible with FP (which is yet to be proven). OOP and FP are tools. They are not incompatible by themselves, in the sense that you would not be able to, or perhaps should not, do some functional programming stuff with a language labelled "OOP" and conversely. I have yet to see a language that is exclusively OOP or exclusively FP. This simply do not exist, despite the efforts made by some to create it. So I would not say that FP breaks the essential paradigm of the language. It simply uses a different paradigm. It may even use part of the OOP paradigm + FP. In the same way, you can do OOP while using some elements of the FP paradigm. Clearly separating functions from effects or insuring referential transparency, does not break the OOP paradigm. Even passing functions to methods or returning functions from methods do not break this paradigm. In fact, this is something that has always been done in Java, and there are even named patterns for this.