[plt-scheme] Where to introduce the functionality: a function or a macro?

From: Grant Rettke (grettke at acm.org)
Date: Sun Dec 2 01:31:26 EST 2007

The macro at the end of this email allows the user to define processes
that can abort and continue using continuations.

Here is an example:

(define cond1 #f)
(define cond2 #f)
(define-process (foo-process arg1 arg2)
  (printf "Starting the proceess with args: ~a ~a~n" arg1 arg2)
  (if cond1
      {printf "Condition 1 met, proceding~n"}
      {return "Condition 1 not, aborting"})
  (if cond2
      {printf "Condition 2 met, proceding~n"}
      {return "Condition 2 not, aborting"})
  (let ([result (+ arg1 arg2)])
      (return result))))

'mark' sets a point from which to continue and 'return' aborts the process.

'mark' is implemented as a function. This behaves as expected, but I
don't think that this is the right way to do it because when the
continuation is called again, it will really continue at the end of
the 'mark' function and then return to the expected place in the impl
function. So this gets the desired behavior, but it really ought not
continue from within the mark function.

How do I implement 'mark' so that the continuation will be set
directly within the impl function?

(define-syntax define-process
  (lambda (stx)
    (define gen-id ; Source: _TSPL_3rd_Ed_ by Kent Dybvig
      (lambda (template-id . args)
            (lambda (x)
              (if (string? x) x
                  (symbol->string (syntax-object->datum x))))
    (syntax-case stx ()
      ((_) (raise-syntax-error #f "a process requires a name and at
least one command" stx))
      ((_ (name args ...)) (raise-syntax-error #f "a process requires
at least one command" stx))
      ((_ (name args ...) command commands ...)
       (with-syntax ([constructor-name (gen-id (syntax name) "make-"
(syntax name))]
                     [return (syntax-local-introduce (syntax return))]
                     [mark (syntax-local-introduce (syntax mark))])
          (define (constructor-name args ...)
            (define (mark)
              (let/cc resume-here (set! impl resume-here)))
            (define (name)
              (call/cc impl))
            (define (impl return)
                commands ...))

Posted on the users mailing list.