Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

A student's question

Name: Anonymous 2011-05-30 12:20

My teacher keeps drilling into our collective heads that using the break command is harmful, and that if we wish to terminate a loop early it would be far better to create a boolean variable, set it to 0, and add a condition to the head of the loop, and set the boolean variable to 1 when a break is needed. Note that this way you actually have to check this every single loop (where it is not needed almost every time) as well as waste a command to reset the boolean in case it was set to true.

Is there a reason to this?

Name: Anonymous 2011-05-30 17:15

>>16-23
But Scheme has break and continue! They are called call-with-current-continuation!
This should be portable R6RS code, but it is untested
(define-syntax while
  (lambda (stx)
    (syntax-case stx ()
      ((while cond body body+ ...)
       (with-syntax ((break (datum->syntax #'body 'break))
                     (continue (datum->syntax #'body 'continue)))
         #'(let loop ()
             (call-with-current-continuation
              (lambda (break)
                (let loop ()
                  (when cond
                    (call-with-current-continuation
                     (lambda (continue)
                       body body+ ...))
                    (loop)))))))))))

(define-syntax for
  (lambda (stx)
    (syntax-case stx ()
      ((for init cond incr body body+ ...)
       (with-syntax ((break (datum->syntax #'body 'break))
                     (continue (datum->syntax #'body 'continue)))
         #'(call-with-current-continuation
            (lambda (break)
              init
              (let loop ()
                (when cond
                  (call-with-current-continuation
                   (lambda (continue)
                     body body+ ...))
                  incr (loop))))))))))

;(while #t (display "read ") (display "SICP "))
; => read SICP read SICP read SICP
;(while #t (display "read ") (continue) (display "SICP"))
; => read read read read ...
;(while #t (display "read ") (break) (display "SICP"))
; => read


Yes, continue does the right thing in for (executes incr).
If you had read your SICP today, you would've known. You also would known that all the call-with-current-continuations can be optimized to call-with-escape-continuations.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List