Ian Burnette writes:
> I've recently been playing around with Clojure, and I really like the
> way they've overcome the JVM not supporting TRE. The way Clojure
> solves this problem is to have a built in "recur" function that
> signals to the Clojure compiler to convert the code to a loop in the
> JVM. In python we could do something similar by having a recur(*args,
> **kwargs) function that removes its parent from the stack and then
> runs the parent function again with the given arguments. It would look
> something like this:
where I introduce some indentation:
> def factorial(n, acc=1):
> if n == 0:
> return acc
> else:
> return recur(n-1, acc=(acc*n))
> #signals to the interpreter to trigger TRE
That's oddly restricted to self-calls. To get the real thing, "recur"
should replace "return" - I'm tempted to spell it "recurn" - so the
definition would look like this:
def factorial(n, acc=1):
if n == 0:
return acc
else:
recur factorial(n-1, acc=(acc*n))
Probably it would still be syntactically restricted to calls - just
guessing what it would and would not be like to have this in Python:
def factorial(n, acc=1):
recur ( acc if n == 0 else factorial(n-1, acc=(acc*n)) ) #error?
Something similar could be done inside lambda forms, again probably
restricted to calls in value position:
factorial = ( lambda n, acc=1 : #horror?
( acc if n == 0 else rec factorial(n-1, acc=(acc*n)) ))
But I don't think it's a way that's missing, I think it's a will. I know
you know this, and I agree with your point (in a paragraph that I'm not
quoting) that an explicit syntax for "eliminable" tail calls would be,
well, explicit :) so a user of such syntax should at least know why they
are not getting in their stack traces material that they have
specifically requested to not have in their stacks.
--
https://mail.python.org/mailman/listinfo/python-list