Matheus Moreira氏へのインタビュー2026年7月 - Alex Alejandre

Matheus Moreira氏(ブログ)はLinuxのシステムコール上に直接lone lispを構築しました。このインタビューでは、CとLinuxカーネルに関する彼の知識を共有しています。


元々どのようにコンピューティングに携わるようになったのですか?Lispなどを発見する前の経歴は?

私は昔からコンピュータが好きでしたが、本当にプログラミングに没頭するきっかけとなったのはビデオゲームでした。子供の頃、Mega Man Battle Networkというシリーズのゲームをプレイしていて、そのゲームにインスパイアされました。結局、それらのゲームのおかげで英語を学ぶことになりました。英語を話せない状態でフォーラムに参加し、交流を試みていたのです。最初は大変でしたが、改善しました!最初の言語であるC++についても同じことが言えます。

C++を始めたのは何歳の時ですか?

ブラジルには「技術学校」というものがあり、私はそこに通っていました。通常の高校のカリキュラムに加えて、専門的な授業があるのです。海外では一般的でないかもしれませんし、それに相当する用語があるかどうかもわかりません。他にも化学、メカトロニクスなどのコースがありました。質については基本的でしたが、高校レベルとしてはかなり良かったと思います。ただ、それによって独学を始めることになりました。6ヶ月以内に、カリキュラム全体をすでに学んでいました。最終的には、仲間の学生を助けるために教師アシスタントとして雇われました。

高校に入学した頃、13〜14歳の時に情報コースを受講し、Dev-C++という非常に古いIDEでC++を学び始めました。今でもSourceForgeに存在しています!また、cplusplus.comのチュートリアルも閲覧していました。ゲームを作ろうとしましたが、あまり成功しませんでした!特に、シミュレーションすべき物理学をまだ学んでいなかったので、かなり難しかったです :) 結局、多くの言語を学ぶことになりました。基本的なC++の習熟度に達した後、Javaをかなり学び、次にRuby、Pythonと学びました……それが最終的にLispとSchemeにつながりました!Schemeを初めて見たとき、非常にエレガントだと思ったことを覚えています。 Rubyが一番好きな言語でした。その頃にいくつかのgemを書きました。実際に少しフォロワーがついたものがあると思います:Acclaimという、gitのようなコマンドベースの引数パーサーです。

素晴らしい!新しい言語に喜んで飛び込んだのですか、それとも最初はC++にこだわったのですか?

cplusplus.comのチュートリアルをやり尽くした後に、より多くの言語を学び始めたと思います。そのサイトにこれ以上学ぶものがなければ、そろそろ次のステップに進むべきだと思ったのですよね。Sunには当時、非常に大きなJava Tutorialsのウェブサイトがありました。そのサイト全体を読んだと思います。それがオブジェクト指向プログラミングを学んだ時でした。10代の頃にいくつかのJavaコードを書きました……いくつかの「ユーティリティライブラリ」です。振り返ってみると、Apache Commonsの1%をひどく実装したバージョンに過ぎませんでした!公開したと思います。今でもどこかにあるかもしれません……また、Java Swingアプリケーションをたくさん実験していたことも覚えています。Nimbusのルックアンドフィールが本当に好きで、数学の教授のために円/弧を描画するアプリケーションを作ったことがあります。

これらの探求を促したものは何ですか?さまざまな言語などをチェックし続けるきっかけとなったものは何ですか?Rubyも使い続けましたか?

学校のプロジェクトは、学生時代の初期の大きな動機でしたが、ある時点では好奇心と「The Right Thing」への欲求でした。自分の居場所となる言語が欲しかったのです。Rubyを一番長く使い続けました。本当に良い言語です。いつもインストールしていて、最近Railsプロジェクトを始めました!しかし、欠点もあります。もう一つ使い続けた言語はCでした。その低レベルのシンプルさが本当に魅力的でした。

C++は忘れませんでしたが、知識を更新しませんでした。現在のC++は本質的に完全に新しい言語なので、もはやC++を知っているとは主張しません。ある意味で、Cに置き換えました。Cは、すべての問題とレガシーにもかかわらず、何らかの理由で常に魅力的でしたが、10代の頃にCRuby VMのソースコードを探索し始めた時に、本当に頭の中に定着し始めました。誰かが「なぜRubyはXのように振る舞うのか?」と尋ねる興味深いStack Overflowの質問を探し、ソースコードを掘ってそれを解明するという、本当に楽しい趣味がありました。

数年前にRustに移行しようとしましたが、あまり定着しませんでした。Zigとその作成者の大ファンでもあります。「the road to Zig 1.0」の基調講演で、人々が「Cで物を書き直す」理由(速度、ABI……)を説明しているのを見て以来です。

CとRubyを使い続けることになったメリットとデメリットは何ですか?

Rubyは非常に表現力豊かな言語で、私のメンタルモデルに「ぴったり」合いました。メソッド名を推測することができ、それが実際に動作することがよくありました。メソッド名の単数形/複数形、同義語などの良い点があります。私たちの脳はこれらの単語で機能し、Rubyはそれらすべてをサポートしています。

Matkladは、良いAPIは推測可能であるべきで、存在しないものを推測した場合、APIがそれを要求しているというバグレポートを提出することが多いと述べています!

Rubyはまた、恐ろしいほどシェルに似た処理パイプラインの作成を可能にします…… items.each.with_index.map… それはどんどん合成され、非常に少ない文字で多くの作業を行うことができます。

Cの主な利点は、出力のシンプルさです。関数を書くと、ELFシンボルと関連するアセンブリコードにコンパイルされます。Cを書いているとコンパイラの出力が見えると言いますが、それは本当です。C++では、コンパイラが多くの機構を追加し、それがどのようにすべてが組み合わさっているかを理解するのは非常に困難です。動的言語では同じですが、コンパイラのソースコードよりも仮想マシンのソースコードを探索する方が簡単だとわかりました。

つまり、あなたのC++スタイルは、糖衣構文を削除してCを書くようになったのですね?

はい。他の開発者が書いたコードをますます読むにつれて、私のスタイルも変わりました。CRubyのコード、CPythonのコード、JVMのコード、Guileのコードを少し、V8のコードを少し……しかし、Linuxカーネルのソースコードを読み始めた時に、本当にエキスパートのCプログラマを尊敬するようになりました。本当に良いもので、おそらくゴールドスタンダードでしょう。

最初から、たくさん読んでいたのですか?特に今日では、他人のコードを本当に読む人は非常に稀です。どのようにアプローチしていますか?何かコツやテクニックはありますか?

私はたくさん読みます。物事がどのように機能しているのかを知りたがる好奇心旺盛なタイプでした。あるライブラリを使うだけで満足せず、それが内部で何をしているのかを知りたかったのです。ドライバがハードウェアとどのように通信しているのかを知りたかったのです。隠された楽しいものをすべて知りたかったのです。それが私にとって興味深いことなのです。本当に作りたかったアプリケーションは、これらの無関係な探求に逸脱してしまうことがありました。他のプログラマは「なぜそんなことに時間を無駄にするのか?すでに解決済みだ」と言うでしょうが、私はそれがどのように行われたのかを知りたかったし、最終的には車輪の再発明をしたいというある種の傲慢さも発達しました。ただし、より良いものを。

しかし、そのメッセージは受け取りました。この癖のためにソフトウェア開発のキャリアには向いていないと感じたので、結局は追求しませんでした。今日まで趣味として続けています。

ドライバのコードを初めて見た時、どのように理解したのですか?

最初はまったく理解できませんでした……。それは苛立たしいことでしたが、粘り強く続け、最終的には少なくともいくつかのことを理解できるようになりました。私はハードウェアエンジニアではありません、それは確かです……しかし、ラップトップの機能のいくつかをリバースエンジニアリングすることに成功しました。今でも最も誇りに思うプロジェクトの一つです。私のラップトップはClevoのベアボーンモデルの一つです。RGB LEDを備えた非常に良いキーボードがあり、ほとんどが個別にアドレス指定可能です。それらのLEDを制御するための本当に悪いWindowsアプリがありました。画面にウィンドウを表示するのに1分以上かかったことを誓います。本当に苛立たしいものでした。Wiresharkを使ってキーボードに送信されているUSBパケットを傍受し、Linuxのユーザースペースドライバを書きました。パケットをキャプチャし、それらの構造を理解するまで画面を見つめ、私のためにキーボードを設定する小さなCプログラムを書きました。GitHubに投げ出して忘れていました……ある日戻ってみると、どういうわけか人々がそのものを使っていて、一人がGUIを作っていたのです。それはかなり良い気分でした。ラップトップの残りの機能をリバースエンジニアリングしようとすることで、ドライバとコンピュータ技術について多くを学びました。ACPI電源管理のものなど。すべてを理解できたわけではありませんが、今日まで。

Linuxシステムコールに関する記事がありますが、それがloneの方向に進むきっかけになったのですか?

システムコールのコードは非常に最小限で、通常の関数呼び出しのように機能します。面白いのは、libcをバイパスしてLinuxを直接ターゲットできることです。LinuxはユーザースペースABIの安定性で有名です。ユーザースペースコンポーネントはそうではありません。これにより、人々は中間に他のものを挟むことなく、Linuxカーネルに直接依存することができます。

人々がシステムコールを使いたがらないという一般的な感覚から始めました。マニュアルを読んで、「このシステムコールはglibcでサポートされていません」といったことが書かれているのを見ました。Wikipediaを読んで、glibcがLinuxをラッピングしているというインフォグラフィックがあり、まるでそれがLinuxのCRTであり、他のlibcが存在しないかのようでした。それから、getrandomシステムコールがglibcに登場するまでに2年かかったというLWNの記事を読んだのを覚えています。

CRT?

Cランタイム。標準Cライブラリ:glibc、musl、uclibc。

互換性を破ると世界全体が壊れるパッケージです。すべてがそれに依存しているからです。記事には、「Linuxはシステムコールだけを含むliblinux.aを持つべきだったかもしれない。そうすれば、人々は役に立っていない時にlibcをバイパスできる。コンパイラに-llinuxを渡すだけで」といったことが書かれていたと思います。それは本当にクールなプロジェクトアイデアだと思ったので、liblinuxを作成しました。それはまさにそれでした:freestanding CプログラミングのためのLinuxシステムコールラッパーのコレクションでした。Linuxシステムコールインターフェースに対してプログラミングするのが本当に楽しいことがわかりました。freestandingモードでは、Cの問題の多くが消えるのです。

freestandingモードでは、どのようなCの問題が消えるのですか?

最も基本的なもの:errno。Cには「現在のエラー」という概念があり、それはグローバル変数です。すべての関数がそれを設定し、それをチェックするはずです。Linuxはそれを通常の関数が返すように返します。Cライブラリはその値を取り、グローバル変数に入れます。それがCのやり方です。freestanding Cではそうではありません。Cのレガシーも消えます。Cライブラリには多くのレガシーコードがあります。ロケール関連のものは、例えば、非常に問題があります。また、グローバルステート(繰り返されるテーマ!)でもあり、環境変数のようなものに基づいて非常に微妙なエラーを引き起こす可能性があります。Liblinuxはfreestanding Cと、Cがどれだけクリーンになり得るかを教えてくれました……レガシーをすべて削除できれば。痛ましいことでした。すべての関数を自分で書かなければなりませんでした。基本的なバイトコピー関数から、整数→文字列変換関数まで……しかし、問題は想像していたほど乗り越えられないものではないことがわかり、粘り強く続けました。疑問に思った時はいつでも、コードを読めばいいことを知っていました。巨人がどのようにそれを行ったかを見ることができました。glibcリポジトリは解釈が困難でしたが、musl libcのソースコードは本当にクリーンで、飛び込みやすいです。非常に貴重でした!また、ある程度の創造性も刺激されました。例えば、Cライブラリも、メモリ割り当ても、静的メモリだけを使って自動テストスイートを作成するにはどうすればよいでしょうか?loneでそれを行うことができました!

RedditでGreg Kroah-Hartmanに、なぜLinuxに「公式」のCライブラリがなかったのかについて尋ねたことを覚えています。彼は、Linuxにはかつてklibcプロジェクトがあったと返信しました。liblinuxの歴史はそこで終わりました:ある時点で、Linuxカーネルの人々がまさに同じことをしていることを発見しました。彼らはnolibc.hというファイルを作成し、自分たちのツールで内部的に使用していました。私が考えたものよりも優れていて、使いやすいと思いました。そこでプロジェクトをアーカイブし、別のものを始めました:Lone Lisp。そのパラダイムで書かれた完全なプログラミング言語。心の底では、それが可能だと思うのは自分が正気ではないことを自分に証明したかったのです。Linux上で直接実行されるfreestanding Lispを作ることができれば、どのようなプログラムでもそのように書くことができることを証明できるでしょう。

現代のLinuxユーザースペースは怪物のような迷宮です。Linux自体はそうではありません。私は本当にクリーンなシステムだと感じました。すべての基本は、実際にはLinuxシステムコールのバイナリインターフェースです。実際には、ユーザースペース全体をゴミ箱に捨てて、Linuxだけを使ってゼロから始めることができます。必要であれば、ユビキタスなGNUのものもゴミ箱に捨てることができます。

なぜ、組み込みのシステムコールサポートを持つコンパイラを持てないのでしょうか?提供されたパラメータを使用してLinuxシステムコールコードをインライン化するsystem_callキーワードを追加するだけです。中間にlibcのくだらないものは必要ありません。Cや特定の言語は必要ありません。誰かが今日言語を作ることができ、その単一の機能が、システムプログラミングにおいてCと同じくらい有能なものにするでしょう。彼らはソフトウェアを書いて、Linuxを直接それにブートすることができます。- Matheus 2021

要約すると、freestanding Cはいくつかの興味深いCの欠陥を削除します:すべてのグローバルステート:errnorand/srandステート、ロケールステート、strtokreentrantではない!)、時々人々を困らせる暗黙的なファイルバッファリング。gets(擁護の余地なし)、atexitsignalmallocのような poorly designed API。loneのアロケータの方がはるかに良いです。math.hはNaNで非常に乱雑になり、errnoが関与するとさらに悪化します。決して消えないものもあります。Cの難解な整数プロモーションルールは残ります。また、オーバーフローチェックの欠如もありますが、私はコンパイラの組み込みを使用しています。また、自分自身の欠陥を導入しているのではないかと心配しています……傲慢さは間違いなくいつか私を襲うでしょう。

nolibc.hのアプローチがなぜもっと人気がないのか知っていますか?

現在、nolibc.hはカーネルツリーの広がるディレクトリになり、ある種のアドホックなlibcになりました。彼らはそれを内部プロジェクトとして扱っているようです。Linuxが使用する内部ツールをコンパイルするためのもの。Linuxカーネル開発の外では、それが存在することを知っている人は非常に少ないと思います。人々はそれを自分のプロジェクトを構築するために使用することができますが、その点でLinuxがどのような安定性保証を提供しているかはわかりません。

関連して、浮動小数点パースを実装するためにCosmopolitanのパッチを送ったことがあります。私はそのプロジェクトと作者のファンです。それを「愚かな」ハックと呼ぶ人々でさえ、それが天才的なハックであることを認めていると私は考えています。それは本当に素晴らしいプロジェクトで、APE形式という単一の形式に信じられないほど多くのウィザードリーな知識を凝縮したものです。さまざまなプラットフォームで異なる実行可能形式として解析できる実行可能ファイルを作成できるということは、本当に奇妙なことです。そして、その上でさらに素晴らしいことを行い、実行可能ファイルに埋め込まれたアーカイブをサポートします。

傲慢さと欠陥を避ける方法について、少なくとも考えることは重要です、うまくいけば。多くの人は内省しません……浮動小数点はloneの唯一のチェックされていない機能です、その後はどうなりますか?特定のものを構築したいですか。

Steve Yeggeが言ったように、インタプリタを作成するだけで、赤ちゃんが生まれ、一生の仕事になります。浮動小数点は難しいものになりますが、前進する仕事は文字通り無限です。

この週末、ちょうどエラー処理システムを実装しました。Common Lispスタイルの再開可能なコンディションシステムです。それ以前は、すべてのエラーパスがインタプリタからのハードexit(255)でした。次のタスクは、それらのコールサイトをすべてLisp内で処理できる例外に置き換えることです。また、適切な末尾呼び出し最適化のサポートも今プッシュしました……浮動小数点は難しい機能になります、私がCosmopolitanに送ったパッチが何らかの指標になるでしょう。それは実装しなければならないものです。また、最終的にはErlang/BEAMシステムのアイデアを実装したいと思っています。Lispコードを並列に実行する多くのインタプリタがいつか存在できるように構造化しました。それらはすべて言語レベルの機能です。

言語自体で何を構築するか?loneで作りたい最初のプロジェクトは……静的サイトジェネレータの置き換えです。私は自分でメンテナンスしているpugjsのフォークでウェブサイトを書いています。long term goalは、それを置き換えるためにlone Lispで独自のシステムを書くことです。その後、独自のシェルを書きたいです。独自のユーティリティ。伝統的なLinuxユーザースペースを私のイメージで作り直し始めます。

それがloneを開発している間に私の心に浮かぶアイデアでした。私の記事の一つには、環境をlone Lispテーブルとしてダンプするだけのenvの実装についても言及しています。当時、loneには反復機能がなかったので、それが私ができた最善のことでした。今、loneにはジェネレータがあります!もっと多くのことができます……何かを実装して、それが他の多くのものをアンロックした時の感覚は素晴らしいものです。埋め込みセグメント機能は、まさにその「Linuxユーティリティ」ユースケースのために設計したものです。loneインタプリタには、特別なELFセグメントを読み取り、そこにコードがあるかのように実行する機能があります。そのため、インタプリタをコピーし、そのコピーにいくつかのLispコードを追加することで、loneプログラムを作成でき、自己完結型のプログラムになります。今ではジェネレータ、区切り付き継続があり、エラー処理を導入したところです。

新しいエラーシステムはCommon Lispのものとどのくらい似ていますか?

エラーシステムは多くの点で似ていますが、シグナリングコードが再開方法のオプション(use-valueなど)を提供するCommon Lisp APIはありません。私のシステムは、区切り付き継続の作業の上に直接構築されています。それらを実装するまで、継続はSchemeの神秘的な機能の一つに過ぎませんでしたが、誰もがすでにそのバージョンを使用していることを発見しました。例外メカニズムは本質的に継続の一形態であり、値にキャプチャされることはありません。そして、魔法は継続をキャプチャすることです。Alexis Kingの区切り付き継続に関するプレゼンテーションは、私にとってそれを解明しました。それは、結局のところスタックをmemcpyしているだけであることを示しました。スタックのコピーを作成し、そのスタックをどこか他の場所で「リプレイ」する、VCRのように。再開可能な例外。エラーシグナリングシステムは、結局のところ、その上にハンドラメカニズムを備えたものでした。「catch ErrorType -> ErrorTypeのコード」の部分を実装する必要がありました。単純なシステムを選択し、例えば'not-foundのようなシンボルをラムダにマッピングしました。そのため、ラムダのアリティをテストし、1つの引数を取る場合:(lambda (error) ...)は、他のすべての言語と同様に機能します。しかし、2つを取る場合:(lambda (error continuation) ...)は、継続を介してコードを再開する方法を提供します。

Loneのエラーシステムは、throwが呼び出し元のコードに値を返すようにします。各例外ハンドラは、オプションで区切り付き継続を受け取ることができます。受け取った場合、それを呼び出して値を返すことで、誤ったコードを再開できます。

特定のシステムやアプローチを拒否しましたか?

私は、他の言語がこれらのことを解決する、しばしば重い方法を拒否する傾向があります。例えば、Common Lispスタイルの「restart API」を明示的に拒否しました。これは、コードが再開方法の数を列挙できるものです。すべてを評価器自体の単純な言語メカニズムで実行したかったので、再開はsignal/throw/transferが値を返したかのように動作します。また、評価器における「特殊ケース」も拒否しました。一方、伝統的なLisp実装では、evalifのような特殊形式を明示的にサポートしています。loneでは、評価器にそれらの特殊ケースはありません。FEXPRのサポートがあり、それは本質的に評価器プラグインです。それにより、ある程度のエレガンス(少なくとも私にはそう思える)のために、必要以上に多くのことが複雑になりました。例えば、末尾呼び出し最適化は純粋なLisp関数では機能しましたが、プリミティブでは完全には機能しませんでした。プリミティブのTCOはそれ以来修正されましたが、evalからそれらを分離するという設計上の選択のために、しばらくの間バグがありました。それらを末尾リターンさせるための特別なメカニズムを導入する必要がありました。

また、一般的に、評価器の機構を活用した、共通のことを言語内で実行する方法を考え出そうとしてきました。例えば、ベクトル(配列)とテーブル(辞書)を呼び出し可能にしました。([1 2 3] 0)1を返します。そして([1 2 3] 0 4)はベクトルを修正して[4 2 3]にします。継続とジェネレータも直接呼び出し可能です。2つのプリミティブがあります:controlとtransfer。controlはbeginのようなものですが、継続をサポートしています。transferはコードから最も近いcontrolブロックを抜け出します。抜け出した時点のプログラムをエンコードする呼び出し可能な継続値を返します。そのため、再開するには(continuation 'some-value)とするだけです。(control (transfer 0) (lambda (value continuation) continuation))そして、(continuation 'something-else)を呼び出すことで、(transfer 0)の呼び出しが何か他のものを返すようにすることができます。関数(同じ呼び出し規約)のように動作し、その上にカリー化を実装できるかもしれません。

loneは実際に何個のシステムコールを使用していますか?

loneが起動すると、親プロセスによるexecveシステムコールが1つあります。次に、内部メモリ管理のための約12個のmmapシステムコールがあります。次に、標準入力からスクリプトファイルを読み取り、それを実行し、終了します。最小限です。実行中は、内部でより多くのLinuxシステムコールを発生させる可能性があります、mmapmunmapmremap(!)。モジュールシステムはまた、openatcloseを使用します。Linuxの300以上のシステムコールの幅広いレパートリーのうち、loneが使用するのはごく一部です。ただし、Lispレベルでシステムコールプリミティブを提供しています。そのため、Lispコードは何でもできます。それらのシステムコールの多くは、カーネルデータ構造も必要とします。それらのC構造を作成/操作するためのサポートも保留中です。例えば、ioctlは、端末のサイズを取得するなどのことを可能にする重要なシステムコールです。

それらのものは今からどのくらい離れていると思いますか?「ロードマップ」を拡張することを考えていますか?

正直に言うとわかりません。私は組織化があまり得意ではありません。ただし、AIの助けでかなり良くなりました。Claudeを一種のマネージャーとして使用しています。仕事は無限ですが、言語自体は完全な機能セットに近づいています。Claudeが私にとって行っている最も価値のあることは……コードレビューとプロジェクト管理です。私は15年以上にわたってほぼ一人でプログラミングしてきました。私のプロジェクトに別の目を持ち、コードを批評し、問題点や未開発の領域を発見することは、私にとって本当に世界を変えるものでした。loneのコードベース全体をClaudeに指摘し、厳しくすべての問題を指摘し、将来の開発領域を特定するように指示することがよくあります。AIとアイデアを議論することも本当に役立ち、多くの場合でアイデアを洗練することができました。AIがはるかに改善されたアルゴリズムを教えてくれたおかげで、ガベージコレクタとメモリアロケータを大幅に改善しました。私はまだAIにコードを書かせることを信頼していません。loneをあまりにも大切にしているので、コードベースに入るすべての行を精査せざるを得ません。実際に自分でコードを書くことは、私にとってしばしば教育的でもあります。しかし、Claudeを私のJavascriptベースの静的サイトジェネレータに指摘し、機能をvibecodeさせることは確かに罪悪感があります。

Claudeにコードベース全体をレビューするように依頼すると、問題を発見し、将来の方向性を提案し、それらをドキュメントにコンパイルします。「ユーザーはXを望んでいる」、「ユーザーはアプローチYを拒否した」、これは私の心の中にしか存在しない多くのこの一時的なコンテキストを管理するのに素晴らしいことです。本質的に、私のために自動的にTODOリストを管理してくれています。私はよく「これは今はやりません、将来のためにメモしておいて」と言うと、Claudeはプロジェクトのメモリに保存します。例えば、私の計画している機能の一つは、GCC/clangコンパイラAPIのサポートです。最も基本的なものはスタックプロテクタ関数です。それらのAPIについて知られているすべてのものが保存されたメモがあります。

他にこの言語に影響を与えたものは何ですか?「モダン」なLisp構文を使用していますが、これは今では普遍的のようです。

RubyとSchemeが私に影響を与えています。Rubyを書くのがいかに素晴らしかったか、そしてSchemeが言語としてどれだけクリーンだったかを思い出しました。両方を混ぜて、何が得られるかを見てみたかったのです。また、Lispが本当に解析しやすいということも大きな助けになりました。パーサを手書きで書いたら、突然、プレイできるすべてのネストされたリストが手に入りました。それが私が本当に興味があったことでした。しかし、評価器にFEXPRサポートを実装するまで、私は本当にLispを理解していませんでした。関数がリスト自体を受け取るという何かについて、ついに理解できました。

配列に[1 2 3]、辞書に{k v}を使うのは非常に直感的で良いと思います。ClojureとnewLispの他に、Ruby、Python、Javascriptもその構文を持っています。その構文を採用しないことは問題になる可能性があります!人気のある動的言語に慣れ親しんだプログラマにとって、多くの不必要な摩擦を追加するでしょう。Common Lispのリテラルもやや醜いです:#(1 2 3)はリストですが、#のため完全にはそうではありません?

あなたにとって良いコーディングスタイルとは何ですか?

私のCスタイルは、Linuxカーネルのスタイルを修正したものです。それに密接に従う傾向がありますが、一部のインスタンスでは独自の規則を打ち破ります。例えば、彼らは視覚的に解析しやすくするために均一なコードを本当に好みます。私はもっとコードを整列させ、装飾するのが好きです。私のRubyスタイルは句読点の欠如を好みました。method 'arg'の代わりにmethod('arg')。アイデアは、コードを英語の散文のように読めるようにすることでした。よく設計されたAPIもこの特性を持っていました:collection.each.with_index { |item, i| ... }。Lispスタイルについて意見を持つにはまだ早いかもしれませんが、構文的なネストを減らすことへの強い好みを開発しています。簡単な例:let。loneでは、letは次のように機能します:(let (a b c d ...) body...)ではなく、伝統的な(let ((a b) (c d) ...) body...)。この方法で行う理由は、関数適用実装を反映したものです。((lambda (x y)) 10 20) -> x 10, y 20(x 10)(y 20)のリストを使用するのは不自然に感じられ、それらは本当にペアではなく、私の脳にはより順序付けられたシーケンスのように感じられました:x 10 y 20

パフォーマンスはどのような感じですか?

loneが勝つベンチマークが1つあります:起動速度。RubyがRubygemsをロードするよりも速くプログラムを開始して終了することができます。アドホックなベンチマークでは、loneはPythonよりも約10-100倍……遅い……ことが明らかになりました。ただし、それらは異なるパフォーマンスカテゴリにあります:loneはリストレベルのインタプリタで、SICPの第5.4章のようなものです。PythonとRubyはバイトコードインタプリタです。私はバイトコードコンパイルに勇敢に抵抗しています。リストをバイトコードに変換するとLispの本質を失うと感じるからです。評価器がリストを処理していない場合、それは本当にリスト処理なのでしょうか?

CPUの分岐予測器が非常に洗練されてきて、通常の素朴なインタプリタでさえ速くなっているという記事を読んだことを覚えています。彼らは今では間接分岐を予測できるようです。それが私にいくらかの希望を与えてくれました!パフォーマンスに関する私の長期計画は、ブートストラップのための究極のベースラインとしてCインタプリタを維持し、次にlone自体の中にJITコンパイラを書くことでした。いくつかの実行可能ページにmmapして命令をエミットするだけです。それがコンパイルが始まる時です……Pythonはパフォーマンスの悪さで日常的に非難されているので、loneはさらにいじめられるのではないかと恐れています。しかし、真実は……ユーザースペースの作業には驚くほど実行可能であるはずです。bashに対してアドホックなベンチマークを実行し、絶対に打ち負かしました。bashは人々がいつも使っているものです!(ただし、再帰的なフィボナッチがbashの強みではなく、各反復で新しいプロセスを生成している可能性があるため、テストのアーティファクトかもしれません……)しかし、スクリプトでは、起動速度が非常に重要です。ブートストラップに0.5秒かかる仮想マシンを持つことはできず、loneはここで本当に輝きます。

loneの起動をさらに改善することもできます。例えば、Ruby VMは自身をブートストラップするためにかなりの量のコードを実行します。いたるところでハッシュテーブルを初期化するようなことを行います。環境がいくつかの変数をRubyオブジェクトにマッピングするようなもの。loneでは、すべてのハッシュテーブルを事前計算し、それらをC初期化子にコンパイルするビルドステップを追加する必要があります!そうすれば、Linuxは実行可能ファイルをmmapし、すぐに準備が整います、スクリプトに最適です!Zigのcomptimeはこれを本当に簡単にするでしょうが、loneを始めた時にはZigをあまり知りませんでした。

Loneにはいくつかの「組み込み」モジュールがあります。トップレベルの環境には、importとexportの2つのシンボルしか含まれていません。そこから、すべてのモジュールが環境をブートストラップします。ifquoteのようなものも、ユーザーが自分の環境のすべての名前を完全に制御できるようにするためにインポートする必要があります。リスト、リテラル、関数呼び出しメカニズム以外のすべてをインポートする必要があります。現在は非常にスパルタ的です。実装自体に必要なもの、例えばflattenを実装したところです。合計で、おそらく50の関数があり、主に言語機能を含むloneモジュールにあります:ifletbegincontrol/transferintercept/signal……

mmapは正確にはどのように機能しますか?

mmapは、本質的にカーネルにメモリの「ページ」を要求する関数です。mallocに似ていますが、より低レベルです。各ページは(最も一般的には)4096バイトのメモリで、その倍数を要求できます。また、それらのページに特定の保護を要求できます。読み取り可能なページ、書き込み可能なページ、実行可能なページ(JITコンパイラが使用するもの)です。メモリアロケータは、その上に高レベルのインターフェースを構築します。なぜなら、16バイトが必要な時に4 KiBを要求すると、多くのメモリを無駄にするからです。そのため、アロケータは128 MBを要求し、それをプログラムのニーズを満たすためにチャンクに切り分けます。

テストでは、さまざまな例がありますが、まだ言語ドキュメントはありません(実装関連のものだけ)。その時が来たら、どのようにアプローチしますか?

非常に不完全ですが、実際のところ、言語に追加するものがなくなってきています。すぐに標準ライブラリに取り組む必要があります。RubyとSchemeからインスピレーションを得るつもりです。Rubyの標準ライブラリは私の意見では比類のないもので、Schemeの命名規則も楽しんでいます。次のリストは反復プロトコルです。(for (each collection) (lambda (item) ...))のようなものになるでしょう。すでにいくつかのeach関数があり、そこではRubyをコピーしようとしました。ただし、再設計が必要です。それらはすべてジェネレータを返す必要があります。次に文字列操作関数。効率的な文字列連結を可能にする基本的な文字列ビルダーでも、loneを有用にするために大いに役立つでしょう。これを追加し、loneの反復の物語を完成させれば、loneでhiccupスタイルのWebフレームワークを書くことができると賭けます。

しかし、その段階に達した時にADHDに悩まされる危険があります。今はすべての楽しい低レベルの作業に取り組んでいます。それが完了し、「ああ、今は標準ライブラリを作るだけだ」となったら、それを管理するのに苦労するかもしれません……その時が来たらClaudeに私を鞭打たせます。

APLとLispはよりシンプルであると考え、それらを布教し、力を与え、物事がどれだけアクセス可能であるかを示そうとしています……私はめったに成功しません。私は「それはただのX Y Zだよ」と人々を驚かせようとしますが、まるで本当にシンプルであるかのように、しかし逆の効果を得ます、代わりに威圧します。

私はこれらの洞察を持つことを楽しんでいるのですよね。継続のように。ああ、それはただスタックフレームをコピーしているだけです。以前は魔法でしたが、今は普通のことです。私は人々がそのような洞察を楽しんでいないという感覚を持っています、なぜなら結局のところ彼らは気にしていないからです。loneの使命の一つは、人々が自分のシステムを持ち、探求するようにインスパイアすることです。マニュアルを書いた人々は、私にはできないと言いました。このsyscallのものは使えません、それはあなたのような凡人のためのものではありません。私は禁じられたものを使いたい、私はライブラリを作る側になりたい、ただ消費するだけではない。私はloneが他の人々にも同じことをするようにインスパイアすることを望みます。人々がそうしない理由の一つは責任です。自分のシステムを持つためには、それを所有しなければなりません。壊れたら、修正しなければなりません。人々はすでに人生に責任が多すぎると考えていて、コンピュータはただもう一つ追加するだけだと考えています。私はより多くの人々にその責任を選び、それがもたらすすべての報酬を楽しんでほしいと思います。

loneを書くことで、私は周囲の名前さえも完全に制御できます。コンピューティングにはレガシーがたくさんあるように感じます。すべてのこの根付いたコード、それは間違っていて、醜いですが、誰もそれを触れません、なぜならそれを削除するとすべてが壊れるからです。私は人々が勇気づけられて、悪いものを削除し始めるのを見てみたいです。もしかしたらLinuxユーザースペースを再構築するのは私ではないかもしれません、RustやZigの人々かもしれません。libcを取り除きました、彼らは警告しました、それは物を壊すだろう、DNSを壊すだろう、すべてを壊すだろう。私は脅迫される可能性がありましたが、押し通しました。私はただ世界に示したいのです、見てください、何も恐れることはないと。これらのレイヤーをすべて剥がすことができます。安全です。そして、楽しい旅でもあります!loneが何も生み出さなくても、少なくともそれにインスパイアできれば、私は幸せでしょう。

スタック全体を根本的に所有できるというこのメッセージが大好きです、なぜならあなたはできるからです。それはDeckerFennelとそのゲームの、同じインスピレーショナルな火です。

ええ。私はフリーソフトウェアのユーザーのエンパワーメントの価値が本当に好きです。コンピュータは世界を変える技術であり、私たちはそれらを所有すべきです、企業や政府にコントロールを任せることはできません。人々が所有権を気にせず、企業にコンピュータを「管理」させているのを見ると、私はかなり悲しくなります。その結果、汎用コンピュータはアプライアンスになり、何か下等なものになります。多くの人々がsystemdのようなプロジェクトを嫌っていますが、ある意味で、彼らは私がインスパイアしたいLinuxユーザースペースの「再想像」をまさに同じように行っています。私が望むよりも重い手かもしれませんが、systemdがいかに優れているかについては議論できません。彼らはそれを再発明し、それは素晴らしいものでした。伝統的な* nixシステムから離れたら、他にどのような人々が思いつくのかを見てみたいです。自分の戦いを選ぶことも重要です。loneをベアメタルのLispにしようとしたら、それがブートすることはなかったかもしれません。その一つは私よりずっと賢い誰かに任せます。jartのsector lispは良い例です……512バイト未満のブートセクタコードのLisp。

私は日常的にTermuxを使用して多くのことを自動化しています。loneがTermuxの中で生まれたと言ったら信じますか?私は電話でその多くを書きました。Androidはかなりの数のsyscallをブロックします(statxが私を困らせたもの)が、loneはAndroid上で動作し、テストスイートは100%パスします!

ソフトウェアのキャリアを拒否しました、あなたは何をしていますか?

私は医師です。2019年に医学部を卒業しました。AIから始まりました。高校で、私はプログラミングニューラルネットワークについて読んでいたので、生物学が好きになり始めました。ある日は10〜14時間連続で働き、医学を practiced します。他の日は全く働きません。今日はそのような日です。スケジュールはクリアで、今日のアポイントメントはありません。医学は自分の時間を自分で作るある程度の自由を与えてくれます。多くのキャリアパスから選択できます。外科医は事実上病院に住んでいます。私はもっと軽やかなライフスタイルを望んでいました、なぜならリラックスする時間が必要だからです。私は電子カルテを備えた人気のクリニックで働いています。それは本当に効率的で、特に私のようなテック系の人には。システムが遅かったり、機能がなかったりしても、私は自分のスキルでそれを補います。コンピュータに保存された小さなテンプレートでさえ、100倍速くします。そのため、迅速な診察が可能になり、患者との良い関係を維持できます。タッチタイピングができることさえ役立ちます!人々の目を見てすべてを入力できます!私の同僚にはできません!先ほど言及したRailsプロジェクトはまさにこれです。私は自分の痒いところを掻くために、独自の電子患者記録システムを作っています。失敗しても、私は十分にサービスを受けるでしょう。

非プロのプログラマは非常に少ないです。もちろんあなたは早くから始めましたが、なぜより多くのプロフェッショナルが自分の痒いところを掻かないと思うのですか?

多くの人が実際にはコンピュータが好きではないと思います。これを変えるには、コンピューティングがいかに素晴らしいかを彼らに興味を持たせる必要があります。学ぶには努力が必要ですが、ほとんどの人のマインドセットは結果に焦点を当てているようです。私は高校で、プログラミングのクラスに参加することを選んだ人々の間でその態度をすでに見ました。結果だけでなく、ソーセージがどのように作られているかを掘り下げるために、物事を気にするためには好奇心が必要です。人々にそれをどのようにインスパイアするかはわかりません。もしあなたがそれを行う方法を見つけたら、知りたいです。