# Source code of rec from SRFI 31

**URL:** <https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997>\
**Category:** Questions & Answers\
**Created:** [November 6, 2025, 8:52pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997 "2025-11-06T20:52:43Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [November 6, 2025, 8:52pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/1 "2025-11-06T20:52:43Z")

</div>

Hi,

i searched a moment before asking in racket mailing list.  
There is a definition of `rec` in the official SRFI 31

> **[SRFI 31: A special form \`rec' for recursive evaluation](https://srfi.schemers.org/srfi-31/srfi-31.html)**

that i recopy here:

```scheme
(define-syntax rec
  (syntax-rules ()
    ((rec (NAME . VARIABLES) . BODY)
     (letrec ( (NAME (lambda VARIABLES . BODY)) ) NAME))
    ((rec NAME EXPRESSION)
     (letrec ( (NAME EXPRESSION) ) NAME))))

```

but i do not understand this part: `(lambda VARIABLES . BODY)` , this seems to not be valid scheme syntax?!

But i can not think an error could be in an official SRFI too.So i ask advice here.

If try in Racket of course i got errors:

```scheme
> (lambda VARIABLES . 7)
. lambda: bad syntax in: (lambda VARIABLES . 7)
> rec
. . rec: undefined;
 cannot reference an identifier before its definition
> (define-syntax rec
  (syntax-rules ()
    ((rec (NAME . VARIABLES) . BODY)
     (letrec ( (NAME (lambda VARIABLES . BODY)) ) NAME))
    ((rec NAME EXPRESSION)
     (letrec ( (NAME EXPRESSION) ) NAME))))

> (lambda v . 7)
. lambda: bad syntax in: (lambda v . 7)
> (letrec ( (NAME (lambda VARIABLES . BODY)) ) NAME)
. lambda: bad syntax in: (lambda VARIABLES . BODY)
> (letrec ( (NAME (lambda VARIABLES . 7)) ) NAME)
. lambda: bad syntax in: (lambda VARIABLES . 7)
> rec
. rec: bad syntax in: rec
> (rec (toto . x) . 7)
. lambda: bad syntax in: (lambda x . 7)
> 

```

but `rec` from racket seems to be ok as i already used it, but i can not find the source code in the github repository.

Guile seems to use another code for rec:

> **[guile/module/srfi/srfi-31.scm at main](https://codeberg.org/guile/guile/src/branch/main/module/srfi/srfi-31.scm)**
>
> guile - The Guile Scheme implementation.

but Gambit seems to use the official SRFI 31 code:

> <https://github.com/gambit/gambit/blob/master/lib/srfi/31/31.scm>

but haven't test it.

Best regards,

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [November 6, 2025, 9:31pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/2 "2025-11-06T21:31:08Z")

</div>

> [@damien\_mattei](#):
>
> but i do not understand this part: `(lambda VARIABLES . BODY)` , this seems to not be valid scheme syntax?!

There is an implicit requirement that `BODY` be list-structured for the resulting `lambda` form to be valid. More specifically, a `lambda` must have one or more body expressions, so a valid `BODY` must be (a syntax object containing) a non-empty list.

While remaining within the `syntax-rules` context, an implementation could enforce those requirements like this:

```scheme
(define-syntax rec
  (syntax-rules ()
    ((rec (NAME . VARIABLES) BODY0 BODY ...)
     (letrec ( (NAME (lambda VARIABLES BODY0 BODY ...)) ) NAME))
    ((rec NAME EXPRESSION)
     (letrec ( (NAME EXPRESSION) ) NAME))))

```

Apparently [at least some Schemers around the SRFI 31 era](https://srfi-email.schemers.org/srfi-5/msg/2776367/) (before my time) preferred the dot operator to ellipses, on the grounds that it is “more  
general-purpose,” or perhaps because ellipses did not exist in Lisps without pattern-based macros, which were controversial. I found that in SRFI 5, also, the use of `.` when the tail is actually constrained to be a proper list [obscured subtleties of the specification](https://srfi-email.schemers.org/srfi-5/msg/18709896/).

I think it's also fair to say that Scheme macros from this era rarely were concerned with good error reporting, probably because it was very difficult. Letting the target form (`lambda`, in this case) report the error seems to have been common. Especially with `syntax-parse`, specifying requirements instead of leaving them implicit pays off in obviously better error messages.

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [November 6, 2025, 9:47pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/3 "2025-11-06T21:47:46Z")

</div>

The srfi/31 implementation is just the mzlib/etc implementation, which is here: [compatibility/compatibility-lib/mzlib/etc.rkt at master · racket/compatibility · GitHub](https://github.com/racket/compatibility/blob/master/compatibility-lib/mzlib/etc.rkt#L114)

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [November 6, 2025, 10:15pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/4 "2025-11-06T22:15:05Z")

</div>

> [@LiberalArtist](#):
>
> There is an implicit requirement that `BODY` be list-structured for the resulting `lambda` form to be valid. More specifically, a `lambda` must have one or more body expressions, so a valid `BODY` must be (a syntax object containing) a non-empty list.

It is more clear now then.

```scheme
> (rec (toto . x) . (7))
#<procedure:toto>

```

works.

> [@LiberalArtist](#):
>
> Apparently [at least some Schemers around the SRFI 31 era](https://srfi-email.schemers.org/srfi-5/msg/2776367/) (before my time)

ah ah but i used `define-macro` ([Teach Yourself Scheme in Fixnum Days](https://ds26gte.github.io/tyscheme/index-Z-H-10.html#TAG:__tex2page_chap_8)) in the '90 and it is still in some light scheme implementation.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [November 6, 2025, 10:22pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/5 "2025-11-06T22:22:10Z")

</div>

> [@samth](#):
>
> The srfi/31 implementation is just the mzlib/etc implementation, which is here: [compatibility/compatibility-lib/mzlib/etc.rkt at master · racket/compatibility · GitHub](https://github.com/racket/compatibility/blob/master/compatibility-lib/mzlib/etc.rkt#L114)

thank you for the path because i was lost in the racket github labyrinth here:

> <https://github.com/racket/srfi/blob/12213e013937b0c1532de2238cf04906f589b302/srfi-lib/srfi/31/rec.rkt>

😭

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 6, 2025, 11:38pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/6 "2025-11-06T23:38:55Z")

</div>

> [@damien\_mattei](#):
>
> ```scheme
> (define-syntax rec
> (syntax-rules ()
> ((rec (NAME . VARIABLES) . BODY)
> (letrec ( (NAME (lambda VARIABLES . BODY)) ) NAME))
> ((rec NAME EXPRESSION)
> (letrec ( (NAME EXPRESSION) ) NAME))))
> 
> ```
> 
> > but i do not understand this part: `(lambda VARIABLES . BODY)` , this seems to not be valid scheme syntax?!

Note that `(lambda VARIABLES . BODY)` appears in a template.  
The dot is not part of the syntax of `lambda`, but rather for a dotted pair.  
E.g. `(1 . (2 . ())` is the same as `(1 2)`.

If `BODY` from the pattern has matched a list, then `(lambda VARIABLES . BODY)` becomes a list.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [November 7, 2025, 9:28am UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/7 "2025-11-07T09:28:31Z")

</div>

yes but convention of BODY being a list in not mentioned in the SRFI.

in fact i have concern only with the latter template not the one, i rarely use rec and only the 2nd template i use.

I just asked it because i wanted to inject infix feature in the body of rec to create a rec+ for scheme+

it seems chez scheme use only the latter template according this site but it is not sure, i have not checked the code:

> **[rec](https://practical-scheme.net/wiliki/schemexref.cgi?rec)**
>
> A Wiki site to create a cross reference of the programming language Scheme

for rec+ i will rely on the guile definition, perheaps like that:

```scheme
(module rec+ racket/base

	(provide rec+) 

	(require 
		 Scheme+/nfx)

(define-syntax rec+
  (syntax-rules ()
   
    ((_ (name . formals) body ...) ; procedure
     (letrec ((name (lambda formals ($nfx$-rec body) ...)))
       name))
    ((_ name expr) ; arbitrary object
     (letrec ((name ($nfx$-rec expr)))
       name))))
)

```

or even simplier , i could construct rec+ with lambda+ that i recently added and this give the possibility to `return` :

```scheme
(module rec+ racket/base

	(provide rec+) 

	(require srfi/31
		 Scheme+/lambda+)

(define-syntax rec+
  (syntax-rules ()
   
    ((_ (name . formals) body ...) ; procedure
     (letrec ((name (lambda+ formals body ...)))
       name))
    ((_ name expr) ; arbitrary object
     (letrec ((name ($nfx$-rec expr)))
       name))))
)

```

but that sound strange because there is a lambda+ in the first pattern and not the other , but the user can use lambda+ in expr.And it would then cause the infix parsing/detection run twice ,one time on the code , another on result,to be tested.....

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 7, 2025, 11:31am UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/8 "2025-11-07T11:31:04Z")

</div>

> [@damien\_mattei](#):
>
> yes but convention of BODY being a list in not mentioned in the SRFI.

> yes but convention of BODY being a list in not mentioned in the SRFI.

Well, you are looking at an implementation, not the specification.

## SRFI 31 Specification

```scheme
Syntax

The following production rules are to be added to those of [KCR1998] (we reuse names of non-terminals).

    <derived expression> --> <rec expression>
    <rec expression> --> (rec <variable> <expression>)
    <rec expression> --> (rec (<variable>+) <body>)

```

The syntax uses `<body>` which is defined in R5RS as:

```scheme
<body> --> <definition>* <sequence>

```

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [November 7, 2025, 11:48am UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/9 "2025-11-07T11:48:18Z")

</div>

> [@soegaard](#):
>
> The syntax uses `<body>` which is defined in R5RS as:
> 
> ```scheme
> <body> --> <definition>* <sequence>
> 
> ```

🤔

yes but i'm not Champollion  
😅

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 7, 2025, 1:50pm UTC](https://racket.discourse.group/t/source-code-of-rec-from-srfi-31/3997/10 "2025-11-07T13:50:28Z")

</div>

Great reference!

**Jean-François Champollion** (French: [[ʒɑ̃ fʁɑ̃swa ʃɑ̃pɔljɔ̃]](https://en.wikipedia.org/wiki/Help:IPA/French)), also known as **Champollion _le jeune_** ('the Younger'; 23 December 1790 – 4 March 1832), was a French [philologist](https://en.wikipedia.org/wiki/Philology) and [orientalist](https://en.wikipedia.org/wiki/Oriental_studies), known primarily as the [decipherer](https://en.wikipedia.org/wiki/Decipher) of [Egyptian hieroglyphs](https://en.wikipedia.org/wiki/Egyptian_hieroglyphs) and a founding figure in the field of [Egyptology](https://en.wikipedia.org/wiki/Egyptology).
