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

2019-10-19 Thread Ricardo Gabriel Herdt



Am 19.10.2019 18:57 schrieb felix.winkelm...@bevuta.com:

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).


Thanks again, this makes sense, I had already experienced this infinite 
loop when using a compiled version of the program.


I added a note to the wiki mentioned 
(https://en.wikibooks.org/wiki/Scheme_Programming/Continuations) telling 
to be aware of implementation-dependent behavior, just in case someone 
stumbles on this issue in the future.


Cheers,

Ricardo

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


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

2019-10-19 Thread Ricardo Gabriel Herdt

Am 19.10.2019 15:46 schrieb megane:

There's special compiler syntax for map; search for 'map-loop in the
sources. You can also see what your code expands to by giving -debug 2
flag to csc.


Thanks megane,

with -debug 2 I see that map uses some local variables that are changed 
with set! in the loop, so it's quite more complex than I thought, and 
this explains the behavior seen. Thanks for the hints.


;; generated code
(set! numbers
  (let ((g2836 (scheme#cons (##core#undefined) '(
(let ((g2737 g2836) (g2938 capture-from-map) (g3539 '(1 2 3 4 5 6)))
  (let ((t46 (##sys#check-list g3539 'map)))
(##core#app
  (let ((map-loop2340 (##core#undefined)))
(let ((t45 (set! map-loop2340
 (##core#lambda
   (g3541)
   (if (scheme#pair? g3541)
 (let ((g2442 (scheme#cons (g2938 
(##sys#slot g3541 '0)) '(
   (let ((t43 (##sys#setslot g2836 '1 
g2442)))

 (let ((t44 (set! g2836 g2442)))
   (##core#app map-loop2340 (##sys#slot 
g3541 '1)

 (##sys#slot g2737 '1))
  (let () map-loop2340)))
  g3539)

Regards,

Ricardo



___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


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

2019-10-19 Thread Ricardo Gabriel Herdt

Am 19.10.2019 14:18 schrieb felix.winkelm...@bevuta.com:

The exact behaviour of re-
entering a continuation captured during execution of "map" is, I think,
dependent on implementation details (there may be a note about this in 
the

SRFI-1 document or R7RS, I can't remember right now).


Many thanks for the fast and detailed answer.

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).


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?


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)) ) ))

...
(set! scheme#map
(lambda (fn lst1 . lsts)
  (if (null? lsts)
  (##sys#map fn lst1)
  (let loop ((all (cons lst1 lsts)))
(let ((first (##sys#slot all 0)))
  (cond ((pair? first)
 (cons (apply fn (mapsafe (lambda (x) (car x)) all #t 'map))
   (loop (mapsafe (lambda (x) (cdr x)) all #t 'map)) ) )
(else (check (##core#inline "C_i_cdr" all) #t '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.


Regards,

Ricardo


___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


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

2019-10-19 Thread Ricardo Gabriel Herdt

Hi all,

I'm trying to understand how continuations work, and tried out the first 
example described at 
"https://en.wikibooks.org/wiki/Scheme_Programming/Continuations; with 
Chicken (5.1):


---
(define continuations '())

(define (push arg)
  (set! continuations
(cons arg continuations)))

(define (capture-from-map arg)
  (call-with-current-continuation
   (lambda (cc)
 (push cc)
 arg)))

(define numbers (map capture-from-map '(1 2 3 4 5 6)))

;;REPL

numbers

(1 2 3 4 5 6)

((car (reverse continuations)) 76)

((result "#") (output . ""))

numbers

(1 2 3 4 5 6 76 2 3 4 5 6)
---

To my surprise, this last value stored at 'numbers' differs from other 
implementations (and from the example described on the Wiki):

Guile/Racket/MIT: (76 2 3 4 5 6)
Chez: (1 2 3 4 76 6)

Could someone please explain what's going on? Why would Chicken append 
the new list to the old value of 'numbers', which as I understand should 
be empty at the moment of the stored continuation?


Regards,

Ricardo


___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users