5
votes

R5RS gives proposed macro definitions for library forms of syntax:

http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-10.html#%_sec_7.3

Which also defines letrec, in a very complicated way, certainly not how I would define it, I would simply use:

(define-syntax letrec2
  (syntax-rules ()
    ((letrec2 ((name val) ...) body bodies ...)
     ((lambda ()
       (define name val) ...
       body bodies ...)))))

As far as I understand the semantics of letrec, which I use very often as a named let. It works in this way, however as I've had my fair share of debates with philosophers who think they can just disprove special relativity or established phonological theories, I know that when you think you have a simple solution to a complex problem, it's probably WRONG. There has got to be some point where this macro does not satify the semantics of letrec else they'd probably have used it.

In this definition, the definitions are local to the body of the letrec, they can refer to each other for mutual recursion, I'm not quite sure what (if any) is wrong.

4

4 Answers

5
votes

It seems to me that you have pushed the responsibility of the implementation from the macro to the compiler something the R5RS designers seem to be trying to avoid.

In fact local defines are implemented with letrec in R5RS. See 6.2.2 Internal definitions.

I think the designers intentions are summed up well in the introduction to the R5RS:

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today.

edit1: Example of internal defines transformed to r5rs version of letrec. PLT scheme 4.2.5 collects/r5rs/main.ss

(define-syntax (r5rs:body stx)
(syntax-case stx (let)
  [(_ (let () . body))
   #'(let () . body)]
  [_
   ;; Convert internal definitions to `r5rs:letrec', as opposed
   ;; to `letrec'.
...

In PLT Scheme in R5RS mode does convert internal defines to the R5RS version of letrec. You can also test this for yourself by using DrScheme's macro expander on any code with internal defines.

3
votes

R5RS states that the semantics of letrec are exactly the same as those of internal definitions. See the section devoted to the latter for details; I quote the key fragment below:

A <body> containing internal definitions can always be converted into a completely equivalent letrec expression.

Thus defining letrec in terms of internal defines just shifts the problem around.

Also, I find it simpler to define a letrec macro and have lambda desugar internal defines into letrec than to stuff all that complex code into the lambda handler and build letrec on top of that. That's without touching on the question of which is the prettier form of introducing mutually recursive bindings in a non-top-level scope... ;-)

0
votes

Good question.

I think the problem with a sequence of define is this:

"The order of evaluation of the expressions expr ... is unspecified, so a program must not evaluate a reference to any of the variables bound by the letrec expression before all of the values have been computed"

Here: http://www.scheme.com/tspl4/binding.html#./binding:s20

0
votes

Okay, I finally found the reason, it's as simple as useless, there is nothing wrong with my definition, and it is in fact due to some errors superior to the one in R5RS.

http://community.schemewiki.org/?scheme-faq-macros

Look for 'letrec', you all couldn't have answered my question of what was wrong, nothing was wrong apparently, R5RS had an 'erratum' in an informative section apparently. I'll be forced to accept my own answer now I guess...

What begs the question now is why the R5RS authors didn't choose this simple solution and went for a very complex one which even contained an error...