メインコンテンツまでスキップ

Shol 言語について

ショル助とショル子は、目を覚ますと見知らぬ部屋に閉じ込められていた。

助「本当だ、開かない。でも鍵穴らしきものも見当たらないな」

子「ショル助、あれを見て!」

そこには【Shol 言語についての概要を理解しないと出られない部屋】と書かれた看板が。

助「Shol 言語? なんだそれ」

子「霽月(X: @Se1getsu)って人が作った独自パラダイム言語のことかしら?」

助「知っているのか、ショル子」

子「ええ、チョットね。それじゃあ、Shol の概要について説明するわね」

Shol とは

助「独自パラダイム言語と言ってたけど、パラダイムって何だ?」

子「プログラミング言語には、パラダイムという、プログラミングをする上での考え方みたいなものがあるわ。手続き型や、関数型、オブジェクト指向などがあるわよ」

助「ああ、それのことか。独自パラダイムってことは、Shol はどれでもないのか?」

子「ええ。Shol は規則やデータフローを中心にプログラムを表現するルールベースの宣言型言語よ」

助「ふむ、あまりピンと来ないな。手続き型言語にあるような、if 文とか for 文、関数とかはあるのか?」

子「ないわよ。C や Java にある main 関数のような、エントリーポイントも存在しないわ」

助「何だって!」

Shol の目的

助「Shol ってどういう時に使える言語なんだ?」

子「実は、Shol は実用目的で作られた言語ではないのよ。BrainF**k は知っているかしら?」

助「難解プログラミング言語として有名な、あの?」

子「そう。Shol はそういった言語と同じく、実用面よりも、全く新しいユニークなパラダイムの面白さに焦点を当てた言語なのよ」

助「じゃあ、全く使い道はないのか?」

子「AtCoder のような競技プログラミングの問題に挑戦してみると面白いわよ。Shol のコンパイラには Rust のソースに変換(トランスパイル)する機能が備わっているから、Rust に対応しているサイトであれば提出が可能よ」

サンプルコード

助「例えば、Shol で Hello, world! を表示するプログラムはどう書くんだ?」

子「こうよ」

%print
Hello, world!

%exit
0

助「なるほど、%print で出力して、%exit終了コード 0 を返して終わりって感じか。シンプルだな」

子「そうね」

助「なら条件分岐やループはどうするんだ? if 文や for 文はないんだろう?」

子「それなら FizzBuzz 問題のサンプルを見てみるといいわ」

%cin
. $ #nGen 1, $.int

*nGen
. $n, $max # $n+1, $max, $n<$max
| $n, $max #fizzBuzz $n
. false #exit 0
| true #

*fizzBuzz
. $ % 3 = 0 # Fizz
| $ % 5 = 0 # Buzz
. Fizz, Buzz # FizzBuzz
. $ #print $

%print
%exit

助「む……さっぱり分からない。どこがループになっているんだ? $ がついているのが変数か?」

子「Shol に変数という概念は存在しないのよ。そうね、まずは Shol の概念について教えましょう」

Shol の概念

概念:コロニーと規則

子「Shol のプログラムは コロニー(colony) と呼ばれる独立した単位で構成されているわ」

助「へえ、それって FizzBuzz のプログラムでいうと、どこのことなんだ?」

子「cin, nGen, fizzBuzz, print, exit がコロニーよ」

助「確認だが、%print%exit は『print する』『exit する』のような命令を表してるんだよな?」

子「違うわよ。print コロニーと exit コロニーを宣言しているだけね」

助「……? ひとまず説明を続けてくれ」

子「各コロニーは リソースキュー(resource queue)規則(rule) を持っているわ」
子「リソースキューは リソース(resource) と呼ばれるデータをためる入れ物で、規則はリソースキューに入っているリソースを変換する処理のことよ」
子「そうね、例えばこんなコードを書いてみましょう」

*sample
10
. $ # $+1

子「これは 10 というリソースと『リソースを、その値に 1 足したものに変換する』という規則を持った、sample という名前のコロニーを宣言しているわ」

助「規則はいつ実行されるんだ?」

子「規則はプログラムの実行が始まると、ソースファイルの一番最初に書かれた規則から順番に実行されるようになっているわ。そして最後の規則まで行ったら、最初の規則に戻って来て再び順番に実行されて、また戻って来てを繰り返すのよ」

助「つまり、ソースファイル内の規則全体が大きなループになっているってことなのか?」

子「ええ、そうよ。そして、そのループ 1 回分のことを サイクル(cycle) と呼んでいるわ」

助「なるほど。それなら、このプログラムは 10 に 1 を永遠に足し続けるようになっているのか」

子「そうよ。数が大きくなり過ぎてオーバーフローしてしまうまで止まらないわ」

助「それで、$ はリソースって意味で合っているか?」

子「ええ。$キャプチャ(capture) と呼ばれているわ。それじゃあ、次の例を見てみましょう」

*sample
1
3
. $ # $+5, $+10 // 1 つ目の規則
. $ > 10 # // 2 つ目の規則

助「これはどう動くんだ?」

子「まず、sample コロニーのリソースキューの初期状態は [1, 3] よ」

助「13 という 2 つのリソースがある状態だな」

子「そこから 1 つ目の規則で、[6, 11, 8, 13] に変化するわ」

助「13 それぞれが、6, 118, 13 に変換された結果そうなるわけか」

子「そこから 2 つ目の規則で、[6, 8] に変化するわ」

助「10 より大きいリソースが削除されるんだな」

子「そうよ。正確には 10 より大きいリソースをキャプチャ(捕まえる)して、無に変換しているといった方がいいかしら」

助「その後また 1 つ目の規則に戻って来て……今度は [11, 16, 13, 18] に変化するわけか」

子「そうね。今度はすべて 10 より大きいリソースになっているから、2 つ目の規則の実行でリソースキューは空になるわね」

助「リソースキューが空になったら、そのコロニーの規則はもう実行されないのか?」

子「変換対象のリソースがないから、sample コロニーの規則が働くことはもうないわね」

助「なるほど」

概念:並列規則

助「行頭の . は、規則ってことを意味してるのか?」

子「そうよ」

助「なら FizzBuzz のプログラムに出てきた | って何なんだ?」

子「|並列規則(parallel rule) といって、直前の規則と同時に動作するのよ」

助「マルチスレッドってことか?」

子「違うのだけど、イメージとしては近いかもしれないわ。fizzBuzz コロニーの例で説明しましょう」

*fizzBuzz
15
. $ % 3 = 0 # Fizz
| $ % 5 = 0 # Buzz
. Fizz, Buzz # FizzBuzz
. $ #print $

%print

子「3 の倍数のリソースを Fizz に変換する規則と、5 の倍数のリソースを Buzz に変換する規則が、いっぺんに実行されるのよ」

助「下のように、別々の規則として書くのと何が違うんだ?」

. $ % 3 = 0 # Fizz
. $ % 5 = 0 # Buzz

子「並列規則の場合、15 のリソースは Fizz, Buzz に変換されるのだけど、別々の規則で書いた場合、15Fizz に変換された時点で 15 というリソースはなくなってしまうから、Buzz を生成する規則が動作しないのよ」

助「Fizz しか生成されなくなってしまうんだな」

子「そういうことよ」

助「その後は、3 つ目の規則で FizzBuzzFizzBuzz に結合されて print されるわけだな」
助「15 以外だとどうなるんだ?」

子「3 なら Fizz5 なら Buzz に変換されて、2 なら 2 のままね」

概念:リソースの送信

助「#print ってのが、これが画面に文字を出力するって命令ってことだよな?」

. $ #print $

子「いいえ、命令ではないわ。これは、変換したリソースの出力先を print コロニーに指定しているのよ」
子「例えば、こう書いた場合、a コロニーから b コロニーに対して 100 というリソースが送信されるわ」

*a
90
. $ #b $+10

*b

助「送信されたら a のリソースキューは空になるのか?」

子「そうよ」

概念:組み込みコロニー

子「print コロニーは 組み込みコロニー(built-in colony) という特別なコロニーのひとつで、このコロニーのリソースキューに入ったリソースは標準出力に出力されるのよ」

助「Hello, world! のプログラムでも登場したな」

%print
Hello, world!

%exit
0

子「これは組み込みコロニーの print"Hello, world!" という初期リソースを配置しているのよ」

助「% が組み込みコロニーで、* が普通のコロニーってことか?」

子「そうよ。exit もプログラムを終了させるための組み込みコロニーなのよ」

助「なるほどな」

子「% で宣言したコロニーには、自動的に規則が追加されるわ。イメージとしてはこんな感じね」

%print
Hello, world!
. $ # ($ を標準出力する)

%exit
0
. $ # (終了コード $ でプログラムを終了する)

子「ちなみに Shol のプログラムは exit コロニーを使わないと終了しないようになっているわ」

助「プログラム全体が無限ループだもんな」

まとめ

助「ここまでで教えてもらった Shol の概念をまとめてみたぞ」

用語説明
コロニーShol のプログラムを構成する独立した単位。リソースキューと規則を持つ。
リソースコロニーのリソースキューに格納されるデータ。
リソースキューコロニー内でリソースを管理するためのキュー。
規則リソースキューにあるリソースを変換する処理。
サイクルソースファイル内のすべての規則が 1 回実行される単位。
キャプチャ$ で表され、リソースを捕まえて処理する仕組み。
並列規則| を用いた規則で、同時に動作する規則を定義する。
送信# を用いてリソースを別のコロニーに送ること。
組み込みコロニーprintexit など、Shol に標準で備わっている特別なコロニー。

子「素晴らしいわ! これらが Shol における基本的な概念よ」
子「Shol はリソースの変換やコロニー間のリソースのやり取りによってプログラムを表現する宣言型のルールベース言語で、手続き型や関数型とは異なる新しいアプローチを採用しているの」
子「変数や命令の概念がないから、一般的なプログラミングの方法論とは異なる発想が求められるわ」

助「BrainF**k のように実用的な言語ではないと聞いて、初めは難解な言語なのかと思っていたけど、ショル子の説明を聞いていると興味が湧いてきたよ」

子「それはよかったわ! Shol の独特なパラダイムをぜひ実際に触って体験してみてほしいわ」

ガチャッ

子「何かしら? あっ、扉が開いてるわ!」

助「ショル子のおかげで、Shol の概要を理解するというミッションをクリアできたようだ」

子「これで外に出られるわね!」

こうしてショル助とショル子は、【Shol 言語についての概要を理解しないと出られない部屋】からの脱出を果たしたのであった。

次のステップ

蛇足

助「ところでショル子、Shol の名前の由来って何なんだ?」

子「……知りたいの?」

助「教えてくれ」

子「霽月が ひょんなことから 思いついた ランゲージ
子「略して Shol よ」

助「なんて安直な……」

子「Wi-Fi のように、何の略でもないという説もあるわ」