Posted 2020-09-22 00:51:35 GMT
LispWorksでコードを書いていて、
(let ((x 42)
(x 69))
x)
→ 42
みたいなものがエラーにならなかったので、コンパイラの最適化のバグか何かかと思って他の処理系でも試してみたところ、SBCLやCMUCL、ECLではエラーになるものの他の処理系では特にエラーにならないようです。
もしや規格上は問題ないのかと思ってHyperSpecを確認してみると、特に記載がない様子。
Common Lispはlambda
に展開される訳ではないので、lambda
での重複チェックとは別になっているのかなと思い、lambda
も確認してみましたが、
((lambda (x x) x) 42 69)
→ 69
これもSBCLやCMUCL、ECL、CCL以外では、エラーにならない様子(CCLはこちらはエラーにするらしい)
λリストについても、重複については特に記載がない様子。
Scheme(R7RS)ではエラーと規定されているので、そういうものだと思っていましたが、実際の処理系で試してみると、Schemeの処理系でも動作はまちまちでした。
Scheme流の「エラーという定義だけど、どうエラーを処理するかは規定しない」ってやつでしょうか。
束縛部の変数名の重複チェックが緩いのは、バグの元になるので、何らかの方法でユーザーに通知して欲しいですね。
マクロでコード生成するのが頻繁なLisp系言語では特にですが。
SBCLで虫取りが捗るのは、割とこういう類のチェックが充実しているというのもあると思います。
■
HTML generated by 3bmd in LispWorks Personal Edition 7.1.2