[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Multiple values for R4RS.
Your proposal doesn't say what happens when the number of values
expected by the receiver is different from the number the generator
produces. A simple case is when multiple values are returned and one
is expected:
(cons (values 1 2) 3)
=> (1 . 3)
=> (<?> . 3)
=> <error>
In the case of most functions (like CONS), I favor signaling an error,
but I can imagine some cases where passing multiple values as a single
parameter into a function should be permitted.
My argument stems from my discontent with Common Lisp when I have to
write code like:
(let ((a (foo)))
(multiple-value-bind (b c d)
(bar)
(let ((e (baz)))
...)))
when I would much prefer to write:
(let* ((a (foo))
((b c d) (bar))
(e (baz)))
...)
Granted, this can be accomplished by extending the syntax of LET*,
which in Scheme would expand to:
(let ((a (foo)))
(apply-values
(lambda (b c d)
(let ((e (baz)))
...))
(bar)))
but the same is not true of LET:
(let ((a (foo))
((b c d) (bar))
(e (baz)))
...)
-->
((lambda (a (b c d) e)
...)
(foo)
(bar)
(baz))
This suggests an extension of LAMBDA in which it may be specified that
multiple values can be passed in by a single parameter. In addition
to the conciseness this permits with LET and LET*, one could also
imagine writing code with this extended LAMBDA such as:
(define foo
(lambda (a (b c))
(list a b c)))
(foo 1 (values 2 3))
=> (1 2 3)
(foo 1 2)
=> <error>
---PROPOSAL---------------------------------------------------------------------
(LAMBDA <formals> <body>) essential syntax
<formals> ::= <variable>
| (<var/values>*)
| (<var/values>+ . <variable>)
<var/values> ::= <variable> ; single value
| (<var/values>*) ; multiple values
(LET (<binding spec>*) <body>) essential syntax
(LET* (<binding spec>*) <body>) essential syntax
<binding spec> ::= (<var/values> <expression>)
(VALUES . <expression>*) essential procedure
(APPLY-VALUES <receiver> <generator>) essential procedure
- with appropriate error messages when numbers of values mismatch.
- also suggest renaming APPLY to APPLY-LIST.
--------------------------------------------------------------------------------
Note that:
(apply-values (lambda (a b c) ...) (foo))
is equivalent to:
((lambda ((a b c)) ...) (foo))
I realize that the cost to implementors is much higher for this
proposal, but I think the power and conciseness of expression
justifies it.
Warren Harris