[racket] multiple-value sugar in "let"* forms
What do people think about this syntax addition for multiple values in
"let" and "let*" (and perhaps "letrec")?
I like using multiple-value returns, but two problems with using them
with the "let"* family:
1. "let-values" and "let*-values" are long identifiers, and increase
rightward drift, sometimes making the difference between a line break
needed before right-hand-side (RHS) or not (which line break is ugly in
a "let"* form).
2. If I have an existing "let"* that's not a *"-values" that already has
a few clauses in it, and I want to add a multiple-value LHS to it, I
have to go to the trouble of converting it to a "-values", which
requires editing each clause to add parentheses.
So, I've been wondering what would be a good way to support multiple
values on a per-clause basis. Options I see:
1. Change "(ID VAL-EXPR)" to "(ID ...+ VAL-EXPR)". I am shying away
from this one because it seems error-prone, and the standard indenter
won't know a good way to break such a clause across multiple lines, but
it does have some appeal.
2. In addition to "(ID VAL-EXPR)", have "((ID ...+) VAL-EXPR)". This
could work. One drawback I see is if in the future someone wants to
have some funky generalized-"set!" selectors that have a parenthesized
form, and have those work with the "let"* forms. I'm not currently
interested in such "set!" selectors. Another small drawback is that
we'll sometimes see "(let (((ID" three parentheses sometimes, like we do
with "let-values", which is not the most visually pleasant thing to see.
3. In addition to "(ID VAL-EXPR)", have "((values ID ...+) VAL-EXPR)".
This avoids the hypothetical problem with some future "set!" selectors,
since I doubt is going to use "values" for the name of such a selector
with any other purpose. This still has the three-parentheses problem
like option #2.
4. In addition to "(ID VAL-EXPR)", have "(values ID ...+ VAL-EXPR)" or
"(values (ID ...+) VAL-EXPR)". This avoids the three-parens of #2 and
#3, it's not ambiguous with "values" used as a variable name, but it
doesn't seem very Scheme-y, it has similar indent problem to option #1,
and we still have rightward drift because of the "values" keyword.
I lean a little towards option #2, but I think #1 or #3 would still be
an improvement. #4 seems less-Schemely syntax, so I am reluctant to go
there.
For each option, the transform to Racket's canonical "let-values" is
trivial.
I don't know whether there are implications for TR syntax.
A separate question -- which I don't care about, but someone else might
-- is whether there should be ``rest'' ID in the LHS that gets a list of
any remaining values from the RHS. I think this came up in a SRFI
discussion a long time ago. I almost never have occasion to use such a
feature, and it could complicate the syntax and the Racket compiler, so
I'm not interested in a ``rest'' in the LHS.
Neil V.