2016-07-31 56 views
0

我可以在球拍使用「而」循環與代碼While Loop Macro in DrRacket從環球拍使用break

(define-syntax-rule (while-loop condition body ...) 
    (let loop() 
    (when condition 
     body ... 
     (loop)))) 

不過,我想用一個無限循環內線突破如下:

(define (testfn) 
    (define x 5) 
    (while-loop #t   ; infinite while loop; 
    (println x) 
    (set! x (sub1 x)) 
    (when (< x 0) 
     (break))))   ; HOW TO BREAK HERE; 

如何在上面的無限循環中插入break?感謝您的評論/答覆。

+1

在問題的代碼使用一個命令行式風格,這不是我們如何寫在方案一環。 –

回答

3

你不知道。球拍在Scheme系列中,因此所有的循環實際上都是通過遞歸完成的。

通過不遞歸,您擺脫了循環。任何其他值都將成爲表單的結果。

(define (helper x) 
    (displayln x) 
    (if (< x 0) 
     'return-value 
     (helper (sub1 x))) 
(helper 5) 

有宏使得語法更簡單。使用命名let是:

(let helper ((x 5)) 
    (displayln x) 
    (if (< x 0) 
     'return-value 
     (helper (sub1 x))) 

看着你while-loop只是使用命名let宏變成了遞歸程序的宏。

如果你不用#t寫一個表達式,最終會變成假,它停止。像:

(while-loop (<= 0 x) 
    ...) 

注意,使用set!以更新循環變量不被認爲是很好的做法。如果您正在學習球拍,請儘量不要使用set!或您的新循環結構。嘗試使用名爲letletrec

2

正如在鏈接問題的接受答案中提到的,它是而不是推薦 - 根本!以這種方式循環。使用標準方案時避免使用命令循環並優先遞歸(使用助手程序或名爲let),或在球拍中使用iterations and comprehensions。並且,break不是標準的Scheme構造。考慮使用更地道球拍,不需要明確的斷裂,避免了命令行式風格重寫邏輯:

(define (testfn n) 
    (for [(x (in-range n -1 -1))] 
    (println x))) 

(testfn 5) 
=> 5 
    4 
    3 
    2 
    1 
    0