and-let*
8章4節、and-let*に関して。
条件式が#fじゃなければその値を使って計算して、その結果で真偽を判定して、#fならば処理を止め、#f以外ならばさらにその値を使って計算して...、みたいな場合、つまり
int val1=0,val2=0,val3=0; if ((0 != (val1 = SomeFunc1())) && (0 != (val2 = SomeFunc2(val1))) && (0 != (val3 = SomeFunc3(val1, val2)))) { SomeFunc4(val3); }
みたいなコードを書こうとしたら、
(let ((val1 (SomeFunc1))) (if val1 (let ((val2 (SomeFunc2 val1))) (if val2 (let ((val3 (SomeFunc3 val1 val2))) (if val3 (SomeFunc4 val3)))))))
とか
(cond ((SomeFunc1) => (lambda (val1) (cond ((SomeFunc2 val1) => (lambda (val2) (cond ((SomeFunc3 val1 val2) => (lambda (val3) (cond (val3 (SomeFunc4 val3)))))))))
みたいに、すぐインデントが深くなって読みにくい!
ってことで、「名前を束縛しつつandみたいにどこかで#fが出たら処理を打ちきる」ための方法がand-let*。
(and-let* ((名前1 S式1) (名前2 S式2) ... (名前n S式n)) 本体のS式)
S式1から順に、評価してはその値で名前を束縛していって、n個全部が#f以外の値だったら「本体のS式」を評価して返す。
S式1〜S式nのうち、どれが#fになったら、ただちに#fを返す。
(名前i S式i)
の部分は、
(S式i)
やら
名前i
ともできて、前者は名前を束縛せずに真偽だけを判定する方法。
後者は変数の値が#fでない場合に処理を続行する方法。