chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] continuation example: different behavior from other


From: felix . winkelmann
Subject: Re: [Chicken-users] continuation example: different behavior from other Scheme implementations
Date: Sat, 19 Oct 2019 18:57:04 +0200

> I found this in R5RS/R7RS/SRFI-1: "The dynamic order in which proc is
> applied to the elements of the lists is unspecified". Indeed redefining
> map in all implementations as
>
> (define (map f l)
>    (cond ((null? l) '())
> (else (cons (f (car l))
>      (map f (cdr l))))))
>
> make all behave the same way (I know this is not a complete map
> implementation, is just an example).

Exactly. In CHICKEN, "map" is implemented in a (nearly) canonical
way (modulo some edge cases for extra arguments, etc.). On interpreted
implementations, "map" may be implemented in a lower-level way,
perhaps mutating the result list while it is build. Continuations expose
such details in a sometimes surprising way.

>
> R7RS adds this: "If multiple returns occur from map, the values returned
> by earlier returns are not mutated". Does this mean returns through
> continuation calls?

That's correct.

>
> I was curious how CHICKEN implements map and found the following in
> library.scm:
>
> (define (##sys#map p lst0)
>    (let loop ((lst lst0))
>      (cond ((eq? lst '()) lst)
>            ((pair? lst)
>              (cons (p (##sys#slot lst 0)) (loop (##sys#slot lst 1))) )
>            (else (##sys#error-not-a-proper-list lst0 'map)) ) ))
>

> So still I don't get why calling any stored continuation appends the
> result to the previously computed "numbers", but if the standard allows
> this behavior it's not a big deal.

As you save the continuation, you effectively retain all local state
from executions before the continuation was captured. The result list
is constructed recursively, the 2nd return from "p" above will restart
the mapping of 6 elements (with element 1 replaced by 76) until the list
runs out. What is done before is thus returned once again, with extra
elements appended, since you restart the processing of the list, you sort
of jump back in time into the recursion, effectively prolonging it.

But what I forgot, and which may be the confusing part is that
after the mapping is complete, "numbers" (in your example) will be
assigned once again - the continuation includes everything following
the invocation of "map". Only the REPL "cuts off" this continuation
(otherwise you would have an infinite loop, similar to when you would
run your example code as a non-interactive program).


felix




reply via email to

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