[racket] Problem with macro

From: Harry Spier (vasishtha.spier at gmail.com)
Date: Sat Sep 1 18:09:22 EDT 2012

Dear list members,

I'm trying to work my way through Racket continuations by going
through the Guide and Reference.  And as part of that I set up small
examples and sometimes macros to simplify the syntax so I can see more
clearly whats going on.

So I made a let type form of call-with-continuation-prompt called
let/set-prompt as follows and a small example as follows:
--------------------------------------------------------
;(let/set-prompt prompt handler body)
; prompt and handler are optional
; Examples:
; let/set-prompt () (+ 1 2 3 4))
; let/set-prompt prompt-1 () (+ 1 2 3 4))
;let/set-prompt prompt-1 handler-1 () (+ 1 2 3 4))
(define-syntax let/set-prompt
  (syntax-rules ()
    [(_                ARGS BODY) (call-with-continuation-prompt (let
ARGS (λ () BODY)))]
    [(_ PROMPT         ARGS BODY) (call-with-continuation-prompt (let
ARGS (λ () BODY)) PROMPT)]
    [(_ PROMPT HANDLER ARGS BODY) (call-with-continuation-prompt (let
ARGS (λ () BODY)) PROMPT HANDLER)]))

(define-syntax abort-to-prompt
  (syntax-rules ()
     [(_ VAL) (abort-current-continuation
(default-continuation-prompt-tag) (thunk VAL))]
     [(_ PROMPT-TAG VAL) (abort-current-continuation PROMPT-TAG (thunk VAL))]))


(define prompt-1 (make-continuation-prompt-tag))
(define prompt-2 (make-continuation-prompt-tag))
(define prompt-3 (make-continuation-prompt-tag))

(define (play-with-prompts [p (default-continuation-prompt-tag)])
  (+ 1
     (let/set-prompt prompt-1 () (+ 10
        (let/set-prompt prompt-2 () (+ 100
           (let/set-prompt prompt-3 () (+ 1000
              (abort-to-prompt p 0) 2000)) 200)) 20))))


(play-with-prompts prompt-1)
(play-with-prompts prompt-2)
(play-with-prompts prompt-3)
(play-with-prompts)
-------------------------------------------------
This works fine  for this example but the let/set-prompt macro has
problems. It can only take a single body so it can mimic (let ()(+ 1 2
3))
but it can't mimic (let () 1 2 3)  etc.

So I tried modifying the macro to the following.

;(let/set-prompt args prompt (body ...))
(define-syntax let/set-prompt
  (syntax-rules ()
    [(_                ARGS (BODY ...)) (call-with-continuation-prompt
(let ARGS (λ () BODY ...)))]
    [(_ PROMPT         ARGS (BODY ...)) (call-with-continuation-prompt
(let ARGS (λ () BODY ...)) PROMPT)]
    [(_ PROMPT HANDLER ARGS (BODY ...)) (call-with-continuation-prompt
(let ARGS (λ () BODY ...)) PROMPT HANDLER)]))

but then when I execute:
(play-with-prompts prompt-1)
(play-with-prompts prompt-2)
(play-with-prompts prompt-3)
(play-with-prompts)

I no longer get the correct results of

1
31
331

but I get this instead.
1
21
21

Any suggestions of what the problem could be.  (I haven't had great
success using the macro stepper up till now..  Does  anyone have any
documentation on its use with some simple examples.)  Also I'm a
little familiar with syntax-id-rules but not syntax-case.

Thanks,
Harry Spier


Posted on the users mailing list.