This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

searching an explanation: call/cc and 'do' strangeness


We have stumpled across some rather strange looking behaviour when
trying to combine `do' and `call/cc'. I suspect the problem is related
to this paragraph from R4RS:

     `Do' expressions are evaluated as follows: The <init> expressions
     are evaluated (in some unspecified order), the <variable>s are
     bound to fresh locations, the results of the <init> expressions ...
              ^^^^^^^^^^^^^^^

but if anybody can explain precisely (or even vaguely :-) what is
going on in the following code, we would appreciate the enlightment.

The example may seem a bit complex but has been extracted from the
application we are currently working with. The idea is to control a
walk of a datastructure using a kind of co-routine style to control
the communication between the maintainer of the datastructure and the
client doing the walk.

The "server" is implemented by the following function:

    (define invocation-demo #f)

    (define scopeWalkDemo (lambda (continuation)
      (let ((result #f))
	(set! invocation-demo 
	      (if (not continuation)
		  (call-with-current-continuation invocation-demo)
		  (call-with-current-continuation
		   (lambda (found)
		     (let ((l (list 'cow 'horse 'pig )))
		       (do ((i 0 (+ i 1)))
			   ((= i (length l)))
			 (set! result (list-ref l i))
			 (call-with-current-continuation found))
		       (set! result #f))))))
	result)))

which generates a list (containing the symbols cow, horse and pig) and
returns these by subsequent calls of `scopeWalkDemo' as in the
following session:

    guile> (scopeWalkDemo #t)
    cow
    guile> (scopeWalkDemo #f)
    horse
    guile> (scopeWalkDemo #f)
    pig
    guile> (scopeWalkDemo #f)
    #f

Now, suppose I want fill the symbols into a vector using a `do' loop,
I could something like this:

    guile> (define v-demo (make-vector 3))
    guile> 
    (do ((j 0) (cont #t) (tmp #f))	
	((>= j 3)) 
      (display (list cont j v-demo))(newline)
      (set! tmp (scopeWalkDemo cont))
      (vector-set! v-demo j tmp)
      (set! j (1+ j))
      (set! cont #f))
    (#t 0 #(#<unspecified> #<unspecified> #<unspecified>))
    (#f 1 #(cow #<unspecified> #<unspecified>))
    (#f 2 #(cow horse #<unspecified>))
    guile> v-demo
    #(cow horse pig)

But if I try to update `j' using a <step> clause, I get the following:

    guile> (define v-demo (make-vector 3))
    guile> 
    (do ((j 0 (1+ j))(cont #t)(tmp #f))	
	((>= j 3)) 
      (display (list cont j v-demo))(newline)
      (set! tmp (scopeWalkDemo cont))
      (vector-set! v-demo j tmp)
      (set! cont #f))
    (#t 0 #(#<unspecified> #<unspecified> #<unspecified>))
    (#f 1 #(cow #<unspecified> #<unspecified>))
    (#f 1 #(horse #<unspecified> #<unspecified>))
    (#f 1 #(pig #<unspecified> #<unspecified>))
    (#f 1 #(#f #<unspecified> #<unspecified>))
    ERROR: In expression (@call-with-current-continuation proc):
    ERROR: Wrong type to apply: #f
    ABORT: (misc-error)
    guile> v-demo
    #(#f #<unspecified> #<unspecified>)


Or if I move the scopeWalkDemo into the vector-set! expression I get
the following:

    guile> (define v-demo (make-vector 3))
    guile> 
    (do ((j 0) (cont #t))	
	((>= j 3)) 
      (display (list cont j v-demo))(newline)
      (vector-set! v-demo j (scopeWalkDemo cont))
      (set! j (1+ j))
      (set! cont #f))
    (#t 0 #(#<unspecified> #<unspecified> #<unspecified>))
    (#f 1 #(cow #<unspecified> #<unspecified>))
    (#f 2 #(horse #<unspecified> #<unspecified>))
    guile> v-demo
    #(pig #<unspecified> #<unspecified>)


So what is going on. Is our usage of call/cc in error, is this a bug
with `do' or perhaps just a feature of the excessive powers of
call/cc?


---------------------------+--------------------------------------------------
Christian Lynbech          | Telebit Communications A/S                       
Fax:   +45 8628 8186       | Fabrikvej 11, DK-8260 Viby J
Phone: +45 8628 8177 + 28  | email: chl@tbit.dk --- URL: http://www.telebit.dk
---------------------------+--------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - petonic@hal.com (Michael A. Petonic)