[plt-scheme] while and return macro?

From: Chongkai Zhu (czhu at cs.utah.edu)
Date: Sun Mar 2 05:01:32 EST 2008

Or if you don't want the explicit "break/return" in the macro:

(define-syntax (while stx)
  (syntax-case stx ()
    ((while cond body ...)
     #`(let/ec #,(datum->syntax-object #'while 'return)
         (let lp ()
           (when cond
             body ...
             (lp)))))))


  Happy Texas Independence Day!

Chongkai



Chongkai Zhu wrote:
> First, you are in a functional programming language. So please stop 
> thinking procedurely.
>
> Most people will use first class continuation to implement break control:
>
> (define-syntax while
>  (syntax-rules ()
>    ((_ break cond body ...)
>     (let/ec break
>       (let lp ()
>         (when cond
>           body ...
>           (lp)))))))
>
> (let ((i 0))
>  (while return
>         true
>         (display i) (newline)
>         (if (< i 10)
>             (set! i (+ i 1))
>             (return i))))
>
>
>
>
> YC wrote:
>> Hi all -
>>
>> what's the way to implement a return (or break) control from a 
>> infinite while loop (i.e. (while true ...))?
>>
>> A while loop with a test condition is straight forward, but I cannot 
>> figure out how to return from an infinite loop. My thought is to 
>> introduce a hidden conditional, and then having the inner return 
>> macro to set the condition to be true, but having the two macros 
>> being separate basically means the return macro's hidden variable is 
>> different from the hidden variable in while loop, so obviously my 
>> approach is incorrect.
>>
>> Below is what I have.  Thanks in advance for suggestions,
>> yc
>>
>> (define-syntax (return stx)
>>   (syntax-case stx ()
>>     ((_ exp)
>>      #'(begin
>>          (set! __ret__ #t)
>>          exp))))
>>
>> (define-syntax (while stx)
>>   (syntax-case stx (true)
>>     ((_ test exp ...)
>>      #'
>>          (let loop ((__ret__ #f))
>>          (cond (test exp ... (loop __ret__)))))
>>     ((_ true exp ...) ;;; this is *incorrect*...
>>      #'(_ (= __ret__ #f) exp ...))))
>>
>> (let ((i 0))
>>     (while true
>>            (display i) (newline)
>>            (if (< i 10)
>>                (set! i (+ i 1))
>>                (return i))))
>> ;; => set!: cannot set undefined identifier: __ret__
>>
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> _________________________________________________
>>   For list-related administrative tasks:
>>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme


Posted on the users mailing list.