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-16

DylanでL-99 (P02 最後2つの要素)

| 14:42 | DylanでL-99 (P02 最後2つの要素) - わだばLisperになる を含むブックマーク はてなブックマーク - DylanでL-99 (P02 最後2つの要素) - わだばLisperになる

マニュアルを読んでも、あまり書法が理解できないので、参考にできそうなコードを探してみたところ、DylaのCL風ライブラリというものを発見。

作者は、Scott MacKay氏ですが、元Symbolicsの人で、現在ITAに所属しているらしいというLISP街道まっしぐらな方のようです。

Dynamic Languages Wizards Series, Spring 2001にもDavid Moon氏等と一緒にパネリストとして出演してたのを見たことがあります。

とりあえず、真似するのが良いかなと思って、MacKay氏のスタイルを真似。

最初にgenericを作成して、後で特定化されたmethodを追加し、Dylanでは、返り値の型を明示することができるのですが、そこはきっちり書くというスタイルのようです。

let list = #(foo:, bar:, baz:);
format-out("%=\n", last2(list));
// => #(#"bar", #"baz")

let list = #();
format-out("%=\n", last2(list));
// => #()

// Code
module: l99-02

define generic last2
    (sequence :: <sequence>) 
 => (result :: <sequence>);

define method last2
    (sequence :: <list>)
 => (result :: <list>)
  if (2 >= size(sequence))
    sequence
  else
    last2(tail(sequence))
  end if
end method last2;

比較としてCLOSでも考えてみました。

Dylanと違ってdefgenericで返り値の型は指定できないようなので、documentationを付けてるだけです(笑)

返り値の型の指定はどうやったら良いかなと思いましたが、theを付ければ良いだけなんでしょうか。どういうのが定石なんでしょう…。

もしくは、aroundや、afterメソッドで返り値の型をチェックする、なども可能だったりするんでしょうか?

返り値の型を明示するというのは、CLのようにインクリメンタルにコンパイル可能で会話的に開発できる言語でも、割と御利益が多いんじゃないかと思うのですが、どうでしょう。

自分はコンパイラが教えてくれる情報が多くなるので、なんとなく好みです。

(defgeneric last2 (sequence)
  (:documentation "last2"))

(defmethod last2 ((sequence list))
  (if (>= 2 (length sequence))
      (the list sequence)
      (last2 (cdr sequence))))