Number: 2071 Date: 6-Sep-84 08':52':47 Submitter: Masinter Source: Masinter Subject: want Catch/Throw, named LAMBDAs & progs, etc. in Interlisp-D Assigned To: Attn: JonL Status: Open In/By: Problem Type: Impact: Difficulty: Frequency: Priority: System: Subsystem: Machine: Disk: Lisp Version: 5-Sep-84 16':37':47 Source Files: Microcode Version: 5124 Memory Size: 4096 File Server: Server Software Version: Disposition: Description: [this may be in CMLSPECIALFORMS, but I thought I would preserve this discussion here':' ' Date': 16 Feb 1982 0959-PST' From': Neil Goldman <GOLDMAN at USC-ISIF>' Subject': Re': AP statistics' To': Masinter at PARC-MAXC' In-Reply-To': Your message of 12-Feb-82 1748-PST' ' Your NAMEDLAMBDA would allow me to get the effect I get now with my SETSTKNAME (provided you had both NAMEDLAMBDA and NAMEDNLAMBDA). But there are two alternatives which would be preferable, from my viewpoint':' ' 1) Generalization of the lambda (under some other name, of course) to something akin to the lisp machine notion of a lambda list, where I can specify for each formal parameter': ' a) how it is to be passed (quote the actual, eval the actual, or (this is not provided by the lisp machine) some other function' b) whether a formal parameter is optional, and, if so, how to initialize it if no actual is provided' ' 2) Simply allowing me some way of distinguishing, inside a function, whether an actual parameter was provided or not. The rule of universally binding "excess" formals to NIL in interlisp, i think, was a very bad choice; the empty list is simply too important a value to be co-opted for this purpose -- i.e., the fact that the formal is initially NIL' can''t be assumed to indicate that the actual was defaulted. It is because of this that I had to translate my (APLAMBDA (F1 ... Fn) ...)' into (NLAMBDA X (PROG (F1 ... Fn) ...] instead of simply' (NLAMBDA (F1 ... Fn) ...]' and get into the setstkname stuff.' ' I suppose (1) is too major an effort to consider. Conceivably (2) could be done by means of some hack without too much difficulty -- e.g., a function-specific declaration which EVAL, APPLY and the compiler were sensitive to. Doing it right might also be a major effort.' ' neil' ********************' ' Mail-from': Arpanet host USC-ISIF rcvd at 7-APR-82 1252-PST' Date': 7 Apr 1982 1245-PST' From': Neil Goldman <GOLDMAN at USC-ISIF>' Subject': getting close' To': masinter at PARC-MAXC' cc': goldman at USC-ISIF' ' I''ve been able to use /CALLME as an interim solution until some form of your "named" frame construct becomes available. I have 1 observation and 1 question':' ' OBSERVATION':' APPLY and APPLY* are not equivalent with respect to merging of frames. In particular,' (APPLY* (FUNCTION (LAMBDA (X Y) (\CALLME ''FOO) ... )) ...)' did not give me a new frame when compiled, and ended up with an outer frame being named FOO, whereas the analogous APPLY did produce a separate frame named FOO. (It would be slightly more efficient in my application to use APPLY* that APPLY, since the arguments are not already in a list, but I will convert to the named frame construct as soon as it is available anyway.' ' QUESTION':' Is it correct that, as things stand now, there is no reasonable way for me to implement my CATCH/THROW like construct -- that is, the only way to get distinct frame for the CATCH, with a name I can specify,' is to introduce an APPLY -- e.g.,' (CATCH ERRORCLASS <form>) ===>' (APPLY (FUNCTION (LAMBDA NIL (\CALLME ''ERRORCLASS) <form>)) NIL)' which works, but requires all variables used freely in <form> to be made special, even if they are bound in a PROG or LAMBDA in which the CATCH is lexically enclosed.' ' In particular, whatever you do to make NLSETQ work without ' requiring variables to be declared special goes beyond anything I can accomplish with ordinary macros??' ' neil' Catch and Throw' To': MASINTER at PARC-MAXC' ' Here is a version of CATCH* and THROW* (lisp machine style versions of catch and throw). They seem to work correctly in INTERLISP-10. I would appreciate your comments, especially if it does something terrible. Included is a macro, RESETLST*, like RESETLST, but it knows about catch*' and throw*. There are backquoted and un-backquoted versions.' ' Here is the backquoted version.' ' (PUTPROP ''CATCH* ''MACRO' ''(ARGS `((LAMBDA (/CatchLabel)' (SETSTKNAME -1 ''CATCH*)' ,(CADR ARGS))' ,(CAR ARGS))))' ' ' ' (DEFINEQ' (THROW* (LABEL VALUE POS)' (* CATCH* and THROW* interact properly with RESETLST*' only if thrown through the last form of the RESETLST* args.)' (OR POS (SETQ POS (STKSCAN ''THROW*)))' (PROG ()' LOOP' (SETQ POS (STKNTH -1 POS POS))' (OR POS (ERROR LABEL "No pending CATCH* for this label"))' (SELECTQ (STKNAME POS)' (CATCH*' (COND ((OR (NULL LABEL)' (EQ LABEL (STKARG ''/CatchLabel POS)))' (RETFROM POS VALUE T))))' (RESETLST*' (RETTO POS (LIST ''/CatchLabel LABEL VALUE) T))' NIL)' (GO LOOP))))' ' ' (PUTPROP ''RESETLST* ''MACRO' ''(ARGS `(PROG ((VAL (RESETLST @,(DREVERSE (CDR (REVERSE ARGS)))' ((LAMBDA ()' (SETSTKNAME -1 ''RESETLST*)' ,(CAR (FLAST ARGS)))))))' (COND ((AND (LISTP VAL)' (EQ (CAR VAL) ''/CatchLabel))' (THROW* (CADR VAL) (CADDR VAL)))' (T (RETURN VAL))))))' ' Workaround: Test Case: Edit-By: Edit-Date: