命令型言語とは異なり、変数を使用したり、回避できる場合は変数を更新しdefine
たりしないでください。set!
ジェネレーターのように、状況によっては必要になります。これを行いたい完全なコード例がないため、どのような明白な解決策を使用するかわかりません。
let
または再帰の場合に中間値を格納する方法:
;; within the let block x shadows the original x
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
(do-something x))
あなたはいくつかの中間体を行うことができますlet*
(let* ((tmp (+ x y))
(tmp2 (* tmp y))) ; tmp is bound here
(do-something-with tmp2)); or tmp and tmp2
再帰によって内側の手順で cur と lst を更新する再帰を使用できます。
(define (mmin x . xs)
(define (min-aux cur lst)
(cond ((null? lst) cur)
((<= cur (car lst)) (min-aux cur (cdr lst)))
(else (min-aux (car lst) (cdr lst)))))
(min-aux x xs)) ; start recursion
すでに定義されているものに対するエラーであるdefine
ため、定義したのはそのためです
このトップレベルを行う必要がある場合は、次のことができます。
(define min_xy (if (< x y) x y))
min_xy
. バインディングを破壊的に変更する (別の値を参照するように取得する) には、次を使用できます。set!
(set! x (+ x 1)) ; increases x
最もローカルな定義を変更しますが、それがまだ存在しない場合はエラーになります。これは、ジェネレーターの作成に使用できます。
(define (generator start alter-proc)
(lambda () ; returns a procedure taking 0 arguments
(let ((old start)) ; temporary store what start points to
(set! start (alter-proc start)) ; change what the local start points to
old))) ; return the old value
(define counter (generator 1 (lambda (x) (+ x 1))))
(counter) ; ==> 1
(counter) ; ==> 2
(define doubler (generator 1 (lambda (x) (* x 2))))
(doubler) ; ==> 1
(doubler) ; ==> 2
(doubler) ; ==> 4