Scheme で length 手続きを再実装

久しぶりに Scheme の勉強。

R5RS を読んでいて気になるのが、list と vector と string に対して、それぞれ似たような、だけど専用の名前の関数が用意されていること。

その中でも極めつけが length 関数。

Python だと len 関数、Haskell だと length 関数にどんな型でも渡して長さが取れる。

だけど、Scheme だと list は length、vectorvector-length、string なら string-length という関数を呼び分ける必要がある。

これは PythonHaskell のように集約させたくなる。


ということで再実装した length 関数。

(define list-length
  (lambda (a)
    (let loop (
        (x a)
        (len 0))
      (if (null? x)
        len
        (loop (cdr x) (+ len 1))))))

(define list
  (lambda (a)
    (if (list? a) (list-length a)
      (if (string? a) (string-length a)
        (if (vector? a) (vector-length a)
          ; ここでエラーを発生させたい
          )))))


R5RS には、length、vector-length、string-length に、それらが期待する以外の型を渡すとどうなるのか、というところまでは記載されていないので、実装依存なのかもしれないけど、Gauche はエラーが発生するので、再実装した length でもエラーを発生させたかったんだけど、その方法がわからない。エラーを発生させる、という仕様も R5RS には定義されていないようだ。