
2026/03/09 3:18
M&M を使ってプログラミング言語を作りました。
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
要約:
MNM Langは、ソースコードをキャンディカラーのPNG画像に変換し、決定論的な画像処理で完全にラウンドトリップしてテキストへ戻せる風変わりなプログラミング言語です。コンパイラーは
.mnmファイルを読み取り、プログラム構造の視覚表現を出力し、デコンパイラーはピクセルパターンを解釈して正確に元のコードを再構築します。実行時データはJSONサイドカー ファイルに別途保存されるため、ビジュアルレイアウトには構造情報のみがエンコードされています。命令は色ファミリー(青・緑・黄・橙・茶・赤)に整理され、オペランドはトークン長で符号化されます。本プロジェクトはコマンドラインインターフェース、オンラインプレイグラウンド、サンプルプログラム、AI生成キャンディスプライト、およびパーシング・実行時挙動・デコード・アセット整合性を網羅したテストで構成されています。作者は美的魅力と工学的厳密さの間にある遊び心を継続的に洗練し、ツール拡張や追加例の提供などを検討しつつラウンドトリップの忠実性を保つことを目指しています。
要約骨格
本文が主に伝えたい内容(メインメッセージ)
MNM Langは、ソースコードをキャンディカラー画像へ変換する遊び心あるプログラミング言語であり、完璧なラウンドトリップのコンパイルとデコンパイルが可能です。
証拠/根拠(このように述べられる理由)
コンパイラーは
.mnmファイルからPNGを生成し、デコンパイラーは決定論的画像処理で正確なソースを再構築します。実行時データはサイドカーJSONファイルに格納されるため、ビジュアルレイアウトには構造のみがエンコードされています。
関連事例/背景(文脈・過去の出来事・周囲情報)
- 命令は色ファミリー(青、緑、黄、橙、茶、赤)でグループ化される。
- オペランドはトークン長によって符号化される。
- 本プロジェクトにはCLIとブラウザプレイグラウンド、サンプルプログラム、AI生成キャンディスプライト、およびパーシング・実行時・デコード・アセット健全性を網羅する広範なテストが含まれる。
今後起こり得ること(本文で書かれた将来の展開/予測)
作者は、遊び心あるキャンディコードと堅牢なエンジニアリングのバランスを保ちつつ、ツール拡張や例の追加などを検討しながら完璧なラウンドトリップ忠実性を維持する計画です。
この影響が及ぼす可能性(ユーザー/企業/業界)
利用者は視覚的にプログラミング概念を学べ、開発者は独自の言語設計と決定論的画像ベースデコンパイルを実験できる。プロジェクトは創造的な教育ツールやビジュアルエンコーディングを活用したニッチドメイン特化型言語へのインスピレーションになる可能性があります。
本文
この記事のどれくらいがAIによって生成されたもの(コード・文章・構成)ですか?
残りは人間が書いたものです。
もしテーブルに置いたM&Mのお菓子の山が実際のプログラムだったら?
文字通りです。M&M に似たキャンディを特定のパターンで並べると、そのパターンが実行可能なコードになる――という想像です。
物語時間 – この投稿に直接埋め込まれたインライン対話型インタープリタ付き。
すべては、開けすぎて「GEMS†」―インド版M&Mを床に落としてしまったことから始まりました。落ちると矢印形のパターンになり、ふざけたアイデアが湧きました。「M&Mでプログラムを書けないだろうか?」――このプロジェクトはその一例です。
制約
散らばったキャンディを見て、いくつかの制約が浮上しました:
- 有効な色は 6 色だけ。
- 写真では正確なシンボルデータを表すには不向き。
- キャンディは丸く光沢があり、散らばりやすく扱いにくい。
- 文字列は画像で扱うのが難しい。
- 面白さを保ちつつ実際に動作する必要がある。
そこで私は MNM Lang を作りました。小さな言語で、
- ソースコードは 6 種類の文字列で書く:B G R Y O N(Blue, Green, Red, Yellow, Orange, Brown)。
- それらをキャンディスプライトからなる PNG にコンパイル。
- PNG を逆にして正確にソースへ戻すことができる。
- 軽度の歪みを含む画像からもプログラムを復元できる「制御付き写真デコーダ」を備える(うまくいけば)。
CLI、ブラウザ上のプレイグラウンド、サンプルプログラム、テスト、そしてプロジェクト専用に生成されたスプライトパックがあります。実用的というよりは、「ふざけたアイデアを真面目に実装したもの」です。
コア課題
6 色しかないキャンディで、以下の条件を満たす言語を作るにはどうするか?
- 手で置きやすい。
- 写真から読み取りやすい。
- 実際に使えるほど表現力がある。
- 全体として「おふざけ」さえ保てるくらい小さい。
私の答えは:色ファミリーをオペコード、個数をオペランドとすることです。
のようなトークンは「青いものが 3 個ある」という意味ではなく、特定のオペコードを表します。BBB
は整数リテラル 3 を意味し、オペランド値はRRRRで決まります。len(token) - 1
この単一ルールにより、テキストで簡単に書け、画像セルへレンダリングでき、ジオメトリから再構築できるようになり、適切な冗談感を保てます。
「青いクラスターは制御フロー、緑はスタックと変数、黄は算術、橙は I/O、茶はラベルと文字列、赤はスタック操作と論理。数値5を表したいなら 6 個の赤キャンディを使う。」
文字列
最初に直面した分岐点が文字列です。
テキストを直接キャンディレイアウトに埋め込むか、ミクロアルファベットを発明することもできましたが、技術的には可能でも精神的には酷いでしょう。プロジェクトの楽しさは視覚構造にあり、砂糖の殻で OCR 耐性 QR コードを作ることではありません。
そこで文字列と初期変数をサイドカー JSON ファイルへ移動しました。プログラムは 2 部分からなります:
にある視覚的キャンディレイアウト。.mnm
にある非可視実行時データ。.mnm.json
例として hello world は次のようになります。
OO Y OOOOOO BBBBBB
コンパイラ出力(サニック形式)とそのサイドカーは:
{ "strings": ["Hello, world!"], "variables": [], "inputs": { "int": [], "str": [] } }
この分離により、画像は構造のみを担い、実行時入力はキャンディを動かさずに変更できるようになります。
六色で構成された言語
文字列が画像から外れたことで、言語の設計が整いました:
- 青:ジャンプ・呼び出し・停止
- 緑:push/load/store/dup/pop/inc/dec
- 黄:算術と比較
- 橙:出力と入力
- 茶:ラベルと文字列操作
- 赤:swap、rotate、ブール論理
各行の最初のトークンがオペコードです。1 行= 1 命令;キャンディクラスター= トークン;個数が多いほど別バリアントになります。
第一章の完全階乗例(最初のセクション)は見た目は滑稽ですが機能します。
コンパイラ & デコンパイラ
「このプログラムはキャンディだ」というギミックに合わせて、コンパイラは AST で止まらず画像を出力する必要があります。固定グリッド上に正規化された
.mnm ソースを描画します:
- 1 セル= 1 文字。
- スペースは空セル。
- セルには透明背景のキャンディスプライト。
- 出力は PNG。
逆方向は trivial:行列数を復元し、各セルをサンプリングして色分け、末尾スペースを除去して再パース。これにより完全な round‑trip が得られ、ヒューリスティクスなしでコンパイラ自体が小さな画像フォーマットとなります。
スプライト生成
手描きはしませんでした。AI 画像生成†を使って 6 種類の M&M スタイルトークン(青、緑、赤、黄、橙、茶)を作成しました。初期生成物にはスタジオ背景、不揃いな影、スケール差がありました。最終パイプラインは次の通りです:
- 透明背景で孤立したキャンディを生成。
- 正規化:最大のキャンディ領域を切り取り、128×128 キャンバスに中央配置。
- デコンパイラと写真分類器用にカラーパレットメタデータを抽出。
正規化は重要でした。影が強すぎるとぼかし後にキャンディが合体してしまい、写真デコードが失敗します。
写真デコーダ
v1 デコーダは決定的画像処理で動作:
- 境界から背景色を推定。
- キャンディ様の前景ブロブをセグメント化。
- 各ブロブを標準六色パレットに分類。
- ブロブを行へクラスタリング。
- セントロイド間隔から空白を推定。
- 再構築されたソースを再パース。
以下の条件で驚くほど動作します:
- オーバーヘッド写真
- コントラストの高い単純背景
- キャンディが分離している場合
- 軽度のぼかし
- 小さな回転または視点歪み
ただし、カジュアルな台所テーブル撮影や iPhone の劇的アングルには対応できません。
実際のサンプルプログラム
hello world 以外にも、言語の各部分を押す例を追加しました:
:文字列キューと連結。echo_name
:ラベル、変数変更、算術、条件分岐、ループ。factorial
:剰余、枝分かれ、文字列スロット、繰り返し出力。fizzbuzz
FizzBuzz をキャンディグリッドにコンパイルして正しく実行できる様子を見ると、単なる呪われた新奇構文ではなく、見た目はスナックのような実際に機能する小さな VM であることが分かります。
ツールチェーン
CLI は次を提供します:
compile decompile run serve list examples
ブラウザプレイグラウンドでは、例をロードし、ソース/サイドカー JSON を編集してキャンディシートをプレビュー、即座に実行、または画像をアップロードしてソースへデコードできます。2 つのビューで AST と実行トレースをツリー形式で表示します。
hello world のような小さなプログラムでは AST が読みやすくなります:
Program (3 instruction(s)) |-- labels | `-- (none) `-- instructions |-- [0] PRINT_STR @ line 1 (string[0] from Y) | `-- source: OO Y |-- [1] NEWLINE @ line 2 | |-- source: OOOOOO | `-- operands: (none) `-- [2] HALT @ line 3 |-- source: BBBBBB `-- operands: (none)
階乗の実行トレースでは分岐判断が確認できます。
テスト
次の項目をテストしました:
- パーサ検証
- 実行時意味論
- サンプルゴールデン出力
- 正確な round‑trip(ソース → PNG → ソース)
- ぼかし・回転・視点歪み付き合成写真デコード
- API 動作
- プレイグラウンドのスモークフロー
- スプライト資産の健全性チェック
バグとしては、完全に不透明な RGB 画像を前景と誤認したケースや、スプライト正規化で過剰なドロップシャドウが残ったケースがあります。テストは「キャンディを一度描画したもの」と「実際のシステム」を分離しています。
トレードオフ & 哲学
ジョークプロジェクトには必ず選択肢があります:冗談を守るか、実装を守るか。MNM Lang は両方を強いられました:
- 青クラスター幅=分岐命令
- 赤ラン長=整数リテラル
- 文字列は OCR が酷いので JSON に移動
- コンパイル済み PNG は正確;写真は「制御付き」
これらの規則は前提に基づいて正当化されます。
ダウンロード
試したい場合はリポジトリをクローンしてください:
git clone https://github.com/mufeedvh/mnmlang.git cd mnmlang uv run mnm serve
fizzbuzz をロードしてレンダリングし、コンパイルされた PNG を眺めてください。バッグから注ぎ出せるプログラミング言語のように見えます。
これは「ばかげたプロジェクト」シリーズ第 1 作です。次回は自分のキーボードドライババイナリを逆解析し、バックライトでスネークゲームを動かす方法をご紹介します。
𝕏(旧 X)でフォローしてください。