Skip to content

Proper tail recursion - #728

Closed
Tritlo wants to merge 9 commits into
hylang:masterfrom
Tritlo:master
Closed

Tritlo wants to merge 9 commits into
hylang:masterfrom
Tritlo:master

Conversation

@Tritlo

@Tritlo Tritlo commented Dec 21, 2014

Copy link
Copy Markdown
Contributor

I've added support for Proper tail recursion in Hy. It's optional, and can be enabled with an

(import [__future__ [TailRec]])

in the Hy source where it is needed. Benefits can be seen for example in the tests, where we can use mutual recursive functions (not just self recurring, as the current loop macro implements) on much larger values without hitting a recursion depth exceeded exception.

Needs a little more work before it can be in Hy proper, as it does not work while bootstrapping (since the TailCall mechanism itself is written in Hy).

@Tritlo Tritlo changed the title Proper tail recursion in Hy Proper tail recursion Dec 21, 2014
@paultag

paultag commented Jan 11, 2015

Copy link
Copy Markdown
Member

Interesting approach!

@paultag

paultag commented Jan 11, 2015

Copy link
Copy Markdown
Member

I'll get on a more in depth review with how this is structured, since this adds a bunch of new things to internals. Very cool work, though!

* 'master' of git://github.com/hylang/hy:
  Correct indentation level of code blocks
  Miscellaneous fixes to transplanted style guide
  Match heading/subheading style to rest of Hy docs
  Transplant style guide from hylang/hy-style-guide
* 'master' of github.com:hylang/hy:
  Add Shenyang Zhao to AUTHORS
  add documents for symbol?
  add `symbol?` function to `hy.core`
  Fix completion bugs
  fix typos in koan
  Adding Shrayas to AUTHORS
  Adapt attribute completion from IPython completer
  Added a fix for nested decorators. Fixes hylang#752
  Fix typo
@Tritlo

Tritlo commented Jun 11, 2015

Copy link
Copy Markdown
Contributor Author

So, any news?

@paultag

paultag commented Jun 11, 2015

Copy link
Copy Markdown
Member

Ah, yes, the news is I'm literally the worst.

Let's get eyes on this and tend to it - ping @hylang/core

Comment thread hy/compiler.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use snake-casting rather than camel casing :)

@paultag

paultag commented Jul 22, 2015

Copy link
Copy Markdown
Member

Interesting approach, using Exceptions. The overhead on this might slow it down, but short of crosscutting into Bytecode, we can't have GOTO/JUMP instructions.

This is pretty similar (but not similar enough to merge with) https://github.com/hylang/hy/blob/master/hy/contrib/loop.hy -- not sure which I like more.

Can we move this to contrib to start with? This is a total no brainer for contrib right now, but I'd love to battle test this a little before putting it into core.

Really interesting work. I like it. Well done, @Tritlo

@Tritlo

Tritlo commented Jul 23, 2015

Copy link
Copy Markdown
Contributor Author

This is actually more powerful than loop, since it allows mutually recursive functions. I'm not sure that this can be moved into contrib, since we need access to the expressions themselves when we convert the return into an exception. This is needed to break out of the stack, and avoid a stack overflow. This also allows us to have tail recursive functions within other tail recursive functions, without any additional overhead.

The overhead can definitely slow this down, which that is why we use the from future expression, to avoid the overhead where we can.

@paultag

paultag commented Dec 12, 2015

Copy link
Copy Markdown
Member

Merge conflicts against master - mind updating? I'm going to close this until it's ready :)

👍

@paultag paultag closed this Dec 12, 2015
@bowbahdoe

Copy link
Copy Markdown

Is there any reason that this has been neglected for a year? It seems like a tremendously useful feature.

@Kodiologist

Kodiologist commented Dec 8, 2016

Copy link
Copy Markdown
Member

Apparently, nobody cared enough to fix the merge conflicts. Feel free to make a new PR out of this if you want to do it.

@Tritlo

Tritlo commented Dec 8, 2016

Copy link
Copy Markdown
Contributor Author

Oofh. I've been very busy the last year, and haven't had time to take care of this pull request. It's been ready for about 2 years now, and there never seems to be interest in actually getting it into the Hy language. I'll try to look into it over christmas if possible, but I'm afraid that I haven't been following Hy's development for a long time, so I might need some help. Is there still interest for this feature, @paultag @Foxboron ?

@bowbahdoe

Copy link
Copy Markdown

Looking at the source now, the actual areas this changed haven't been updated that much. I'm not well versed in git, but if I insert the changes again on an updated branch that should get rid of merge conflicts.

@Tritlo

Tritlo commented Dec 8, 2016

Copy link
Copy Markdown
Contributor Author

I'll see whether I can patch this up real quick.

@jochasinga

Copy link
Copy Markdown

Without an attempt to tackle tail call optimization, this is going to ward off any Lispers / functional programmers looking into the language. Which I think is a shame.

@Kodiologist

Copy link
Copy Markdown
Member

Personally, I never write pure tail calls because they're more concisely expressed as loops. Recursion is better saved for when you actually need it. But, different strokes.

@jml1996

jml1996 commented Nov 20, 2020

Copy link
Copy Markdown

Interesting that everyone's converging here at the same time. (Or all two or three of us, at least.) I am myself looking for a way to write a couple of vanilla tail-recursive functions amid a vanilla python program, which is running behind a vanilla little website. Wondering if this branch would work for basic cases. I suspect that I could do what I'm trying to do without recursion, but I'm looking for a longer-term solution that might allow me to write stuff in lisps without getting boxed in.

@Tritlo

Tritlo commented Dec 15, 2020

Copy link
Copy Markdown
Contributor Author

This should work for basic cases. You could do this in vanilla python as well, but the resulting code would be very ugly. Fortunately, in Hy we don't look at the generated tree, so it works out.

And to @Kodiologist, not all calls can be expressed as loops! Take a look at mutual tail-recursive calls. If there is a non-trivial amount of tail-recursive functions all calling each other, that would be a mess of a loop, but works great here.

@jml1996

jml1996 commented Dec 15, 2020 via email

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants