Going through the compile-rtl stuff I realized that the handling of <dynlet>
in tail call position is not as good as one could do or?
The reason is that the tail _expression_ is transformed to a value position and
hence these expressions risks blowing the stack when one would think that we
would be safe. Also, it's possible there exists an acceptable solution for which we
can run tail call expressions with with-fluids for ever.
To achieve the first task of cleaning up the with-fluids the most simple solution would be
to store a pointer to the dynwind stack at each call frame and then at a return unwind the
dynwind stack all the way to that pointer. On the other hand this overhead to handle something
that is not that common may mean that we cannot go that route.
Another approach would be to mark a bit at the call frame when doing a tail-with-fluids and insert
a pointer to the function frame on the dynwind stack and then a return statement would just check for the bit and if set unwind to the stack mark. This means much lower overhead in the common case but this approach seams do not mix well with delimeted continuations.
Another interesting idea is to consider counting the number of call's in the call stack and mark
each fluid data with the number of calls, if we then do a with-fluids-tail call and the old data have the same call frame as the current one one could overwrite that value with the new one doing essentially a fluid-set!. This would mean that most applications with with-fluids in tail position will loop for ever without consuming the memory. Again this approach is difficult to combine with continuations.
The problem with mixing continuations and proper tail call with-fluids can probably by
1. Marking the call-frame as unsafe for tail-call fixups when storing a state and after that
fallback on some old behavior
2. Updating everything in a functional manner
3. When storing a state, copy data that can mutate
A problem with 1 is that we introduce a link to the call frame in question and the address will need to be restored at the correct address. This can be solved however by in the continuation store the old address of the start of the stack and then use the difference between the old position and the new position while updating the call frame addresses at re-installation of the dynstack.
For the second feature I have no clue yet how to approach it, the reason is that I'm too ignorant yet to be able to find a solution. There will be a significant overhead of implementing this and I suggest that if there shows up some use case who needs it we can consider implementing it else we leave it as is. WDYT?
I'm fully capable of fixinig the first part though. The question I have is
1. Do you wan't it implemented?
2. For 2.0 or 2.1?
3. Do you have any comments on the implementation strategy?