[LSP42] Perl
(この記事はLISP Implementation Advent Calendar 4日目のためのエントリです。)
PerlでLISPを作りました。
https://github.com/zick/PerLisp
動機
今年の春、訳あって42個のプログラミング言語でLISP処理系を実装することになりました。これはその6つ目です。
Perlという言語を選んだのは同僚からRを推薦された時に、私がPerlと聞き間違えたのがきっかけだったような気がします。
まるでCのような安心感
私はPerlをほとんど書いたことがなかったのですが、ウェブサイトのカウンタや掲示板を書くのによく使われていた、だれでも気軽に書ける「チャラチャラした言語の筆頭格」と認識していました。でもいざ触ってみたら、変数は宣言するし、セミコロンをちゃんと書かないといけないし、ifやforのあとの括弧も省略できないし、意外とチャラチャラしていませんでした。むしろCのような安心感がありました。
一番驚いたのは「参照」の存在です。Perlと言えばなんでも無駄にコピーされるという認識だったのに、参照のおかげで安心してプログラムが書けます。あと、Perlといえば変数の前に $ を付けますが、配列だと @ で ハッシュだと % を付けるという面倒なルールがありますが、参照を使うと、常に $ しか使わなくていいというのも良かったです。参照の dereference にも $ を使うので、非常にお金の臭がするプログラムが書けます。
sub makeCons { my ($a, $d) = @_; # 中括弧{}を使えるとハッシュの参照が得られる return { tag => 'cons', car => $a, cdr => $d }; } sub pairlis { my ($lst1, $lst2) = @_; my $ret = $kNil; while ($$lst1{tag} eq 'cons' && $$lst2{tag} eq 'cons') { # dereference してから tag にアクセス $ret = makeCons(makeCons($$lst1{car}, $$lst2{car}), $ret); $lst1 = $$lst1{cdr}; # cdr にも参照が入っているはずなので参照がコピーされる $lst2 = $$lst2{cdr}; # 実体はコピーされない } return nreverse($ret) }
まるでCと違う不安感
Perlを高級なC言語と思うと、悪くないんじゃないかと思いましたが、サブルーチンの引数の文法だけは意味が分かりません。
sub makeNumOrSym { my ($str) = @_; # なにこれ...... if ($str =~ /^[+-]?\d+$/) { # これはまあいいや return makeNum($str + 0); } return makeSym($str); }
なんなんですか。 @_
というのは。Perl好きの人に文句を言ったら「shift
とか$_[0]
とかもあるよ」と言われましたが、引数には名前がないとあとで読めなくなるじゃないですか。まあ、私はそう主張しながら x
という名前の引数を作ったりするのですが。
小学生並みの感想
楽しかったです。でも、Perl好きの人から「ぜんぜんPerlっぽくない」と言われたので、私が書いたのはいわゆるPerlとは違う何かである可能性が高いです。
真珠と心中… 幼稚園児並みの子供ギャグ