[r6rs-discuss] (no subject)
dutchyn at cs.usask.ca
Thu Jan 25 16:42:50 EST 2007
Mike Sperber raised the issue of named let.
> The fact that the convenient syntax for writing recursive procedures
> is part of `let' is a long-standing wart in the syntax of Scheme. It
> is unintuitive (it expands into `letrec', rather than a simpler form
> of `let), difficult to explain to newcomers to Scheme, and
> disconcerting to the casual reader.
I also found this disconcerting the first time I saw it.
He suggest deprecating the syntax. I have an potential alternative,
motivated by how define works.
I've always wondered why define permits us to elide lambda, as in
(define (foo x y) ...)
(define (bar . x) ...)
(define (baz x . y) ...)
as syntactic sugar for
(define foo (lambda (x y) ...))
(define bar (lambda x ...))
(define baz (lambda (x . y) ...))
That is, if the identifier element is a symbol, then do the usual
thing, if the identifier element is a list (proper or improper) then
we have a lambda with the corresponding argument identifiers.
But let/let*/letrec/letrec* do not support this shorthand. Despite
the cavities, I personally prefer the first style, because currying
becomes more concise:
(define ((foo x) y) 'a) ; anX -> aY -> symbol
defines a higher-order procedure.
If let (in its variations) permitted the same understanding for the
identifier part of a binding
(letrec ([(foo x) ...]) ...)
then we would have much of the concision provided by named let, and
parallel syntax between define and let and its ilk**.
Named let looks like
(letrec ([(loop a b) ...)])
(loop '(starting a) '(starting b)))
Would this help reduce the wart?
University of Saskatchewan
**I have written such a macro; and Eli has conveniently provided one
that properly locates error messages in the PLT Swindle package.
More information about the r6rs-discuss