[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

*To*: rrrs-authors@MC.LCS.MIT.EDU*Subject*: multiple return values*From*: willc%tekchips.tek.com@RELAY.CS.NET*Date*: 27 Mar 87 15:47:06 PST (Fri)

Our previous round of discussions on multiple return values reached no consensus. I want to try again with the very simple, specific proposal that follows. The proposal consists of additions and changes to the formal semantics that appears in R3RS, an informal description, and a rationale. FORMAL SEMANTICS [Notation: The "\" character should be read as a Greek lambda, and the "!" character should be read as a down-arrow.] Add a procedure RECEIVE-VALUES whose semantics is given by receive_values: E* --> K --> C receive_values = twoarg (\ e1 e2 k . applicate e1 <> (\ e* . applicate e2 e* k)) Add a procedure RETURN-VALUES whose semantics is given by return_values: E* --> K --> C return_values = \ e* k . k e* Either leave the equation of the auxiliary function "single" as is (equation 1 below), or change it as indicated in equation 2 or as indicated in equation 3. single: (E --> C) --> K 1. single = \ f e* . # e* = 1 --> f (e* ! 1), wrong "..." 2. single = \ f e* . # e* >= 1 --> f (e* ! 1), wrong "..." 3. single = \ f e* . # e* >= 1 --> f (e* ! 1), f unspecified INFORMAL DESCRIPTION (RECEIVE-VALUES thunk proc) procedure The first argument is a procedure of no arguments, the second is any procedure. Calls the first argument, obtaining 0 or more return values, and then calls the second argument on the value(s) returned by the first argument. See RETURN-VALUES. (receive-values (lambda () (return-values 3 7)) (lambda (a b) (* a b))) --> 21 (RETURN-VALUES x ...) procedure Takes any number of arguments, and returns them as multiple return values. [See the rationale for a discussion of how many return values a continuation expects, and the error conditions that may result when the expectations are not met.] See RECEIVE-VALUES. (receive-values (lambda () (return-values 'a 'b 'c)) vector) --> #(a b c) (letrec ((f (lambda (x) (if (zero? x) (g x) (g x)))) (g (lambda (x) (return-values x (- x)))) (h (lambda (x) (receive-values (lambda () (f x)) list)))) (h 3)) --> (3 -3) (letrec ((f (lambda (x) (+ (g x) 13))) (g (lambda (x) (return-values x (- x)))) (h (lambda (x) (receive-values (lambda () (f x)) list)))) (h 3)) --> error [equation 1] --> (16) [equation 2 or 3] (receive-values (lambda () (return-values)) vector) --> #() (receive-values (lambda () (return-values 1)) (lambda (x . y) y)) --> () (receive-values (lambda () (return-values)) (lambda (x . y) y)) --> error (list (return-values 'a 'b 'c 'd)) --> (a) (car (list (return-values))) --> error [equation 1 or 2] --> unspecified [equation 3] RATIONALE This proposal is along the lines of multiple return values as in Common Lisp, but is somewhat simpler and more rational. The simplicity of the proposal, as compared to the exposition in CLtL, is attributable to a better choice of primitives and to Scheme's tail-recursive semantics. RECEIVE-VALUES and RETURN-VALUES correspond to T3's RECEIVE-VALUES and RETURN. The name "RETURN" was rejected because it would confuse people who are accustomed to the use of RETURN in Common Lisp and similar Lisps. Note that these are procedures, not syntax, and that neither would be essential Scheme. The arguments to RECEIVE-VALUES are reversed from the way they are in T3. Feel free to argue the argument order. Argue also about which equation we should choose for "single". It determines what happens in the case where RETURN-VALUES returns to a continuation that was not created by RECEIVE-VALUES. Equation 1 says that in such a case there must be exactly one return value. Equation 2 says that in such a case there must be at least one value; the extra values are ignored. Equation 3 allows zero return values, in which case the value received by the continuation is unspecified. No matter which equation is chosen, there is no difference between returning a single value in the usual way and returning a single "multiple value" using RETURN-VALUES. I didn't give equations for the extreme positions. The fascist position would say that it is always an error for RETURN-VALUES to return to a continuation that was not created by RECEIVE-VALUES. The commonlisp position would say that when zero values are returned to a continuation that is expecting one value, then the symbol NIL is passed to the continuation. If there is sufficient demand, I will post equations for these. If we interpret the use of "wrong" in the semantic equations to mean "is an error" instead of "signals an error", then all of the equations allow implementations in which Scheme multiple return values are compatible with the semantics of Common Lisp's multiple return values. This should make it easier to support a Scheme subset in Common Lisp or vice versa. I see no way to implement the proposed procedures in R3RS Scheme, but most implementations should find it easy to add them. William Clinger

**Follow-Ups**:**multiple return values***From:*Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>

- Prev by Date:
**eqv?** - Next by Date:
**Let's get together again** - Prev by thread:
**eqv?** - Next by thread:
**multiple return values** - Index(es):