[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: letrec semantics

From: Alexander Asteroth
Subject: Re: letrec semantics
Date: Wed, 30 Nov 2022 18:24:48 +0100
User-agent: mu4e 1.8.11; emacs 28.2

Dear Taylan,

thanks for pointing me to the use of letrec* in this case. The case
though was meant as an example to illustrate the problem. I'm currently
implementing an R5RS interpreter and was unsure if I can handle letrec
as illustrated below in the second case or if I need to implement it as
guile does.


On Mon, Nov 28 2022, 15:07:39, Taylan Kammer <> wrote:

> On 28.11.2022 09:33, Alexander Asteroth wrote:
>>> scheme@(guile-user)> (letrec ((b a)(a 7)) b)
>>> $1 = 7
>> should be equivalent (of course in a new scope) to:
>>> scheme@(guile-user)> (define b #nil)
>>> scheme@(guile-user)> (define a #nil)
>>> scheme@(guile-user)> (set! b a)
>>> scheme@(guile-user)> (set! a 7)
>>> scheme@(guile-user)> b
>>> $2 = #nil
> Hi Alex,
> The only reason the first example returns 7 is because Guile *happens* to
> bind a to 7 before it binds b to the value of a.  The code could have as
> well returned another value (IIRC Guile uses #<unspecified>) had Guile
> decided to evaluate the arms of the letrec in a different order.
> As per the part of the standard you quoted:
>> the 〈init〉s are evaluated [...] (in some unspecified order)
> That's what the "unspecified order" in the parentheses is referring to.
> On the other hand, in your second code example, there's a strict order
> in which the various expressions will be evaluated.  In the moment you
> type in (set! b a), the value of a has not yet been changed to 7.
> If you want to use letrec but with a specific order of evaluation of the
> arms, then you can use the letrec* variant:
>> (letrec* ((a 7) (b a)) b)
>> $1 = 7
> This will definitely work, without relying on chance or an implementation
> detail of Guile.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]