Scheme:Lisp プログラマのためのPerl入門
Lisp が広く使われるようになった将来。Lisp プログラマが他言語を使わなくてはならないとき、とまどうことが多いかと思います。そのような将来必要になる情報をまとめることで逆に現在 Lisp プログラマを増やせるのではないか?という作戦です。 http://www.norvig.com/python-lisp.html , http://www.unixuser.org/~euske/doc/python/python-lisp-j.html 「Lisp プログラマのためのPython」入門を意識しています。 Perl/Lisp に詳しい方に足していただければ、、と思います。
Perl 入門
Lisp/Perl はインタプリタ型|コンパイラ型で、オブジェクト指向を備えた高水準プログラミング言語です。
Key Feature | Lisp Feature | Perl 5 Feature | Perl 6 Feature |
すべてはオブジェクト | Yes | No | Yes |
リストにいろいろなものを入れられる | Yes | Yes | Yes |
複数のパラダイム | Yes | Yes | Yes |
記憶管理 | GC | Reference Counter | GC (parrot) |
マクロ | Yes | No (ただしSource Filterあり) | Yes |
対話的なループ | Yes | No (perl -de 1) | YES |
簡潔かつ表現力ある言語 | |||
プラットフォーム間での移植性 | Windows, Mac, Unix, Linux | Windows, Mac, Unix, Linux | Windows, Mac, Unixen ... |
実装の数 | たくさん | ひとつ | 複数 (ただし現時点ではpugsのみ) |
Lisp プログラマが Perl を学ぶときの要点
- Perl は Lisp ほど関数的でない。map, grep などの便利な構文、無名関数はある。
- Perl のオブジェクトは「リファレンス変数を bless したもの」。
- bless とはパッケージ名をリファレンス変数に結びつけるもの。
- Perl には構文上はクラスがない代わりに、
bless された package(名前空間)を使ってメソッドディスパッチをする。
- 便宜上、パッケージ名をクラスということは多い。
- Perl のオブジェクトはデータ型についての情報は持たない。(メソッドだけ。)
- Perl のクロージャーは sub で作る。Perl 6 ではより簡潔に作れる。
# 加算関数 #!/usr/bin/perl use strict; use warnings; sub make_adder { my $n = shift; return sub { my $x = shift; return $x + $n; }; } my $add3 = make_adder(3); printf "%s\n", $add3; printf "> %s\n", $add3->(2); my $add27 = make_adder(27); printf "%s\n", $add27; printf "> %s\n", $add27->(2);
# counter sub counter { my $counter = 0; # reset and stamp return ( sub { $counter = 0; return $counter; }, sub { $counter++; return $counter; } ); } my ($reset, $stamp) = counter(); printf "%s %s\n", $reset, $stamp; printf "%s %s %s %s\n", $stamp->(), $stamp->(), $reset->(), $stamp->();
- perl6 では {} の中身はすべてclosureである。forやifなども例外ではない。
- perl6 の実例
# 上記の例 sub make_adder($n){ sub($x){ $x + $n } } sub counter { my $counter = 0; return ( sub{ $counter = 0 }, sub{ $couter++} ); }
# closureいろいろ sub($x){ $x + 1 } # 基本形 -> $x { $x + 1 } # -> を使うとargumentを()でくくらなくてもよい { $^x + 1 } # placeholderを使って
# 無名なのにcombinatorなしで再帰! { $^n <= 1 ?? 1 !! $^n * &?BLOCK($^n - 1) }.(10) # fact(10)
議論
- Lispはインタプリタ型とは限りませんよ。
- とおる。(2006/03/14 05:22:16 PST): Perl には Lisp のマクロほど使いやすいのはないですが、 ソースフィルタというのがあります。 でも恐ろしいので、ぼくは使ったことがありません。 http://search.cpan.org/~nwclark/perl-5.8.8/pod/perlfilter.pod
- えんどう(2006/04/01 16:31:54 PST)おお、ぜひhttp://karetta.jp/ でも執筆してください。PerlにGCってありましたっけ? リファレンスカウントしかなかったのでは?
- とおる。(2006/04/06 03:00:02 PDT): たしかリファレンスカウントだけですが、まあ広い意味では GC だと思っていいんじゃないですかね。 中途半端ですが、以前書いた Perl のオブジェクトシステムの話をさらしておきます。
- Y-Combinator の比較 http://blog.livedoor.jp/dankogai/archives/50458503.html
- 弾 &{$code}()をより現代的な$code->()に書き換えました。Perl 5とPerl 6を表で分けました。その他追補しました。2006/04/16 12:11:36 PDT
- Perl 6 好きになれそうです。Perl 5 のコードを短く見えるようにしました。
- koguro(2006/04/17 07:54:45 PDT): ここで比較しようとしているLispはCommonLispでしょうか、それともSchemeでしょうか? Lispといってもいろいろな言語仕様があるのでPerlと比較する場合は対象を絞った方がよいと思いますがどうでしょう(Schemeですべてがオブジェクトかというとちょっと微妙な気がしますし)。
- Shiro(2006/04/17 17:47:54 PDT): まーそうなんですけれども、元ネタのNorvigの文書からして そう厳密に話を進めてるわけじゃなくてむしろネタなんで、こちらもネタと割り切って Perl6の機能がLisperから見てどんなふうに見えるか、なんて四方山話にしちゃった方が おもしろくなるんじゃないかと思います。
- えんどう(2006/04/17 23:11:47 PDT)ここはWiLiKiだし、暗黙のターゲットはGaucheで良いのではないでしょうか?
- koguro(2006/04/18 07:16:18 PDT): そうですね、たしかにあんまり細かくしない方が良さそうですね。ところで、私もここの文章読んだら「Perl6ってなんか良さそう」って思うようになってきました。