Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'true,': 0.04; 'false,': 0.07; 'rewrite': 0.07; 'false)': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'subject:module': 0.09; 'url:github': 0.09; 'url:blog': 0.10; 'python': 0.10; 'jan': 0.11; 'syntax': 0.13; 'def': 0.13; 'assignments': 0.16; 'cyclic': 0.16; 'module?': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'reedy': 0.16; 'true:': 0.16; 'wrote:': 0.16; 'passes': 0.18; '(see': 0.20; 'suppose': 0.22; 'am,': 0.23; 'consistent': 0.23; 'replacing': 0.23; 'header:In-Reply-To:1': 0.24; 'module': 0.25; 'header:User-Agent:1': 0.26; 'header:X-Complaints-To:1': 0.26; 'order.': 0.27; 'module.': 0.27; 'function': 0.28; 'tail': 0.29; 'that.': 0.30; 'at:': 0.31; 'rule': 0.33; 'gives': 0.35; 'done': 0.35; 'false': 0.35; 'instance': 0.35; 'but': 0.36; 'should': 0.36; 'to:addr:python-list': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'two': 0.37; 'being': 0.37; 'received:org': 0.37; '(with': 0.38; 'difference': 0.38; 'version': 0.38; 'hi,': 0.38; 'test': 0.39; 'format': 0.39; 'does': 0.39; 'subject:-': 0.39; 'to:addr:python.org': 0.40; 'your': 0.60; 'suitable': 0.61; 'more': 0.63; 'believe': 0.66; 'combining': 0.66; 'here': 0.66; 'decided': 0.66; 'finally': 0.70; 'pardon': 0.84; 'received:fios.verizon.net': 0.91 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Terry Reedy Subject: Re: A new module for performing tail-call elimination Date: Wed, 15 Jul 2015 17:19:49 -0400 References: <55a3dcd9$0$3024$426a34cc@news.free.fr> <55A6280C.3090602@rece.vub.ac.be> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Gmane-NNTP-Posting-Host: pool-98-114-97-173.phlapa.fios.verizon.net User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 In-Reply-To: <55A6280C.3090602@rece.vub.ac.be> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 60 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1436995214 news.xs4all.nl 2938 [2001:888:2000:d::a6]:58923 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:93881 On 7/15/2015 5:29 AM, Antoon Pardon wrote: > On 07/13/2015 05:44 PM, Th. Baruchel wrote: >> Hi, after having spent much time thinking about tail-call elimination >> in Python (see for instance http://baruchel.github.io/blog/ ), I finally >> decided to write a module for that. You may find it at: >> >> https://github.com/baruchel/tco >> >> Tail-call elimination is done for tail-recursion as well as for >> continuation-passing style (cps) in a consistent syntax for both usages. >> >> Any tail-recursive function having the suitable format for being >> embeddable in the Y combinator can be used here with no change at all >> (with the main difference that tail-calls will be eliminated), but other >> continuations can also be added > > Can you explain how you would do mutual recursive functions? > Suppose I start with the following: > > def even(n): > True if n == 0 else odd(n - 1) > > def odd(n): > False if n == 0 else even(n - 1) > > How do I rewrite those with your module? I will not answer for Baruchel's tco module. However, combining the two bodies and following the general rule of replacing tail recursive calls with assignments inside a while loop gives us def even(n): return not odd(n) def odd(n): while True: if not n: return False else: n -= 1 if not n: return True else: n -= 1 # which passes this test print(even(0) is True, odd(0) is False, even(1) is False, odd(1) is True, even(2) is True, odd(2) is False, even(5) is False, odd(5) is True, even(6) is True, odd(6) is False) I believe that this pattern should work with any set of mutually recursive functions that always call each other in cyclic order. A more elaborate version does not have this limitation. -- Terry Jan Reedy