npt-japanese

% Macro WITH-SIMPLE-RESTART

UP


Macro WITH-SIMPLE-RESTART

Macro WITH-SIMPLE-RESTART

構文

with-simple-restart (name format-control format-argument*) form*
=> result

引数と戻り値

name - シンボル
format-control - format-control
format-argument - オブジェクト(これはformat-arguments)
form - 暗黙のprogn
result - 通常の状況ではformによる返却値であり、 nameというrestartが起動されたことによる例外的な状況では、 2つの値niltが返却されます。

定義

with-simple-restartrestartを確立します。

もしnameで指定されたrestartform実行中に起動されなかったら、 formの最後から返却される全ての値が返却されます。 もしnameで指定されたrestartform実行中に起動されたら、 制御はwith-simple-restartへ遷移し、 2つの値niltが返却されます。

もしnamenilのとき、 匿名のrestartが確立されます。

format-controlformat-argumentは、 restartの報告のときに使用されます。

例文

(defun read-eval-print-loop (level)
  (with-simple-restart (abort "Exit command level ~D." level)
    (loop
      (with-simple-restart (abort "Return to command level ~D." level)
        (let ((form (prog2 (fresh-line) (read) (fresh-line))))
          (prin1 (eval form)))))))
=>  READ-EVAL-PRINT-LOOP
(read-eval-print-loop 1)
(+ 'a 3)
>>  Error: The argument, A, to the function + was of the wrong type.
>>         The function expected a number.
>>  To continue, type :CONTINUE followed by an option number:
>>   1: Specify a value to use this time.
>>   2: Return to command level 1.
>>   3: Exit command level 1.
>>   4: Return to Lisp Toplevel.
(defun compute-fixnum-power-of-2 (x)
  (with-simple-restart (nil "Give up on computing 2^~D." x)
    (let ((result 1))
      (dotimes (i x result)
        (setq result (* 2 result))
        (unless (fixnump result)
          (error "Power of 2 is too large."))))))
COMPUTE-FIXNUM-POWER-OF-2
(defun compute-power-of-2 (x)
  (or (compute-fixnum-power-of-2 x) 'something big))
COMPUTE-POWER-OF-2
(compute-power-of-2 10)
1024
(compute-power-of-2 10000)
>>  Error: Power of 2 is too large.
>>  To continue, type :CONTINUE followed by an option number.
>>   1: Give up on computing 2^10000.
>>   2: Return to Lisp Toplevel
>>  Debug> :continue 1
=>  SOMETHING-BIG

副作用

なし。

影響

なし。

例外

なし。

参考

restart-case

備考

with-simple-restartは、 もっとも一般的に使用されるrestart-caseの 短縮形のひとつです。

with-simple-restartは次のように定義できます。

(defmacro with-simple-restart ((restart-name format-control
                                             &rest format-arguments)
                               &body forms)
  `(restart-case (progn ,@forms)
     (,restart-name ()
         :report (lambda (stream)
                   (format stream ,format-control ,@format-arguments))
        (values nil t))))

例外的な状況では第二返却値がtになるため、 通常の場合は第二返却値を省略するかnilにして、 2つの状況を区別できるようにするのが一般的です(ただし必須ではありません)。


TOP, Github