湯婆婆にエラーを吐かせて遊ぶ のが流行っているみたいなので、便乗して J で書きました。
わざわざファイルを作るのも面倒なので、GUI (JQt) の REPL で実行します。
下準備
以下の verb (関数のようなもの) を定義しておきます。
ask=: 1!:1@1@echo
say=: echo@stringreplace~ '$'&;
utf32=: 9&u: :.(8&u:)
rand=: {~ ?@#
ask
は、メッセージを表示してユーザーからの入力を受け取ります。say
は、文字列内の $
を置換して出力します。これらは入出力のためのユーティリティーです。
utf32
は、UTF-8 と UTF-32 の相互変換を行います。文字をコードポイント単位で操作するために、UTF-32 を利用します。J では文字列は UTF-8 でエンコードされます。UTF-8 はバイト単位で扱われるため、そのまま使うと悲惨なことになります (1 バイトだけ取り出される)。
rand
は、リストの中からランダムに 1 つ要素を選びます。UTF-32 文字列から 1「文字」(厳密にはコードポイント) 取り出すのに使います。
湯婆婆を錬成
上で定義した verb を組み合わせると、湯婆婆が出来上がります。
yubaba=: [: ('今からお前の名前は$だ。いいかい、$だよ。分かったら返事をするんだ、$!!' say rand&.utf32 [ 'フン。$というのかい。贅沢な名だねぇ。'&say) ask@'契約書だよ。そこに名前を書きな。'
J では、式は右から実行され、データは右から左へと流れます。途中で変数に値を格納することなく、全ての処理を記述できています。具体的な説明には J の知識がある程度必要になるので、ここでは割愛します。
実行
yubaba''
契約書だよ。そこに名前を書きな。
山田太郎
フン。山田太郎というのかい。贅沢な名だねぇ。
今からお前の名前は山だ。いいかい、山だよ。分かったら返事をするんだ、山!!
yubaba''
契約書だよ。そこに名前を書きな。
山田太郎
フン。山田太郎というのかい。贅沢な名だねぇ。
今からお前の名前は太だ。いいかい、太だよ。分かったら返事をするんだ、太!!
ランダムに 1 文字選べています。他の例も試してみましょう。
yubaba''
契約書だよ。そこに名前を書きな。
湯婆婆
フン。湯婆婆というのかい。贅沢な名だねぇ。
今からお前の名前は婆だ。いいかい、婆だよ。分かったら返事をするんだ、婆!!
yubaba''
契約書だよ。そこに名前を書きな。
や婆婆
フン。や婆婆というのかい。贅沢な名だねぇ。
今からお前の名前はやだ。いいかい、やだよ。分かったら返事をするんだ、や!!
コードポイント単位で処理しているので、絵文字も扱うことができます。ただし、👨👩👧👦 のような、複数のコードポイントからなる文字は、バラバラになります。
yubaba''
契約書だよ。そこに名前を書きな。
寿司🍣
フン。寿司🍣というのかい。贅沢な名だねぇ。
今からお前の名前は🍣だ。いいかい、🍣だよ。分かったら返事をするんだ、🍣!!
yubaba''
契約書だよ。そこに名前を書きな。
👨👩👧👦
フン。👨👩👧👦というのかい。贅沢な名だねぇ。
今からお前の名前は👧だ。いいかい、👧だよ。分かったら返事をするんだ、👧!!
もちろん、入力が空だとエラーになります。
yubaba''
契約書だよ。そこに名前を書きな。
フン。というのかい。贅沢な名だねぇ。
|domain error: rand
| yubaba''
救済措置
湯婆婆がエラーで死んでしまっては かわいそうなので、空の入力の場合、名前が空文字列になるようにしてみます。
変更箇所は 1 つだけです。rand
の定義を以下のように書き換えます。
rand=: {~ ::[ ?@#
これだけで、エラーは防げます。
yubaba''
契約書だよ。そこに名前を書きな。
フン。というのかい。贅沢な名だねぇ。
今からお前の名前はだ。いいかい、だよ。分かったら返事をするんだ、!!
おわりに
この記事を見て、J に興味を持った方は、是非始めてみてください。J は奥が深い言語なので、他にも色々な書き方があると思います。例えば、ワンライナーでも書けます。
echo('今からお前の名前は',,&'だ。いいかい、',,&'だよ。分かったら返事をするんだ、',,&'!!')8 u:({~?@#)9 u:(['フン。'echo@,,&'というのかい。贅沢な名だねぇ。')1!:1@1 echo'契約書だよ。そこに名前を書きな。'
手前味噌ですが、現在 J 言語入門 を書いています。J を始めたいけど英語のドキュメントを読むのが辛い、という方は、参考にしてみてはいかがでしょうか。