Path: csiph.com!usenet.pasdenom.info!news.lightlink.com!news.iecc.com!.POSTED!nerds-end From: Kaz Kylheku Newsgroups: comp.compilers Subject: Re: Is multi-level function return possible? Date: Fri, 14 Mar 2014 21:34:19 +0000 (UTC) Organization: Aioe.org NNTP Server Lines: 123 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <14-03-035@comp.compilers> References: <14-03-020@comp.compilers> <14-03-022@comp.compilers> <14-03-025@comp.compilers> <14-03-030@comp.compilers> NNTP-Posting-Host: news.iecc.com X-Trace: miucha.iecc.com 1394834437 76259 2001:470:1f07:1126:0:676f:7373:6970 (14 Mar 2014 22:00:37 GMT) X-Complaints-To: abuse@iecc.com NNTP-Posting-Date: Fri, 14 Mar 2014 22:00:37 +0000 (UTC) Keywords: Pascal, code Posted-Date: 14 Mar 2014 18:00:37 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:1157 On 2014-03-14, George Neuner wrote: > On Tue, 11 Mar 2014 22:15:36 +0000 (UTC), Kaz Kylheku > wrote: > >>Recursion means there is possibly more than one activation of the environment >>which contains the target label of the goto. Which activation is chosen as the >>jump target? Does the goto return to the same recursion level in which >>the closure was created or does it just find the innermost activation of >>that label? > > YMMV, but ISTM that recursion is not really relevant to the issue: > lexical scoping by itself introduces the potential for name shadowing > and the rule always has been to reference the instance which is > defined "closest" to the point of use. The addition of recursion > simply makes locating that closest instance - at least in part - a > runtime operation rather than a compile time operation. But we have the option that we don't want the closest instance, since this isn't lexical scope. E.g. restarts in Common Lisp. compute-restarts can return all the restarts that are visible. There can be more than one which share teh same symbol (for instance due to recursion). You can pick one that isn't the first one on the list, and then invoke-restart. CLISP example session: $ clisp -q [1]> (compute-restarts) (#S(RESTART :NAME ABORT :TEST # :INVOKE-TAG NIL :INVOKE-FUNCTION # :REPORT # :INTERACTIVE # :MEANINGFULP T)) Only one restart is visible from the repl. Let's make an error to get into a nested error-recovery repl, then see what restarts are visible: [2]> (+ "a" 3) *** - +: "a" is not a number The following restarts are available: USE-VALUE :R1 Input a value to be used instead. ABORT :R2 Abort main loop Break 1 [3]> (compute-restarts) (#S(RESTART :NAME ABORT :TEST # :INVOKE-TAG NIL :INVOKE-FUNCTION # :REPORT # :INTERACTIVE # :MEANINGFULP T) #S(RESTART :NAME USE-VALUE :TEST # :INVOKE-TAG NIL :INVOKE-FUNCTION # :REPORT # :INTERACTIVE # :MEANINGFULP T) #S(RESTART :NAME ABORT :TEST # :INVOKE-TAG NIL :INVOKE-FUNCTION # :REPORT # :INTERACTIVE # :MEANINGFULP T)) Now there are two restarts with the same name. If we do (invoke-restart 'abort), of course it will go to the innermost one. But we can search the list of restarts for the other one and do invoke-restart on the restart object. > We can argue about whether the type should be part of the name: e.g., > if x:string shadows x:integer then does an arithmetic operation on x > find x:integer or does it fail for incompatible types? But this is a > discussion at a different level. I would not go farther than separation of function and value bindings. Separate namespaces for strings and numbers seems ... hokey. It erquires static typing, with no overloading. What if x is an integer in one scope, and a string in another scope, and then we call foo(x) which is overloaded for strings and integers. Probably we resolve in favor of the inner nesting. Then, of what value is the separation if we abandon it at the slightest appearance of a problem. :) >>If the closure jsut goes to the innermost block which has the label, >>then the target resolution is in fact dynamically scoped, even though >>the label is lexical. (Because the target block is not lexically captured >>along with the closure, but chosen just from whatever is visible at the >>time the goto takes place.) > > Your Lisp is showing 8-) ... "nested function" is not synonymous with > "closure". It can be if everything is downward. Downward funargs still close over their lexical environment; they coach which arries the bindings, however, turns into a pumpking when the closure tries to escape. I'm only thinking of the downward situation in this whole thread; whose main topic is non-local returns! Jumping out to a closure whose creation environment is still active and which is not set up to try to escape. > Standard Pascal did have not have closures: you could pass a function > by name as an argument to another, but its definition had to be > visible both at the point of passing the name and at the point of > invocation [through the aliasing argument]. Okay, forget Pascal then with these bizarre restrictions. Let's pretend that "Pascal" really means "GNU C" (with its local functions). http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html GNU C has real downard funargs, a.k.a. non escaping closures. (I thought Pascal was like this; but if not, it's too broken to warrant another thought.) So your comment could have said "your GNU C is showing". :)