Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!newsgate.cistron.nl!newsgate.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.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'prefix': 0.07; 'tool,': 0.07; 'wrapped': 0.07; 'wrapper': 0.07; 'cc:addr :python-list': 0.09; 'args,': 0.09; 'python': 0.10; 'exception': 0.13; 'stack': 0.13; 'def': 0.13; 'expression.': 0.16; 'frame;': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'lambda': 0.16; 'oddly': 0.16; 'operation,': 0.16; 'reasonable.': 0.16; 'sense,': 0.16; 'tempted': 0.16; 'wrote:': 0.16; 'shell': 0.18; 'language': 0.19; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; '(the': 0.22; 'saying': 0.22; 'decorator': 0.22; 'function,': 0.22; 'occurs': 0.22; 'visible': 0.22; 'this:': 0.23; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; "i've": 0.25; "doesn't": 0.26; 'sense': 0.26; 'logging': 0.27; 'message-id:@mail.gmail.com': 0.27; 'turns': 0.27; 'function': 0.28; 'looks': 0.29; '13,': 0.29; "i'm": 0.30; 'subject:/': 0.30; 'certainly': 0.30; 'probably': 0.31; 'anyone': 0.32; 'call,': 0.33; 'definition': 0.34; 'received:google.com': 0.35; 'could': 0.35; 'done': 0.35; 'replace': 0.35; 'something': 0.35; 'but': 0.36; 'should': 0.36; 'keyword': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; "won't": 0.38; 'does': 0.39; 'easily': 0.39; 'takes': 0.39; 'rather': 0.39; 'where': 0.40; 'still': 0.40; 'care': 0.60; 'body': 0.61; 'real': 0.62; 'jul': 0.72; '**kw):': 0.84; 'chrisa': 0.84; 'kinda.': 0.84; 'treats': 0.84; 'to:none': 0.91; 'spell': 0.91; 'thing,': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=WoDWVpsb0cyZ7r+2s8pMrvwaEiuVdh3UvRI/ptBCdrE=; b=aTLi47o3C1z327uzyvDenemaDQKuwqo7bpPr6G0I0EPLVzhQsfodDZvIs+BEsaovo5 4rdKeWjl9y/Ycq2Klyt0xuXdSOa2JMQ30DemKDvslcw3EgXLhuUHdQT4WTaric+QoX6p MR0fl1O8AXI9kjHCXW1WmrP9VWJioza0Cp2r/qdlb0JUo3K5sj5WXad+UtlAKrNMHIBg kNo2yQ9ReMJdhve/7qvqApn3s7wPEpZxOh+rJO7kE7hoIYDztUUts5JbAFukexJcWudY IksWFEWh3WFAyBLAUFxgga7N/ltC+UPOeG8MYBOCl2/S8zySQp6UFq58kXHoafDUWI1t E30A== MIME-Version: 1.0 X-Received: by 10.107.165.142 with SMTP id o136mr19932101ioe.120.1436788027801; Mon, 13 Jul 2015 04:47:07 -0700 (PDT) In-Reply-To: References: Date: Mon, 13 Jul 2015 21:47:07 +1000 Subject: Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 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: 44 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1436788030 news.xs4all.nl 2880 [2001:888:2000:d::a6]:42591 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:93753 On Mon, Jul 13, 2015 at 9:22 PM, Jussi Piitulainen wrote: > 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 Huh. Now it looks like the 'exec' operation (the C function and shell operation, not the Python keyword/function) - it's saying "replace the current stack frame with _this_", which looks reasonable. It doesn't have to be recursion. The thing is, you would have to use this ONLY when you don't care about the current stack frame; so you could do a logging decorator thus: def log_calls(func): @functools.wraps(func) def wrapped(*a, **kw): logging.debug("Calling %s(%r, %r)", func.__name__, a, kw) recur func, a, kw return wrapped When an exception occurs inside the wrapped function, the wrapper won't be visible - but that's not a problem, because it doesn't affect anything. Like every other tool, it would be something that could easily be abused, but this actually does justify the removal. It would almost certainly need to be language syntax. I've done it up as a keyword that takes "function, args, kwargs" rather than a prefix on a function call, which emphasizes that the part after it is NOT an expression. In a sense, it makes a counterpart to lambda - where lambda takes an expression and turns it into a function, recur takes a function and treats it as if its body were part of the current function. Kinda. Does that make sense to anyone else? ChrisA