任意の式がエラーをスローしたかどうかをテストする関数を Guile で作成しようとしていますが、壁にぶつかっています。
(define (error-or-not qqx)
(if
(catch
#t
(lambda () ,qqx)
(lambda (k . args) #t))
#t
#f))
(display (error-or-not `(/ 1 0))) ; => #t (1)
(newline)
(display (error-or-not `(/ 1 1))) ; => #t (2)
(newline)
qqx
関数内で評価されerror-or-not
、エラーが発生するかどうかをテストする準引用符付きの式です。
Guile のマニュアルでは、評価qqx
でエラーが発生した場合、catch
関数は 3 番目の引数 (引数を取るラムダ) を呼び出して取得した値を返すと述べています。実際にエラーが発生した場合、これは正常qqx
に機能します (上記の #1 を参照)。
しかし、マニュアルには、エラーがなければ、catch
関数は を評価して値を返すとも書かれていますqqx
。2 つのケースを区別できないため、これはうまくいきません (上記 #2 を参照)。
エラーが発生しなかったことを明確に伝える方法を誰かが指摘できますか?
アップデート
Chris Jester-Young が私の間違いを指摘しました。以下の受け入れられた回答を参照してください。完全を期すために、私が使用している彼のコードのバージョンを投稿しています (Guile 1.8.8 にバックポートされています):
(use-syntax (ice-9 syncase))
(define (stub retval) (lambda args retval))
(define-syntax error-or-not
(syntax-rules ()
((_ expr ...)
(catch #t (lambda () expr ... #f) (stub #t)))))
(display (error-or-not (/ 1 0))) ; => #t
(newline)
(display (error-or-not (/ 1 1))) ; => #f
(newline)