Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!1.eu.feeder.erje.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.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'assignment': 0.07; 'cc:addr:python-list': 0.09; '*is*': 0.09; '128': 0.09; 'instruction.': 0.09; 'wrong,': 0.09; ':-)': 0.12; 'stack': 0.13; 'wed,': 0.15; 'languages,': 0.15; '"if"': 0.16; '"while"': 0.16; '(relative': 0.16; 'assembly,': 0.16; 'bytes),': 0.16; 'conditional': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'gregory': 0.16; 'jumps': 0.16; 'operation.': 0.16; 'pointer,': 0.16; 'statements,': 0.16; 'wrote:': 0.16; 'intel': 0.18; 'pointer': 0.18; 'language': 0.19; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'explicit': 0.22; 'function,': 0.22; 'seems': 0.23; "python's": 0.23; 'thus': 0.24; 'header:In-Reply-To:1': 0.24; 'sort': 0.25; "doesn't": 0.26; 'chris': 0.26; 'message-id:@mail.gmail.com': 0.27; 'restrict': 0.27; 'assembly': 0.29; 'tail': 0.29; 'instruction': 0.29; "i'm": 0.30; 'subject:/': 0.30; 'code': 0.30; '15,': 0.30; 'push': 0.30; 'implement': 0.32; 'statement': 0.32; 'flags': 0.33; 'jump': 0.33; 'lets': 0.33; 'languages': 0.34; 'that,': 0.34; 'received:google.com': 0.35; 'level': 0.35; 'but': 0.36; 'should': 0.36; 'instead': 0.36; 'there': 0.36; 'possible': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'sure': 0.39; 'where': 0.40; 'still': 0.40; 'some': 0.40; 'high': 0.60; 'skip:u 10': 0.61; 'within': 0.64; 'other.': 0.64; 'between': 0.65; 'designers': 0.72; 'jul': 0.72; 'treat': 0.72; 'chrisa': 0.84; 'etc,': 0.84; 'respectively': 0.84; 'ultimately,': 0.84; 'to:none': 0.91 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=G8qiDTHpYkLsq8gVn5AtUW+3bUuduOpnRGkJc4EcmbQ=; b=tqYhm04Rk5gfsyu68NAMcDAK0PTYasFNIWztHfDVQvFuCCZUp7IQw/m8CuGHG267p4 2y6zS1QMCxYfR4jFvPEctlDP53xdg4CXZDQPqx4zSOhk6ebY8kEqNc3QGmwp1g6q56lM XWv7HDkcCAeh2S8fK4hyo6JXU5j0C6H9gPnTP65pl4YVRAeNOdOYlRjZnvn/nOL7YDFo wX9a0MGAC8Cw6F74fnUTuI7jL4/xAMHNdUEMIp6tkT04tAK9v/T3jQQbzErsxlr/7Vi7 0m9o43I9uXPkaKT+LG8RMhAF53KOys80iBcVxtvAXLCCOgdo8dmXQOgrO2vd61tbXO+j 7Pwg== MIME-Version: 1.0 X-Received: by 10.50.114.9 with SMTP id jc9mr25853970igb.56.1436962936400; Wed, 15 Jul 2015 05:22:16 -0700 (PDT) In-Reply-To: References: <55A3A853.4040006@rece.vub.ac.be> <55A3C366.6060602@rece.vub.ac.be> <87fv4r1fre.fsf@jester.gateway.sonic.net> <87bnff1eks.fsf@jester.gateway.sonic.net> Date: Wed, 15 Jul 2015 22:22:16 +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: 42 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1436962945 news.xs4all.nl 2853 [2001:888:2000:d::a6]:40279 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:93872 On Wed, Jul 15, 2015 at 7:13 PM, Gregory Ewing wrote: > Chris Angelico wrote: >> >> I'm still interested in the explicit "replace current stack frame with >> this call" operation. Calling it "goto" seems wrong, as most languages >> with goto restrict it to _within_ a function, > > > This just suggests to me is that most language designers > are not very imaginative. :-) > > A tail call *is* a goto. That's how you implement one in > assembly language -- you write a jump instruction instead > of a call instruction. The jump doesn't have to be to > the same function. > Sure it is; but then, a while loop is a goto, but we don't call them goto loops. Ultimately, assembly language lets you treat everything the same way - in some CPUs, a jump is an assignment to the instruction pointer register, and is thus the same kind of operation as any other. In real-mode Intel 80x86 Assembly, there are unconditional and conditional jumps, where conditional jumps are limited to the shortest possible form of jump (relative jumps within +/- 128 bytes), but other than that, there's no distinctions between "if" statements, "while" loops, etc, etc. (Yes, there's also near-call, far-call, and interrupt, which push the instruction pointer, the IP plus the code segment, and the IP, CS, and the flags register, respectively - but then still just do a straight jump to the other location.) But in high level languages, we differentiate all of them, because the human who reads the code should differentiate between them. You don't use Python's "while" statement as a sort of "if", nor vice versa. At least, not usually... while x < 1: print("x is less than one!") break else: print("x is one or greater!") ChrisA