Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.glorb.com!usenet.stanford.edu!news.iecc.com!.POSTED!nerds-end From: Kaz Kylheku Newsgroups: comp.compilers Subject: Re: catch and throw, was Is multi-level function return possible? Date: Sat, 29 Mar 2014 02:47:31 +0000 (UTC) Organization: Aioe.org NNTP Server Lines: 135 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <14-03-080@comp.compilers> References: <14-03-065@comp.compilers> <14-03-068@comp.compilers> <14-03-070@comp.compilers> <14-03-076@comp.compilers> <14-03-077@comp.compilers> NNTP-Posting-Host: news.iecc.com X-Trace: miucha.iecc.com 1396063017 10685 2001:470:1f07:1126:0:676f:7373:6970 (29 Mar 2014 03:16:57 GMT) X-Complaints-To: abuse@iecc.com NNTP-Posting-Date: Sat, 29 Mar 2014 03:16:57 +0000 (UTC) Keywords: errors, architecture, comment Posted-Date: 28 Mar 2014 23:16:57 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:1202 On 2014-03-29, Ivan Godard wrote: > On 3/28/2014 4:08 PM, mac wrote: > >> Not quite the same. ON defined a handler invoked at the signal site. It >> could attempt repair and return. more like an interrupt. However, the >> typical handler did a non-local GOTO to bail out, clearing any calls >> between the signal and the gone-to label. >> >> I still think that the ability to resume can be useful. > > Useful or no, the ability to resume requires retaining the illusion of > sequential execution. You have no idea how expensive, in power and > performance, that illusion is. And it's flat-out impossible on wide > issue machine such as VLIWs. I suspect you're may be thinking about resuming the exact instruction with the exact machine state where some exception occured. That's not even necessarily the best, most useful way to resume. It's good for virtualizing actions: simulating instructions which are not implemented in hardware, misaligned memory accesses, or making virtual memory work. On some machines, resuming an instruction requires going back a few steps and software-emulating the last parts of what happened, because the state of the CPU pipeline is too big and too messy to store. Restartable exceptions or conditions in a programming language do not have to follow this "down to the faulting instruction" model of restartability. The model can provide restarts that do not go back to the expression which signaled the condition, but are themselves special handlers. The condition handle handles the condition being signaled, and then the restart handlers, similar to error handlers, handle the choice of restart. Here is an example Common Lisp program, where we use the INVOKE-DEBUGGER function as the error handler, and provide interactive mechanisms in the restarts. INVOKE-DEBUGGER shows us available restarts and gives us a prompt. The interaction is not necessary: protocols involving the choice of restarts can be mechanized. Or the style of interaction can be arbitrary: GUI dialog boxes, whatever. (defun read-new-thing () (format t "Enter a substitute thing: ") (list (read))) ;; process-things is a function that prints te items from a list, ;; but it dislikeso items which are the symbol :rotten. (defun process-things (things) (dolist (thing things) (block :continue (restart-case ;; the protected expression which signals (if (eq thing :rotten) (error "rotten thing detected!")) ;; restart cases (abort () (return-from process-things)) (substitute-thing (new-thing) :report "Give me non-rottem item." :interactive read-new-thing (setf thing new-thing)) (ignore-it () :report "Skip the rotten item." (return-from :continue))) (format t "accepting thing ~a~%" thing)))) ;; We ask process-things to rpocess a list of letter symbols, ;; with the rotten item embedded in serveral places. (handler-bind ((error #'invoke-debugger)) (process-things '(a b c :rotten d e f g :rotten h i :rotten z))) Test run with CLISP. FOr the first rotten thing, we choose to restart by substituting an alternative. For the second :rotten, we choose to ignore it. For the third rotten, we choose to abort, so that the item Z which follows is not processed. As you can see, the system makes additional estarts available which we did not code, one of which is to bail out of loading the entire file. $ clisp -q -i restarts.lisp ;; Loading file restarts.lisp ... accepting thing A accepting thing B accepting thing C *** - rotten thing detected! The following restarts are available: ABORT :R1 ABORT SUBSTITUTE-THING :R2 Give me non-rottem item. IGNORE-IT :R3 Skip the rotten item. SKIP :R4 skip (HANDLER-BIND # #) RETRY :R5 retry (HANDLER-BIND # #) STOP :R6 stop loading file /home/kaz/test/restarts.lisp Break 1 [3]> :R2 Enter a substitute thing: foo accepting thing FOO accepting thing D accepting thing E accepting thing F accepting thing G *** - rotten thing detected! The following restarts are available: ABORT :R1 ABORT SUBSTITUTE-THING :R2 Give me non-rottem item. IGNORE-IT :R3 Skip the rotten item. SKIP :R4 skip (HANDLER-BIND # #) RETRY :R5 retry (HANDLER-BIND # #) STOP :R6 stop loading file /home/kaz/test/restarts.lisp Break 1 [4]> :r3 accepting thing H accepting thing I *** - rotten thing detected! The following restarts are available: ABORT :R1 ABORT SUBSTITUTE-THING :R2 Give me non-rottem item. IGNORE-IT :R3 Skip the rotten item. SKIP :R4 skip (HANDLER-BIND # #) RETRY :R5 retry (HANDLER-BIND # #) STOP :R6 stop loading file /home/kaz/test/restarts.lisp Break 1 [5]> :r1 ;; Loaded file restarts.lisp [1]> [Am I the only one who remembers the OS/360 S0C0 termination code? -John]