Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-04-18

CLOSで返り値の型チェックはできたりするのか

| 12:20 | CLOSで返り値の型チェックはできたりするのか - わだばLisperになる を含むブックマーク はてなブックマーク - CLOSで返り値の型チェックはできたりするのか - わだばLisperになる

やりたいこと:

Dylanや、GOOのように総称関数で全体の返り値の型を指定してチェックしたい。

考えてみたこと/試してみたこと:

返り値の型をチェックするのに共通のaroundメソッドを定義すれば良いのかなと思い、試してみる。

感想:

一応できてはいるけど…

  1. どっちにしろ動的に基本メソッドを実行した後にチェックするので微妙。
  2. あんまり綺麗に書けてないし、これでは逆にバグの元になりそう。
  3. コンパイラが型の不整合を教えてくれることも期待できないのかも。
  4. defgenericで宣言したい。

マクロにすれば良いんだろうけど、こういう場合の定番の書法があれば、定番書法が知りたい。きっとDylan風にしたい、って人は過去にいた筈。

MOPは良く分からないけど、こういうのはMOPの領域に踏み込む必要があるんだろうか…。

;; あまり役に立っていない微妙なdefgeneric
(defgeneric sequence=>string (arg)
  (:documentation "sequence=>string"))

;; sequenceクラス全般
(defmethod sequence=>string ((arg sequence))
  (format t "sequence -> ~A" arg)
  arg)

;; listに特化 ここでは単に次に特定できるものを呼んでるだけなのであまり意味なし
(defmethod sequence=>string ((arg list))
  (call-next-method))

;; theでstringかどうかをチェック
(defmethod sequence=>string :around ((arg sequence))
  (let ((res (call-next-method)))  ;theに直接全部詰め込むと、難しくて判定できないらしい。
    (the string res)))

;; 実験
(sequence=>string "foo")
>>> sequence -> foo
(sequence=>string '(foo bar baz))
error:>>> The value (FOO BAR BAZ) is not of type STRING.