Emacsをお使いの皆さんは、if-let
/when-let
マクロをご存知でしょうか?
Rustには、以下のサンプルのようにパターンマッチを利用して便利に条件分岐できるif let構文があります。
if let Some(i) = letter {
println!("Matched {:?}!", i);
} else {
// Destructure failed. Change to the failure case.
println!("Didn't match a number. Let's go with a letter!");
}
Emacs Lispのif-let
/when-let
は、Rustのif let
と同じものではありませんが、束縛される値がnil
でないかどうかに応じて分岐する便利なマクロでした。
(if-let (c (get-letter-from-another-dimension))
(format "Matched %s" c)
"Not matched")
残念ながら、if-let
/when-let
は、Emacs 31.1(2024年12月現在の最新安定バージョンは29.4、もうすぐリリースされるのが30.1です)では廃止予定となり、if-let
/when-let
を使っているとコンパイル時に以下のような警告が表示されます。
Warning: ‘if-let’ is an obsolete macro (as of 31.1); use ‘if-let*’ instead.
if-let
/when-let
の代わりにif-let*
/when-let*
を使ってほしいとのことです。if-let*
/when-let*
では、以下のように1個以上の複数のバインディングを指定することができ、すべての値がnil
でない場合にのみ真と判定されます。
(if-let* ((c1 (get-letter-from-another-dimension))
(c2 (get-letter-from-another-dimension)))
(format "Matched both %s and %s" c1 c2)
"At least one is not matched")
if-let
/when-let
を使っている既存のコードはすべて書き換えなければいけません。 以下の式をバッファ(ファイル)の先頭で評価すると、バッファ内のすべてのif-let
/when-let
がif-let*
/when-let*
に書き換えられます。 if-let
/when-let
を見つけたら修正PRを送りましょう。
(while (re-search-forward (rx symbol-start (or "when-let" "if-let") symbol-end) nil t)
(replace-match (concat (match-string 0) "*"))
(when (looking-at (rx (+ space)))
(goto-char (match-end 0)))
(insert-char ?\()
(forward-sexp)
(insert-char ?\)))