[racket] Behavior of continuation-mark-set->list and continuation-mark-set-first with respect to key values

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Sun May 6 21:57:02 EDT 2012

Do you mean to just leave the quote off of the usage example?

If not, you could do something like the below (note that this doesn't
do a good job of error reporting and the test module requires a git
version of racket to run).

Robby

#lang racket

(define-syntax-rule
  (with-continuation-marks keys vals body)
  (with-continuation-marks/proc keys vals (λ () body)))

(define (with-continuation-marks/proc keys vals thunk)
  (let loop ([keys keys]
             [vals vals])
  (cond
    [(null? keys)
     (thunk)]
    [else
     (with-continuation-mark (car keys) (car vals)
       (loop (cdr keys)
             (cdr vals)))])))

(module+ test
  (require rackunit)
  (check-equal?
   (continuation-mark-set->list
    (with-continuation-marks '(id1 id2 id3)
                             '(1 2 3)
                             (current-continuation-marks))
    'id1)
   '(1)))


On Sun, May 6, 2012 at 8:10 PM, Galler <lzgaller at optonline.net> wrote:
> Thanks Robby.
>
> I'm attempting to implement the behavior described in Section 3.2 of your
> 2007 paper, specifically
>
> "each continuation frame can have any number of marks with distinct keys"
>
> by defining a new 'with-continuation-marks' syntax which will set up
> arbitrary number of nested 'with-continuation-mark' calls in response to a
> list of keys
>
> As Eli B. picked up on earlier, I'm having trouble with Chapter 16 of the
> Racket Guide and its a mess at the moment.
>
>
>
> Is there a basic example of pattern matching for a list of arbitrary number
> of elements (including zero)? I
>
>
> ; usage (with-continuation-marks '(id1 id2 id3) body)
>
> ;this doesn't work because of bad pattern matching in the
> with-continuation-marks macro.  (make-binding ...) just sets up storage.
> ;its the '(id1 id2 id3) in the arguments that's causing the problem.
>
>
> (define-syntax with-continuation-marks
>  (syntax-rules ()
>    [(with-continuation-marks (id) body) (with-continuation-mark id
> (make-binding id) body)]
>    [(with-continuation-marks (id1 id2 ...) body) (with-continuation-mark id1
> (make-binding id1) (with-continuation-marks (id2 ...) body ))]))
>
>
>
> On Sun, May 6, 2012 at 9:56 AM, Robby Findler wrote:
>
>> continuation-mark-set->list always does return all of the bindings,
>> but continuation marks are carefully designed to avoid breaking tail
>> recursion (they let you understand the tail behavior of your program,
>> more accurately) so that's why you see only one binding.
>>
>> continuation-mark-set-first can be more efficient than
>> continuation-mark-set->list and it is more likely to work in futures.
>> That's the only reason it exists.
>>
>> Robby
>>
>> On Sat, May 5, 2012 at 11:02 PM, Galler <lzgaller at optonline.net> wrote:
>>>
>>> BACKGROUND:
>>>
>>> Per the documentation:
>>>
>>> with-continuation-mark  causes a key to be associated with a binding
>>> within
>>> a continuation frame
>>>
>>> continuation-mark-set->list returns the binding(s) associated with that
>>> particular key, for any given continuation-mark-set
>>>
>>> while
>>>
>>> continuation-mark-set-first returns the first (innermost) binding
>>> associated
>>> with a particular key
>>>
>>> QUESTIONABLE  BEHAVIOR
>>>
>>> The issue is:
>>>
>>> if a key is reused, the only binding continuation-mark-set->list returns
>>> is
>>> the innermost binding.
>>>
>>> So continuation-mark-set->list could only possibly return **one** value
>>>
>>> and
>>>
>>> continuation-mark-set-first  appears redundant
>>>
>>> Is that the desired behavior? I would have expected
>>> continuation-mark-set->list to return all the bindings for a particular
>>> key.
>>>
>>> Additionally, I suspect continuation-mark-set->context has to be
>>> implemented
>>> using the 'return a list of all bindings for a single key' behavior,
>>> since
>>> the documentation indicates it uses a single private key.
>>>
>>>
>>> EXAMPLE
>>>
>>> #lang racket
>>> (with-continuation-mark 'global  'outermost-value
>>>  (let/cc k-outer
>>>    (with-continuation-mark 'global 'middle-value
>>>      (let/cc k-inner
>>>        (with-continuation-mark 'global 'inner-value (begin
>>>                                                       (display
>>> (continuation-mark-set->list (current-continuation-marks) 'global))
>>>                                                       (newline)
>>>                                                       (display
>>> (continuation-mark-set->list (continuation-marks k-inner) 'global))
>>>                                                       (newline)
>>>                                                       (display
>>> (continuation-mark-set->list (continuation-marks k-outer) 'global))
>>>         ))))))
>>>
>>> ;Returns
>>>
>>> ;(inner-value)
>>>
>>> ;(middle-value)
>>>
>>> ;(outermost-value)
>>>
>>> but I would have expected:
>>>
>>> ;Returns
>>>
>>> ;(inner-value) (middle-value) (outermost-value)
>>>
>>> ;(middle-value) (outermost-value)
>>>
>>> ;(outermost-value)
>>>
>>>
>>> Thanks very much for looking at this.
>>>
>>> R/
>>>
>>> Zack
>>> ____________________
>>>  Racket Users list:
>>>  http://lists.racket-lang.org/users


Posted on the users mailing list.