lune-lang 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. lune_lang-0.1.0/.gitignore +22 -0
  2. lune_lang-0.1.0/LICENSE +21 -0
  3. lune_lang-0.1.0/PKG-INFO +213 -0
  4. lune_lang-0.1.0/README.md +183 -0
  5. lune_lang-0.1.0/documents/DIAGNOSTICS_COMPARISON.md +462 -0
  6. lune_lang-0.1.0/documents/ERROR_DIAGNOSTICS_SPEC.md +374 -0
  7. lune_lang-0.1.0/documents/ERROR_INDEX.md +571 -0
  8. lune_lang-0.1.0/documents/ERROR_INDEX_JA.md +571 -0
  9. lune_lang-0.1.0/documents/FORMATTER_SPEC.md +46 -0
  10. lune_lang-0.1.0/documents/FOR_LOOP_SPEC.md +126 -0
  11. lune_lang-0.1.0/documents/FUNCTION_TYPE_SPEC.md +111 -0
  12. lune_lang-0.1.0/documents/LANGUAGE_FUTURE_SPEC.md +553 -0
  13. lune_lang-0.1.0/documents/LANGUAGE_SPEC.md +973 -0
  14. lune_lang-0.1.0/documents/LAZY_EVALUATION_SPEC.md +267 -0
  15. lune_lang-0.1.0/documents/LEXER_PARSER_SPEC.md +1056 -0
  16. lune_lang-0.1.0/documents/LIST_LITERAL_SPEC.md +115 -0
  17. lune_lang-0.1.0/documents/LOCAL_TYPE_INFERENCE_SPEC.md +259 -0
  18. lune_lang-0.1.0/documents/MATCH_EXHAUSTIVENESS_SPEC.md +237 -0
  19. lune_lang-0.1.0/documents/MODULE_LOADING_SPEC.md +193 -0
  20. lune_lang-0.1.0/documents/README.md +48 -0
  21. lune_lang-0.1.0/documents/RECORD_FIELD_SPEC.md +404 -0
  22. lune_lang-0.1.0/documents/RELEASING.md +100 -0
  23. lune_lang-0.1.0/documents/REPL_SPEC.md +237 -0
  24. lune_lang-0.1.0/documents/STANDARD_LIBRARY_SPEC.md +352 -0
  25. lune_lang-0.1.0/documents/STRATEGY.md +154 -0
  26. lune_lang-0.1.0/documents/SYNTAX_SPEC.md +879 -0
  27. lune_lang-0.1.0/documents/TUTORIAL.md +1187 -0
  28. lune_lang-0.1.0/documents/TUTORIAL_EN.md +1181 -0
  29. lune_lang-0.1.0/documents/TYPE_CHECKER_SPEC.md +272 -0
  30. lune_lang-0.1.0/documents/VALUE_DISPLAY_SPEC.md +99 -0
  31. lune_lang-0.1.0/documents/WHILE_LOOP_SPEC.md +122 -0
  32. lune_lang-0.1.0/lune/__init__.py +13 -0
  33. lune_lang-0.1.0/lune/cli.py +279 -0
  34. lune_lang-0.1.0/lune/diagnostics.py +124 -0
  35. lune_lang-0.1.0/lune/evaluator.py +1346 -0
  36. lune_lang-0.1.0/lune/explanations.py +532 -0
  37. lune_lang-0.1.0/lune/explanations_ja.py +430 -0
  38. lune_lang-0.1.0/lune/fixer.py +66 -0
  39. lune_lang-0.1.0/lune/formatter.py +490 -0
  40. lune_lang-0.1.0/lune/layout.py +61 -0
  41. lune_lang-0.1.0/lune/lexer.py +294 -0
  42. lune_lang-0.1.0/lune/messages.py +358 -0
  43. lune_lang-0.1.0/lune/module_loader.py +196 -0
  44. lune_lang-0.1.0/lune/nodes.py +405 -0
  45. lune_lang-0.1.0/lune/parser.py +763 -0
  46. lune_lang-0.1.0/lune/repl.py +403 -0
  47. lune_lang-0.1.0/lune/tokens.py +214 -0
  48. lune_lang-0.1.0/lune/typechecker.py +1597 -0
  49. lune_lang-0.1.0/pyproject.toml +64 -0
  50. lune_lang-0.1.0/samples/basics.lune +15 -0
  51. lune_lang-0.1.0/samples/eval.lune +20 -0
  52. lune_lang-0.1.0/samples/for.lune +12 -0
  53. lune_lang-0.1.0/samples/function_types.lune +20 -0
  54. lune_lang-0.1.0/samples/list_tools.lune +36 -0
  55. lune_lang-0.1.0/samples/modules/main.lune +4 -0
  56. lune_lang-0.1.0/samples/modules/math.lune +6 -0
  57. lune_lang-0.1.0/samples/nullable.lune +48 -0
  58. lune_lang-0.1.0/samples/option.lune +12 -0
  59. lune_lang-0.1.0/samples/pipeline.lune +17 -0
  60. lune_lang-0.1.0/samples/records.lune +13 -0
  61. lune_lang-0.1.0/samples/stdlib.lune +16 -0
  62. lune_lang-0.1.0/samples/stream.lune +30 -0
  63. lune_lang-0.1.0/samples/while.lune +9 -0
  64. lune_lang-0.1.0/tests/test_book.py +113 -0
  65. lune_lang-0.1.0/tests/test_cli.py +179 -0
  66. lune_lang-0.1.0/tests/test_diagnostics.py +157 -0
  67. lune_lang-0.1.0/tests/test_evaluator.py +978 -0
  68. lune_lang-0.1.0/tests/test_explanations.py +181 -0
  69. lune_lang-0.1.0/tests/test_fixer.py +84 -0
  70. lune_lang-0.1.0/tests/test_formatter.py +149 -0
  71. lune_lang-0.1.0/tests/test_messages.py +278 -0
  72. lune_lang-0.1.0/tests/test_module_loader.py +197 -0
  73. lune_lang-0.1.0/tests/test_packaging.py +93 -0
  74. lune_lang-0.1.0/tests/test_parser.py +184 -0
  75. lune_lang-0.1.0/tests/test_playground.py +78 -0
  76. lune_lang-0.1.0/tests/test_playground_driver.py +124 -0
  77. lune_lang-0.1.0/tests/test_repl.py +382 -0
  78. lune_lang-0.1.0/tests/test_stdlib.py +323 -0
  79. lune_lang-0.1.0/tests/test_tutorial.py +61 -0
  80. lune_lang-0.1.0/tests/test_typechecker.py +1454 -0
@@ -0,0 +1,22 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+
5
+ # パッケージのビルド生成物 (python -m build / pip install -e .)
6
+ /build/
7
+ /dist/
8
+ *.egg-info/
9
+ .venv/
10
+
11
+ # 発表・投稿用の作業素材はローカルのみで管理する(公開しない)
12
+ /demo/prosym68/
13
+ /paper/
14
+
15
+ # Claude Code のローカル設定(許可済みコマンドの履歴を含み、秘密情報が混入し得る)
16
+ .claude/
17
+
18
+ # macOS Finder のメタデータ
19
+ .DS_Store
20
+
21
+ # 教科書の公開ビルド (.github/workflows/pages.yml がここへ組む)
22
+ /book/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hiroshi Koide
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.5
2
+ Name: lune-lang
3
+ Version: 0.1.0
4
+ Summary: A teaching-first lazy functional language whose diagnostics speak your native language
5
+ Project-URL: Homepage, https://koide55.github.io/lune-lang/
6
+ Project-URL: Playground, https://koide55.github.io/lune-lang/playground/
7
+ Project-URL: Repository, https://github.com/koide55/lune-lang
8
+ Project-URL: Documentation, https://koide55.github.io/lune-lang/book/
9
+ Project-URL: Issues, https://github.com/koide55/lune-lang/issues
10
+ Author-email: Hiroshi Koide <koide.hiroshi.934@m.kyushu-u.ac.jp>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: compiler,education,functional-programming,interpreter,lazy-evaluation,programming-language
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Education
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Natural Language :: English
19
+ Classifier: Natural Language :: Japanese
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
26
+ Classifier: Topic :: Software Development :: Compilers
27
+ Classifier: Topic :: Software Development :: Interpreters
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Lune — the Lazy and Native programming language
32
+
33
+ コンパイラが教えてくれる、遅延評価の関数型入門言語。
34
+ エラーも、その解説も、母語で読めます。
35
+
36
+ > Lune is a teaching-first functional language: lazy by default, with diagnostics that speak your native language. If you prefer English, start with [documents/TUTORIAL_EN.md](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL_EN.md) — every diagnostic and explanation defaults to English.
37
+
38
+ **[▶ Playground(インストール不要)](https://koide55.github.io/lune-lang/playground/)** · [診断カタログ](https://koide55.github.io/lune-lang/playground/errors.html) · [チュートリアル](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL.md)
39
+
40
+ [![CI](https://github.com/koide55/lune-lang/actions/workflows/ci.yml/badge.svg)](https://github.com/koide55/lune-lang/actions/workflows/ci.yml)
41
+ [![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/koide55/lune-lang/blob/main/pyproject.toml)
42
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/koide55/lune-lang/blob/main/LICENSE)
43
+
44
+ ---
45
+
46
+ ## プロローグ — 全員、部活に入ること
47
+
48
+ 転校初日に知らされた校則がこれだった。**「全生徒、いずれかの部に所属すること」**。
49
+
50
+ 運動部は続く気がしない。文化系の一覧を眺めていたら「プログラミング部」とある。パソコンで何か打っていれば終わる、いちばん楽そうなやつだ。僕は入部届を出した。
51
+
52
+ 部室のドアには、こう書かれていた。
53
+
54
+ > **部訓: 必要になるまで、やらない。一度やったことは、忘れない。**
55
+
56
+ ……楽そうな部、で合ってるよな?
57
+
58
+ ## 入部初日 — さっそく間違える
59
+
60
+ プログラミング部にはいってみたら、部員は先輩3人だけ、男子は自分だけだった。はたしてやっていけるのかな?
61
+
62
+ 「じゃあ転校生くん、まず書いてみて」と真知(まち)部長。見よう見まねで打ったら、初日からエラーを出した。
63
+
64
+ ```lune
65
+ let count = 10
66
+ let total = cont + 5
67
+ ```
68
+
69
+ ```text
70
+ $ ./bin/lune --check --lang ja guide.lune
71
+ error[TYP0001]: 未定義の名前: cont
72
+ --> guide.lune:2:13
73
+ |
74
+ 2 | let total = cont + 5
75
+ | ^^^^ この名前は定義されていない
76
+ = hint: もしかして `count` ですか?
77
+ = help: 詳しくは `lune explain TYP0001 --lang ja` を実行してください
78
+ ```
79
+
80
+ 身構えた僕に、部長は画面を指しながら言った。「読み方を教える。上から順に」
81
+
82
+ - `TYP0001` — エラーの出席番号(診断コード)。あとで調べるときの索引になる
83
+ - `^^^^` — 問題の場所そのもの。まずここを見る
84
+ - `= hint:` — 次の一手。**正解の候補まで書いてある**
85
+ - `= help:` — もっと深く知りたいときの案内
86
+
87
+ 「**うちの部では、エラーは赤点じゃなくて教材**。読めるようになったら、もう半分書けるのと同じ」
88
+
89
+ 思っていたのと違う。この部、楽じゃない。でも、理不尽でもなかった。
90
+
91
+ ## 部員紹介 — 教えてくれる先輩たち
92
+
93
+ - **真知(まち)部長** — `match` の抜けを絶対に見逃さない。「`Blue` のケースがありません」と**反例つき**で指摘してくる(TYP0007)。書きすぎれば「そのケースには到達しません」(TYP0009)。null も `T?` の型として扱わせ、`?.` / `??` / フロー narrowing まで仕込んでくる。厳しいが、指摘には全部理由がある。
94
+ - **英美(えいみ)先輩** — 解説担当。全30の診断コードに「意味・発生する最小例・直し方」の詳解を用意している(`lune explain CODE`、REPL では `:explain`)。日本語でも英語でも説明できる(`--lang ja`)。全文は[診断カタログ](https://koide55.github.io/lune-lang/playground/errors.html)に貼り出されている。
95
+ - **直美(なおみ)先輩** — 赤ペンと清書の担当。typo は did-you-mean の候補で機械的に直してくれるし(`lune fix`)、提出前には正準スタイルに整えてくれる(`lune fmt`)。整形で意味が変わっていないことを再パースで検証してから返す、と聞いてこの部の本気度を理解した。
96
+
97
+ 教わる流れは決まっている: **間違える → 読む → `explain` → `fix` → 確認**。チュートリアル第17章には「指定した診断をわざと出せたら正解」という逆転演習まであって、僕は初日にエラーの出し方から教わった。
98
+
99
+ ## 部訓の意味 — 「必要になるまで、やらない」(遅延評価)
100
+
101
+ Lune の値は、必要になるまで計算されない。
102
+
103
+ ```lune
104
+ let danger = crash()
105
+ let answer = 42
106
+ ```
107
+
108
+ `answer` を評価しても `danger` は使われないから、`crash()` は実行されない。「サボりじゃないの。**必要なものを、必要なときに、一度だけ**。そして一度やったことは忘れない(メモ化)」と部長は言う。
109
+
110
+ 信じられないなら目で見ればいい、と教わったのが REPL の `:trace` だ。
111
+
112
+ ```text
113
+ lune> :trace on
114
+ trace on
115
+ lune> let y = x + 1
116
+ ok # 宣言では何も評価されない
117
+ lune> y * 10
118
+ force y * 10
119
+ force x + 1 # y が必要になって初めて評価される
120
+ memo 1 + 1 => 2 # x はメモ化済み。再計算されない
121
+ => 3
122
+ => 30
123
+ 30 : Int
124
+ ```
125
+
126
+ この校風なら、無限リストとも普通に付き合える。どこまで計算が進んだかは `:thunks` が見せてくれる。
127
+
128
+ ```text
129
+ lune> let nat = naturalsFrom(1)
130
+ ok
131
+ lune> head(nat)
132
+ Some(1) : Option[Int]
133
+ lune> :thunks nat
134
+ nat : evaluated = Cons(1, <thunk>) # 先頭だけ計算済み。続きは手つかず
135
+ ```
136
+
137
+ ## 放課後 — 部室はブラウザの中にもある
138
+
139
+ **<https://koide55.github.io/lune-lang/playground/>**
140
+
141
+ 家に帰ってからも練習できるように、部室はブラウザの中にもある。処理系(Pure Python)が Pyodide 上でそのまま動くので、インストールは不要。実行・型チェック・整形・自動修正・explain・遅延評価のトレース・日本語/英語の切り替え、全部できる。
142
+
143
+ **REPL もそのまま入っている。** 出力ペインを「REPL」タブに切り替えると、`lune --repl` と同じセッションがブラウザの中で立ち上がる — 束縛は残り、`:type` も `:thunks` も `:trace` も効き、複数行の `def` も書ける。エディタで書いたプログラムを読み込んで、REPL から突くこともできる。
144
+
145
+ 「新規」で白紙から始められるし、手元の `.lune` ファイルは「開く」(`Ctrl/Cmd+O`、エディタへのドラッグ&ドロップでも可)で読み込める。書いたコードは「保存」(`Ctrl/Cmd+S`)で持ち帰れて、そのまま `./bin/lune` に食わせられる。
146
+
147
+ **`import` で分けたプログラムもそのまま動く。** エディタの上のファイルタブで `main.lune` の隣にモジュールを足せる(`math` でも `util.text` でも)。手元でファイルを並べたときとまったく同じ解決規則で、実行も型チェックもプログラム全体が対象になる。
148
+
149
+ ## 資料棚 — ドキュメント
150
+
151
+ - **[教科書『プログラミング言語 Lune』](https://koide55.github.io/lune-lang/book/)** — 序章+全13章+付録A〜E。腰を据えて体系的に学ぶならこちら。演習には解答付き。[1冊にまとめた PDF](https://koide55.github.io/lune-lang/book/lune-book.pdf)(A4・167ページ、しおり付き)もあります([原稿は books/](https://github.com/koide55/lune-lang/blob/main/books/README.md))
152
+ - [チュートリアル(日本語)](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL.md) / [Tutorial (English)](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL_EN.md) — 全20章。手を動かして1〜2時間で1周する入門。遅延評価は第2〜6章でじっくり、エラー駆動学習は第17章
153
+ - [診断コード索引(日本語)](https://github.com/koide55/lune-lang/blob/main/documents/ERROR_INDEX_JA.md) / [Error Index (English)](https://github.com/koide55/lune-lang/blob/main/documents/ERROR_INDEX.md) — 自動生成、テストで同期を強制
154
+ - [言語仕様](https://github.com/koide55/lune-lang/blob/main/documents/LANGUAGE_SPEC.md)ほか、[documents/](https://github.com/koide55/lune-lang/blob/main/documents/README.md) に仕様書一式
155
+ - [普及戦略](https://github.com/koide55/lune-lang/blob/main/documents/STRATEGY.md) — この部がどこへ向かうか
156
+
157
+ ## 入部届 — はじめかた
158
+
159
+ 必要なのは Python 3.10+ だけ。依存パッケージはありません。
160
+
161
+ ```sh
162
+ git clone https://github.com/koide55/lune-lang.git
163
+ cd lune-lang
164
+
165
+ ./bin/lune # REPL(:help でコマンド一覧)
166
+ ./bin/lune --check --lang ja file.lune # 型チェック(日本語診断)
167
+ ./bin/lune --eval answer file.lune # ファイルの束縛を評価
168
+ ./bin/lune --eval answer --trace file.lune # 遅延評価をトレース
169
+ ./bin/lune explain TYP0007 --lang ja # 診断コードの詳解
170
+ ./bin/lune fmt --write file.lune # 整形
171
+ ./bin/lune fix --write file.lune # typo の自動修正
172
+ ./bin/lune --version # 版番号(バグ報告に添えてください)
173
+ ```
174
+
175
+ 書き味の見本は [samples/](https://github.com/koide55/lune-lang/tree/main/samples) にあります(ADT・match・レコード・パイプライン `|>`・nullable・無限ストリームなど)。
176
+
177
+ ### pip で入れる
178
+
179
+ `pip` で入れると `lune` コマンドがどこからでも使えます(`./bin/lune` と同じもの)。
180
+
181
+ ```sh
182
+ pip install git+https://github.com/koide55/lune-lang.git
183
+
184
+ lune --check file.lune
185
+ LUNE_LANG=ja lune --check file.lune # 既定を日本語診断にする
186
+ ```
187
+
188
+ クローン済みなら `pip install -e .` で編集可能インストールにもできます。配布名は
189
+ `lune-lang`(PyPI の `lune` は別のパッケージが使用中)で、**PyPI への公開はまだ**です
190
+ (手順は [documents/RELEASING.md](https://github.com/koide55/lune-lang/blob/main/documents/RELEASING.md) に用意してあります)。
191
+
192
+ ## 顧問の先生より — 開発者向け
193
+
194
+ 処理系は `lune/` 以下の Pure Python(外部依存なし)。lexer → layout → parser → typechecker → evaluator の各層と、diagnostics / explanations / messages(英日メッセージカタログ)/ formatter / fixer / REPL で構成されています。
195
+
196
+ ```sh
197
+ PYTHONPATH=. python3 -m unittest discover -s tests # 処理系のテスト
198
+ bash books/tools/check_examples.sh # 教科書のコード例を実 CLI で検証
199
+ ```
200
+
201
+ テストは「発行されうる全診断コードに詳解があること」「詳解とメッセージに日本語訳があること」「生成物(診断カタログ)が陳腐化していないこと」まで強制します。間違いを教材にする部なので、自分自身にもそこそこ厳しめです。
202
+
203
+ CI([.github/workflows/ci.yml](https://github.com/koide55/lune-lang/blob/main/.github/workflows/ci.yml))は push と PR のたびに、Python 3.10〜3.14 でこの2つを回し、さらに wheel を組んで `lune` コマンドが単体で動くところまで確かめます。教科書も同じ CI で HTML と PDF に組み上げます(公開しているものと同じ手順です)。
204
+
205
+ ## ライセンス
206
+
207
+ [MIT License](https://github.com/koide55/lune-lang/blob/main/LICENSE)。Copyright (c) 2026 Hiroshi Koide。
208
+
209
+ ---
210
+
211
+ 気づけば、放課後の部室にいちばん長く残っているのは僕になっていた。
212
+
213
+ *Lazy* は評価戦略のこと。*Native* はネイティブコードのこと……ではなく **native language(母語)** のことだと、英美先輩は最初に教えてくれた。それでは、よい部活動を。
@@ -0,0 +1,183 @@
1
+ # Lune — the Lazy and Native programming language
2
+
3
+ コンパイラが教えてくれる、遅延評価の関数型入門言語。
4
+ エラーも、その解説も、母語で読めます。
5
+
6
+ > Lune is a teaching-first functional language: lazy by default, with diagnostics that speak your native language. If you prefer English, start with [documents/TUTORIAL_EN.md](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL_EN.md) — every diagnostic and explanation defaults to English.
7
+
8
+ **[▶ Playground(インストール不要)](https://koide55.github.io/lune-lang/playground/)** · [診断カタログ](https://koide55.github.io/lune-lang/playground/errors.html) · [チュートリアル](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL.md)
9
+
10
+ [![CI](https://github.com/koide55/lune-lang/actions/workflows/ci.yml/badge.svg)](https://github.com/koide55/lune-lang/actions/workflows/ci.yml)
11
+ [![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/koide55/lune-lang/blob/main/pyproject.toml)
12
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/koide55/lune-lang/blob/main/LICENSE)
13
+
14
+ ---
15
+
16
+ ## プロローグ — 全員、部活に入ること
17
+
18
+ 転校初日に知らされた校則がこれだった。**「全生徒、いずれかの部に所属すること」**。
19
+
20
+ 運動部は続く気がしない。文化系の一覧を眺めていたら「プログラミング部」とある。パソコンで何か打っていれば終わる、いちばん楽そうなやつだ。僕は入部届を出した。
21
+
22
+ 部室のドアには、こう書かれていた。
23
+
24
+ > **部訓: 必要になるまで、やらない。一度やったことは、忘れない。**
25
+
26
+ ……楽そうな部、で合ってるよな?
27
+
28
+ ## 入部初日 — さっそく間違える
29
+
30
+ プログラミング部にはいってみたら、部員は先輩3人だけ、男子は自分だけだった。はたしてやっていけるのかな?
31
+
32
+ 「じゃあ転校生くん、まず書いてみて」と真知(まち)部長。見よう見まねで打ったら、初日からエラーを出した。
33
+
34
+ ```lune
35
+ let count = 10
36
+ let total = cont + 5
37
+ ```
38
+
39
+ ```text
40
+ $ ./bin/lune --check --lang ja guide.lune
41
+ error[TYP0001]: 未定義の名前: cont
42
+ --> guide.lune:2:13
43
+ |
44
+ 2 | let total = cont + 5
45
+ | ^^^^ この名前は定義されていない
46
+ = hint: もしかして `count` ですか?
47
+ = help: 詳しくは `lune explain TYP0001 --lang ja` を実行してください
48
+ ```
49
+
50
+ 身構えた僕に、部長は画面を指しながら言った。「読み方を教える。上から順に」
51
+
52
+ - `TYP0001` — エラーの出席番号(診断コード)。あとで調べるときの索引になる
53
+ - `^^^^` — 問題の場所そのもの。まずここを見る
54
+ - `= hint:` — 次の一手。**正解の候補まで書いてある**
55
+ - `= help:` — もっと深く知りたいときの案内
56
+
57
+ 「**うちの部では、エラーは赤点じゃなくて教材**。読めるようになったら、もう半分書けるのと同じ」
58
+
59
+ 思っていたのと違う。この部、楽じゃない。でも、理不尽でもなかった。
60
+
61
+ ## 部員紹介 — 教えてくれる先輩たち
62
+
63
+ - **真知(まち)部長** — `match` の抜けを絶対に見逃さない。「`Blue` のケースがありません」と**反例つき**で指摘してくる(TYP0007)。書きすぎれば「そのケースには到達しません」(TYP0009)。null も `T?` の型として扱わせ、`?.` / `??` / フロー narrowing まで仕込んでくる。厳しいが、指摘には全部理由がある。
64
+ - **英美(えいみ)先輩** — 解説担当。全30の診断コードに「意味・発生する最小例・直し方」の詳解を用意している(`lune explain CODE`、REPL では `:explain`)。日本語でも英語でも説明できる(`--lang ja`)。全文は[診断カタログ](https://koide55.github.io/lune-lang/playground/errors.html)に貼り出されている。
65
+ - **直美(なおみ)先輩** — 赤ペンと清書の担当。typo は did-you-mean の候補で機械的に直してくれるし(`lune fix`)、提出前には正準スタイルに整えてくれる(`lune fmt`)。整形で意味が変わっていないことを再パースで検証してから返す、と聞いてこの部の本気度を理解した。
66
+
67
+ 教わる流れは決まっている: **間違える → 読む → `explain` → `fix` → 確認**。チュートリアル第17章には「指定した診断をわざと出せたら正解」という逆転演習まであって、僕は初日にエラーの出し方から教わった。
68
+
69
+ ## 部訓の意味 — 「必要になるまで、やらない」(遅延評価)
70
+
71
+ Lune の値は、必要になるまで計算されない。
72
+
73
+ ```lune
74
+ let danger = crash()
75
+ let answer = 42
76
+ ```
77
+
78
+ `answer` を評価しても `danger` は使われないから、`crash()` は実行されない。「サボりじゃないの。**必要なものを、必要なときに、一度だけ**。そして一度やったことは忘れない(メモ化)」と部長は言う。
79
+
80
+ 信じられないなら目で見ればいい、と教わったのが REPL の `:trace` だ。
81
+
82
+ ```text
83
+ lune> :trace on
84
+ trace on
85
+ lune> let y = x + 1
86
+ ok # 宣言では何も評価されない
87
+ lune> y * 10
88
+ force y * 10
89
+ force x + 1 # y が必要になって初めて評価される
90
+ memo 1 + 1 => 2 # x はメモ化済み。再計算されない
91
+ => 3
92
+ => 30
93
+ 30 : Int
94
+ ```
95
+
96
+ この校風なら、無限リストとも普通に付き合える。どこまで計算が進んだかは `:thunks` が見せてくれる。
97
+
98
+ ```text
99
+ lune> let nat = naturalsFrom(1)
100
+ ok
101
+ lune> head(nat)
102
+ Some(1) : Option[Int]
103
+ lune> :thunks nat
104
+ nat : evaluated = Cons(1, <thunk>) # 先頭だけ計算済み。続きは手つかず
105
+ ```
106
+
107
+ ## 放課後 — 部室はブラウザの中にもある
108
+
109
+ **<https://koide55.github.io/lune-lang/playground/>**
110
+
111
+ 家に帰ってからも練習できるように、部室はブラウザの中にもある。処理系(Pure Python)が Pyodide 上でそのまま動くので、インストールは不要。実行・型チェック・整形・自動修正・explain・遅延評価のトレース・日本語/英語の切り替え、全部できる。
112
+
113
+ **REPL もそのまま入っている。** 出力ペインを「REPL」タブに切り替えると、`lune --repl` と同じセッションがブラウザの中で立ち上がる — 束縛は残り、`:type` も `:thunks` も `:trace` も効き、複数行の `def` も書ける。エディタで書いたプログラムを読み込んで、REPL から突くこともできる。
114
+
115
+ 「新規」で白紙から始められるし、手元の `.lune` ファイルは「開く」(`Ctrl/Cmd+O`、エディタへのドラッグ&ドロップでも可)で読み込める。書いたコードは「保存」(`Ctrl/Cmd+S`)で持ち帰れて、そのまま `./bin/lune` に食わせられる。
116
+
117
+ **`import` で分けたプログラムもそのまま動く。** エディタの上のファイルタブで `main.lune` の隣にモジュールを足せる(`math` でも `util.text` でも)。手元でファイルを並べたときとまったく同じ解決規則で、実行も型チェックもプログラム全体が対象になる。
118
+
119
+ ## 資料棚 — ドキュメント
120
+
121
+ - **[教科書『プログラミング言語 Lune』](https://koide55.github.io/lune-lang/book/)** — 序章+全13章+付録A〜E。腰を据えて体系的に学ぶならこちら。演習には解答付き。[1冊にまとめた PDF](https://koide55.github.io/lune-lang/book/lune-book.pdf)(A4・167ページ、しおり付き)もあります([原稿は books/](https://github.com/koide55/lune-lang/blob/main/books/README.md))
122
+ - [チュートリアル(日本語)](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL.md) / [Tutorial (English)](https://github.com/koide55/lune-lang/blob/main/documents/TUTORIAL_EN.md) — 全20章。手を動かして1〜2時間で1周する入門。遅延評価は第2〜6章でじっくり、エラー駆動学習は第17章
123
+ - [診断コード索引(日本語)](https://github.com/koide55/lune-lang/blob/main/documents/ERROR_INDEX_JA.md) / [Error Index (English)](https://github.com/koide55/lune-lang/blob/main/documents/ERROR_INDEX.md) — 自動生成、テストで同期を強制
124
+ - [言語仕様](https://github.com/koide55/lune-lang/blob/main/documents/LANGUAGE_SPEC.md)ほか、[documents/](https://github.com/koide55/lune-lang/blob/main/documents/README.md) に仕様書一式
125
+ - [普及戦略](https://github.com/koide55/lune-lang/blob/main/documents/STRATEGY.md) — この部がどこへ向かうか
126
+
127
+ ## 入部届 — はじめかた
128
+
129
+ 必要なのは Python 3.10+ だけ。依存パッケージはありません。
130
+
131
+ ```sh
132
+ git clone https://github.com/koide55/lune-lang.git
133
+ cd lune-lang
134
+
135
+ ./bin/lune # REPL(:help でコマンド一覧)
136
+ ./bin/lune --check --lang ja file.lune # 型チェック(日本語診断)
137
+ ./bin/lune --eval answer file.lune # ファイルの束縛を評価
138
+ ./bin/lune --eval answer --trace file.lune # 遅延評価をトレース
139
+ ./bin/lune explain TYP0007 --lang ja # 診断コードの詳解
140
+ ./bin/lune fmt --write file.lune # 整形
141
+ ./bin/lune fix --write file.lune # typo の自動修正
142
+ ./bin/lune --version # 版番号(バグ報告に添えてください)
143
+ ```
144
+
145
+ 書き味の見本は [samples/](https://github.com/koide55/lune-lang/tree/main/samples) にあります(ADT・match・レコード・パイプライン `|>`・nullable・無限ストリームなど)。
146
+
147
+ ### pip で入れる
148
+
149
+ `pip` で入れると `lune` コマンドがどこからでも使えます(`./bin/lune` と同じもの)。
150
+
151
+ ```sh
152
+ pip install git+https://github.com/koide55/lune-lang.git
153
+
154
+ lune --check file.lune
155
+ LUNE_LANG=ja lune --check file.lune # 既定を日本語診断にする
156
+ ```
157
+
158
+ クローン済みなら `pip install -e .` で編集可能インストールにもできます。配布名は
159
+ `lune-lang`(PyPI の `lune` は別のパッケージが使用中)で、**PyPI への公開はまだ**です
160
+ (手順は [documents/RELEASING.md](https://github.com/koide55/lune-lang/blob/main/documents/RELEASING.md) に用意してあります)。
161
+
162
+ ## 顧問の先生より — 開発者向け
163
+
164
+ 処理系は `lune/` 以下の Pure Python(外部依存なし)。lexer → layout → parser → typechecker → evaluator の各層と、diagnostics / explanations / messages(英日メッセージカタログ)/ formatter / fixer / REPL で構成されています。
165
+
166
+ ```sh
167
+ PYTHONPATH=. python3 -m unittest discover -s tests # 処理系のテスト
168
+ bash books/tools/check_examples.sh # 教科書のコード例を実 CLI で検証
169
+ ```
170
+
171
+ テストは「発行されうる全診断コードに詳解があること」「詳解とメッセージに日本語訳があること」「生成物(診断カタログ)が陳腐化していないこと」まで強制します。間違いを教材にする部なので、自分自身にもそこそこ厳しめです。
172
+
173
+ CI([.github/workflows/ci.yml](https://github.com/koide55/lune-lang/blob/main/.github/workflows/ci.yml))は push と PR のたびに、Python 3.10〜3.14 でこの2つを回し、さらに wheel を組んで `lune` コマンドが単体で動くところまで確かめます。教科書も同じ CI で HTML と PDF に組み上げます(公開しているものと同じ手順です)。
174
+
175
+ ## ライセンス
176
+
177
+ [MIT License](https://github.com/koide55/lune-lang/blob/main/LICENSE)。Copyright (c) 2026 Hiroshi Koide。
178
+
179
+ ---
180
+
181
+ 気づけば、放課後の部室にいちばん長く残っているのは僕になっていた。
182
+
183
+ *Lazy* は評価戦略のこと。*Native* はネイティブコードのこと……ではなく **native language(母語)** のことだと、英美先輩は最初に教えてくれた。それでは、よい部活動を。