Explicit TCE

Dmitry Olshansky dmitry.olsh at gmail.com
Fri Oct 12 10:45:42 PDT 2012


On 12-Oct-12 21:29, Tyler Jameson Little wrote:
> I've read a few threads discussing tail call elimination, but they all
> wanted the spec to articulate specific circumstances where tail call
> elimination is required.  Has there been any thought to adding syntax to
> explicitly state tail call elimination?
>
> D could use something like Newsqueak's become keyword. If you're not
> familial with Newsqueak, become is just like a return, except it
> replaces the stack frame with the function that it calls. This was
> briefly mentioned years ago in this forum, but the become keyword was
> ignored:

I suspect it's so called switch-call or forced tail call. I proposed 
something to the exact effect of the below but to reuse the 'goto' keyword.

> http://www.digitalmars.com/d/archives/digitalmars/D/Rob_Pike_s_Newsqueak_-_some_good_concepts_53511.html
>
>
> I think D could do something like this:
>
>      int fact(int n, int accum = 1) {
>          if (n == 0) {
>              return accum
>          }
>          // become means return, but guarantees TCE
>          become fact(n - 1, accum * n)
>      }
>
> DMD should optimize this already, but explicitly stating become is a key
> to the compiler that the user wants this call to be eliminated.  Then,
> more interesting things can be implemented more simply, like a state
> machine:
>
>      void stateA() {
>          become stateB();
>      }
>
>      void stateB() {
>          become stateC();
>      }
>
>      void stateC() {
>          return;
>      }
>
>      void main() {
>          become stateA();
>      }
>
> This would only take a single stack frame. If there were conditionals in
> there for branching, this could end up with a stack overflow because DMD
> does not support complicated TCE, only simple recursive TCE.
>
> The become keyword would probably have to have these properties:
>
>      * statement after become must only be a function call (can't do
> foo() + 3)
>      * scope() needs to be handled appropriately for functions with become
>
> There might be others. I'm not sure how D handles stack sizes, so this
> may be an issue as well if stack sizes are determined at runtime. A
> requirement could be that functions called with become need to have a
> static stack size, since this stack might never be collected (in the
> case of an infinite state machine).
No idea what you are talking about.

>
> Adding this feature wouldn't cost much, but it would add a ton of
> functional power.

The use case in general is threaded code. In particular fast virtual 
machines.

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list