[r6rs-discuss] (no subject)

Christopher Dutchyn dutchyn at cs.usask.ca
Thu Jan 25 16:42:50 EST 2007

Mike Sperber raised the issue of named let.

> Issue:
> 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?

Chris Dutchyn
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 mailing list