[r6rs-discuss] (no subject)

From: Christopher Dutchyn <dutchyn>
Date: Thu Jan 25 16:42:56 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.
Received on Thu Jan 25 2007 - 16:42:50 UTC

This archive was generated by hypermail 2.3.0 : Wed Oct 23 2024 - 09:15:01 UTC