[plt-scheme] Where to introduce the functionality: a function or a macro?
Grant Rettke wrote:
> 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)
> (mark)
> (if cond1
> {printf "Condition 1 met, proceding~n"}
> {return "Condition 1 not, aborting"})
> (mark)
> (if cond2
> {printf "Condition 2 met, proceding~n"}
> {return "Condition 2 not, aborting"})
> (let ([result (+ arg1 arg2)])
> (begin
> (mark)
> (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?
The invocation of a procedure does not add to the continuation. Only the
evaluation of non-tail expressions (procedure arguments, test expression
of a conditional, etc) adds to the continuation. So the continuation
captured by 'mark' doesn't include any part of the 'mark' procedure,
because the continuation is captured (using 'let/cc') in tail position.
Ryan
> (define-syntax define-process
> (lambda (stx)
> (define gen-id ; Source: _TSPL_3rd_Ed_ by Kent Dybvig
> (lambda (template-id . args)
> (datum->syntax-object
> template-id
> (string->symbol
> (apply
> string-append
> (map
> (lambda (x)
> (if (string? x) x
> (symbol->string (syntax-object->datum x))))
> args))))))
> (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))])
> (syntax
> (define (constructor-name args ...)
> (define (mark)
> (let/cc resume-here (set! impl resume-here)))
> (define (name)
> (call/cc impl))
> (define (impl return)
> (begin
> command
> commands ...))
> name)))))))
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme