1. カマンベールとコロッケ
  2. 72: プログラミング言語を作ろ..
2026-02-11 22:48

72: プログラミング言語を作ろう!

プログラミング言語を自作した話をしました。

https://github.com/shozawa/forth0

たとえば、こんな感じ。フィボナッチ数の10番目を出力するプログラムが動きます。

: fib dup 2 < if exit then dup 1 - fib swap 2 - fib + ; 10 fib .S

おたよりお待ちしています!

https://forms.gle/NzuwLL2H9B1f8ivNA

サマリー

今回のエピソードでは、パーソナリティの一人が年末年始にプログラミング言語の処理系を自作したという体験談が語られます。既存の言語ではカバーできないユースケースや、言語デザインの思想を織り込むために新しい言語が作られる背景が説明されます。特に、1970年代に作られた「Forth」という言語をベースに、x86アセンブリで処理系を実装した話が中心となります。アセンブリ言語の低レベルな性質を利用することで、より便利で高機能な言語処理系を自作する意義や、ブラックボックス化しがちな現代のプログラミングとの対比、そしてAIを活用した学習のしやすさについても触れられています。

プログラミング言語処理系の自作
プログラミング言語の話しようと思って。
おお。なんか一周回った感じがありますね。
あ、そう。なんかあんまり話してなかったと思うけど、マニアックな話になるとさ。
プログラミング言語の話は確かにしてないですね。
うん。まあでも、ちょっと話してみようかなと思って。話します。
適宜補足をする。しない気がするな。しない気がしますけど、話します。
何かというと、年末年始にプログラミング言語の処理系を書いてました。
おお。
あれなんか、もともと初田さん、プログラミング言語、自作の言語を作りかけてたみたいな、ありましたっけ?
なんか前も同じような話を聞いた気がする。
なんかね、3、4年に1回ぐらいプログラミング言語の言語処理系を作りたくなり、何か書いてた。
おお。
うん。で、一応補足しておくと、プログラマー以外の人に。
うん。
プログラミング言語を作ってるんですよ。
おお。え、プログラミング言語って作れるんですか?
そう。作れる、作れてさ、普段はプログラミングをして、ウェブサイト、ECサイトとか、そういうのを作ってるんだけど、プログラミング言語自体もプログラムなんだよね。
えー。言語で言語を作ってるってことですか?
言語で言語を作ってるんですよ。というわけで、プログラムを動かすためのプログラムというものがあり、それがプログラミング言語なんだよね。
へー。
ちょっとメタでかっこいいじゃない?
かっこいい、これちょっと初心者なんで質問なんですけど。
いいよ、なに?
すでに言語があるわけじゃないですか。言語を書くための言語があるのに、なんで新しく言語を書きたいんですか?
なんかいろんな説明がありますけど、やっぱりその、プログラミング言語っていうのは人間が作るんだよね。
言語デザインをする人がいて、その人がこういう文法にしたいとか、こういうことがやりやすいプログラミング言語がいいんじゃないかとか、
最新の研究を踏まえてこういう機能を入れたいとか、そういうことをプログラミング言語に織り込むんですよ。
だから人間の思想とか好み、何を大事にするかとか、そういうものが特徴として出ていて、その既存の言語だとカバーできないユースケースというか、ケースをカバーやるために新しい言語が作られる。
新しい言語が作られる理由
なんかシンプルな疑問として思うのは、なんかその、今既にある言語で書き切れないとか表現できないみたいな部分っていうのは、その言語を拡張すればいいんじゃないかって思う人いると思うんですけど。
それめっちゃいい質問というか話だと思っていて、そのプログラミング言語ね、結構長く使われるんですよ。
例えば日本人が作った有名なプログラミング言語で、Rubyっていうプログラミング言語があるんですけど、あれってもう30何年使われてるのね。
長い。
うん、長いよね。長く使われるとどうなるかっていうと、変えづらくなります。
確かにね。使う人も増えているし、そもそも言語自体が大きくなってくると、簡単に変えるっていうことができなくなってくる。
使ってる人が多いから変えれないっていうのもあるし、そもそもの設計が全く異なっている。
例えば、一軒家を建てるつもりで作り始めました。で、立派な古い一軒家ができましたってなるじゃない。
その後、ビルにしたいんだよねと思ったら、一軒家を改修するよりビルゼロから作った方が早いじゃない。
そうね。
そういうことなんですよ。
というわけで、日々プログラミング言語というのが作られている。
それはでも、昔ながらの公民化がいいっていうユースケースもあるし、大きいマンションの方が使いやすいっていうユースケースもあるから、それはどんどん増えていくような方向に動いてるっていうことですね。
そうだね。
Forth言語とその実装
で、ちょうど今いいパスだと思っていて、僕が今回作ったのは、ゼロからは作んないんだよ。
その公文、文法とかそういうのを自分で考えたっていうよりも、昔からある、既にあるものを自分でちょっとアレンジして作ってみるっていうことをやってるんだけど、
今回、私が作った言語はですね、フォースっていう言語のアレンジになります。
私のプログラムを送りました。
かっこいい、フォースゼロ。
うん。
つづりは合ってるんですか?
フォース、フォースって何に関してだね。
合ってるか。あ、そうですね。
あ、合ってないかもな。
あ、いや、合ってそう。
なんかさ、あれなんだよ、フォースって4番目っていう意味の言語?
はい。
なんで、第四世代。第四世代って意味の言語なんだけど、何文字かしか使えなくて、フォースの正しいつづりを入れられなかったから、何かを削ったっていう話があって、
ていうことは、あ、ていうことは合ってるのか。
第四世代って意味だと、F-O-U-R-T-Hなんだけど、Uが抜けてるから合ってますね。
うん、かもし。
まず、あつみさんに知ってもらうと。
インタープリターモードとコンパイルモードがある。
面白いでしょ。
面白いですね。
これテストなんだけど、これが動くコードね。
あつみさん、読んでください。聴取の方に伝わるように。
伝わらないでしょ、これ。
え?
じゃ、概要欄に書いとこうかな。概要欄に書いとこう。え、でも読んでよ。
えー、フィブ、ダップ、ニ。これちょっと、あの、発音もわかりません。
うん。
イフ文が書いてあるっぽいことだけしかわからない。
スペース区切りで、セミコロン、フィブ、ダップ、ニ、ショーなり、イフ、エグジット、ゼン、ダップ、イチ、マイナス、フィブ、スワップ、ニ、マイナス、フィブ、プラス、セミコロン。
これがフィボナッチ数列を計算するプログラムになります。
なるほど。あ、フィブっていうのは、フィブっていう関数を読んでいる。
あ、定義なのか、これ。
そう。で、読んでいるのが、これですね。10フィブ。フィボナッチの10番目は?ってことで、55が出てくる。
えー。
です。だからフィボナッチ数列が計算できる程度には動くっていうところまで作りました。
Forth言語の特徴と歴史
えー、面白い。なんかこれ、10、なんかすごい実装の話なんですけど、
10フィブって書いてありますけど、10っていうのは引数なんですか?
そう。えーと、そこまで詳細に立ち入らないですけど、このフォースの特徴は、スタック?スタックに値を積んでいって、それを引数として使うっていう。
えー。
まず10を積んで、その10に対してフィブを呼び出すっていう、そういう使い方をします。使い方というか、そういう文法です。
足し算とかもっとわかりやすくて、これ。わかる?
3、2プラスって書くと、3と2に対してプラスを実行しますって言って5が出てきます。
うーん。見慣れなすぎる。
見慣れなすぎるでしょ?独特な。
見慣れなすぎますね。
逆ポーランド記法かな。
うーん。
そう。っていう。
概要に書いてある。
まあ、すごい変わった?言語。
あついさん見慣れないって言ったじゃん。
はい。
見慣れないのもまあ当たり前で、これは1970年ぐらいに作られた言語ですね。
だいぶ古くて、C言語の2年前。で、C言語の影響を受けてないから、我々が使ってるプログラミング言語ってだいたいCの子供たちなんだけど、
C系のプログラミング言語だったらだいたい見たらわかるじゃないですか。
はい。
だけど、Cの子供ではないので、もう全然わかんないというか違った見た目をしています。
えー、これなんかすごく異国情緒が溢れていて面白いですね。
あ、そうそうそうそう。なんかプログラミングしてる気にならないと思う。
うん。これなんかちょっとあのウィキペディアの記事を読んでるんですけど、フォートランから派生した?逆か?
フォートランの方が古いと思うな。あのフォートランどんな言語か知らないから、言語ってどんな文法かわかんないからどこまで言ってるかわかんないけど、フォートランの方が古いよ多分。
大学の時にフォートランを触っていた時期があって。
えー、賢いね。
賢い?緊急施設で扱ってたんですけど、フォートランを使って書き直したものがフォースの原型であるというのがウィキペディアに書いてあります。
えー、関係あるんだねじゃあ。
関係ありそうですね。
これちょっとなんかもう少し前提の話していいですか?
はい、なんすか?
アセンブリ言語での実装の意義
これはなんでフォースを使おうと思ったんですか?
フォースを作ろうと思ったか?
フォースをどのように選んだ理由?
僕?僕が?
はい。
うん、それいい質問で、今回ですね、このフォース言語をどんな言語で書いてるかっていうと、x86アセンブリーで書いてるんですよ。
おー。
ほぼ、なんとかCPUがすごい薄く見える状態で書いてるんだよね。
で、っていう時に難しい言語は作れないんです、アセンブリーでは。
なるほど。
はい、なので、簡単に作れる、アセンブリーで簡単に作れる素朴な言語ということでフォースを選びました。
うん、ほうほうほう。
で、もともと歴史的にもそうで、アセンブリーで書かれることが多いんですよ、フォース。
でね、趣味でプログラミング言語を作るってことをたまにやってるんだけど、葛藤があるわけ。
何かっていうと、高機能なプログラミング言語を使って、しょぼいプログラミング言語処理系を作ることになるんですよ、ほとんどのケースで。
うんうんうん。
わかる?
せっかく機能が揃っているのに、たくさんの機能を個人で限られた時間で作ることはできないという。
そう。え、だから、なんか、パイソン使ってこのフォースを書いたとしたら、パイソンで書いているのにパイソンよりしょぼいことしかできないわけじゃないですか。
うんうんうん。
で、何のためにプログラミング言語を作っているのってなっちゃうなぁと思って悩んでたのね。
それはなんか原理的にそうっていう話ですか?
原理的に…いや、あの、うん。
それとも、しょばさんに無限の能力と無限の時間があれば、パイソンを超えられる言語は作れるという。
作れるんじゃない?その理屈では。
ただ、それこそパイソンのプログラムが10万行、もっとあるかも、どのくらいかわかんないけど10万行とかあって、僕が作れるなんてせいぜい数千行とか。
だから、パイソンを超えることはできないじゃないですか。
はい。はい。
それって、なんかしょぼいものを作るためにそんな高機能なものを使ってどうするの?というジレンマがあるんですよね。
はい。
で、一方…
なんでやってるんですか?
一方、アセンブリを使えば、アセンブリを使ってフォースをかけば、フォースの方が高機能なのよ。
ほう。
アセンブリより。
それは、なぜ?
なぜ?アセンブリっていうのは、CPU命令だから一番低レベルの使い勝手の悪い言語なんだよね。
で、それを自分が書いたプログラムによって便利にする。
ああ、そういうことか。
だから、アセンブリの下がないっていう感じ。機械語ぐらいしかないから。
0と1を直接書くか、アセンブリ書くかが一番底辺なので、それより便利なものを作るのは簡単っていう感じ。
ああ、なるほど。
はい。というわけで、意味があるものを作りたいなと思って。
うーん。
プログラミング言語自作の動機と学び
これは、継続していくんですか?
いや、なんか飽きちゃったね。
満足した。ある程度動いて満足したって感じ。
でも、2回作ってるんだよ、これ。
フォースゼロって名前だけど、ゼロじゃなくて、その前に1回作って、もう1回作ったらこれだから、2週2回作ってます。
なるほど。
これは、目指すゴールというか、とりあえずどこまでできたから満足したんですか?
フィボナッチ数列を計算するところがゴールだった。
ああ、そうなんだ。もうゴールはしてるんですね。
そうそう。だから最後にフィボナッチ数列を計算するプログラムを書いて、あ、動いたねって言って満足して終わる。
なるほど。
でも、もっと難しいことも書けるからね、やろうと思えば。
僕らが普段仕事で使っているプログラミング言語ってさ、かなりリッチだからコンピューターのこと全然見えないじゃない。
CPUのどんな目で呼ばれてるかとか、メモリ上にどんな値があるかとか、全然意識しないでしょ。
それって、ブラックボックスの上でよくわからないものをさり続けてるっていう気持ち悪さが割とあって、中身を知りたいなっていうそういう欲求によってプログラミング言語を定期的に作ってたんだよね。
それでいうと、今までは例えばPythonとかGoでプログラミング言語作ってたけど、今回アセンブリで書いたことによって、
もともとのモチベーションだったブラックボックスをなるべくなくして、自分が知ってるものだけ、なるべく知ってるものを多くしながら動くものを作るってことができたんだよね。
結構、得られるものというか、できるだけ手裏のところで作って、どういう動き方をするかみたいなのは結構わかるようになった。
0と1の世界と16進数
わかるようになった。それこそプログラムって0と1だよねって言うじゃないですか。
はい。
ピンとくる?それ。
あんまりピンとこないですよね。普通に言ったら。
ウェブプログラマーやってるだけだったらピンとこないよね。
そうですね。
あおってるわけじゃなくて。
なんか一般の人から聞いてても多分わかんないと思います。
でも、例えば、0と1、8バイト。0が8個並ぶ。8バイトで文字、アルファベットを表しましょうとか、そういうことをやっているので。
あと、バグったときに調査するんだよね。メモリーがどういう状態になってるか調査するんだけど、そのときにダンプを見るんだけど、ダンプには0と。
0と1というか厳密には16シンスが乗っかっているので、16シンスを見るんですけど、ここは0でここは1かっていうのをすごく見ながらデバッグしましたね。
それ、わかるんですね。
わかるよ。わかるっていうか、ちょっとわかるようになった。で、16シンス正直あんま読めなくない?
読めない。
読みづらいよね。
読めない。
あれもちょっと読めるようになってさ。
かっこいいっすね、普通に。
なんか、16シンスってわかりづらいから普通に10シンスで書いてくれって思わん?
それは人間理由ではそうですね。
でもあれ面白くてさ、16シンスって2つセットで読むと読みやすいんだよ。
確かに。そうなのか。
何かっていうと、16シンスって4ビットでしょ。
はい。
で、それが2つ並んでるとさ、8ビットで1バイトじゃないですか。
はいはい。
1バイト単位で色々扱うことが多いから、1バイトがわかりやすいとプログラマーにとって嬉しい。テレレイヤーのプログラムをするには嬉しいんだよね。
うんうん。
っていう時に1バイトを16シンスで2つとして認識すると、パターンがわかりやすくなるんですよ。
文字コードとAIの活用
これって、なんか素朴な疑問なんですけど、言語を作る時だと思うんですけど、
例えば入力する文字列がどこからどこまでかっていうのを指定すると思うんですよ。
例えばAからZまでとか、数字が使えるとか記号を使えるとか。
それも自分でどこからどこまでっていうのを指定して作ってるんですか?
プログラムが使える文字の種類みたいなとこ。
はい。
それは決まってるものを使っていて、何かっていうと、それがASCII。
ASCIIって語源わかる?
うんうん。
ASCII文字のASCIIだけど。
わかんないな。なんかの略?
アメリカンスタンダードなんちゃらかんちゃらって、127文字ぐらいかな。
7ビットで表せれる範囲の文字のセットって決まっていて、0だったらこれ。
Aだったら何番とか、そういう番号が振られてるんだよね、アルファベットたちに。
はいはい。
で、その数字さえ、数字を入れてこれをASCIIとして解釈してくださいっていうと、数字が文字に変換されるって。
ユウシ君。
アルファベットであれば大文字、小文字、記号、数字は一通り使えるんですね。
そう使える。で、中身としては127までの数字、整数が入っていて、それを整数として扱うか文字として解釈するかはプログラミング次第って感じ。
面白そう。
面白いですよ。なんか、ブラックボックスを開けていく感じが楽しいのかな。
なんか仕組みがどうなってるかみたいなのって結構興味ありますよね。
うん、ある。あとはすごい良いのは、今はAIがあるからさ、教科書に載ってるような話なんだよね、コンピューターをどうやって動くかみたいな話って。
はい。
で、常識というか知ってる人は知ってるって知識なので、AIがよく知ってるんでね、間違えずに教えてくれるので、
その本とか読みながらAIにここってなんでこうなのとか、歴史的にはなんでこうなってるのって聞くと答えてくれるので、
昔の素朴なものを自力で作るっていうことに関してはすごいやりやすい時代になったなっていうふうに思いますね。
確かにそういう質問すごい的確に答えてくれそう。
うん、得意だと思います。
今後の展望とリスナーへの呼びかけ
はい、というわけで、最近ハマっていた。
3、4年後くらいに新しい言語を作れるターンが来る予定ですね。
これを聞いているプログラマーがどこにいるかわからないですけど、新しい言語を作りたくなったら一緒に作りましょう。
僕が書いたやつもGitHubにあげてあるので参考にしてください。
確かに、はい。
じゃあありがとうございました。
はい、ありがとうございました。
22:48

コメント

スクロール