Onion の実用的品質基準¶
「実用的品質」は意図的に曖昧な表現なので、このファイルではそれを客観的に測定可能な指標のセットに固定します。各行には実行可能な測定方法と閾値があり、すべての行が通過したときに言語は基準に達したとみなされます。
ベースライン数値は 2026-07-26 時点(develop @ c2126299)の実測値です。前回のベースライン
(2026-07-26 @ 871fe5a1)は、effect-table / tool-capability / tool-contracts の作業
(#356、#357、#358)が入った後にはすでに乖離していました——テスト数は 2590 と記録されて
いましたが実際は 2644、ガイドは 14/14 に対し 15/15(docs/guide/tools.md が #357 で追加)、
診断コードは 77 に対し 80(capability boundary が追加した E0077–E0079)でした。
| # | 次元 | 測定方法 | 現在値(2026-09-03) | 合格閾値 |
|---|---|---|---|---|
| 1 | テストスイート | sbt shutdown && sbt -Duser.language=en testFull(下記の注記を参照) |
5023 pass / 0 fail / 1 cancelled | 0 failed, 0 skipped |
| 2 | サンプルの健全性 | SampleCompilesSpec / SampleProgramsSpec(どちらも run/*.on 全件をコンパイル) |
248 / 248 compile | すべてコンパイル、rot なし |
| 3 | 大規模プログラム | 100行以上の run/*.on をそのまま end-to-end で実行できる数 |
188(AccessLogAnalyzer、AirlineReservation、AntColony、AstronomyCatalog、AuctionHouse、Automaton、BankLedger、BankSystem、BattleshipSim、BinaryHeap、Blackjack、Blockchain、BookClub、BowlingGame、BrainFuck、BrokenLogDemo、BudgetTracker、BugTracker、CacheSimulator、CalendarManager、CarRentalFleet、CellularAutomata、CensusAnalyzer、ChemCalculator、Chess、CinemaBooking、CipherSuite、CircuitBreakerSim、CircuitSimulator、ClinicRecords、CodeContest、ColorPalette、ConferenceSchedule、ConnectFour、ConwayLife、CourseRegistration、CpuScheduler、CryptoPortfolio、DNAAnalysis、DependencyResolver、DnaAnalyzer、DoctorScheduler、DungeonCrawler、ElevatorDispatcher、EmployeeManager、EpidemiologySim、EspressoShop、EventTicketing、ExpenseAuditor、ExprEval、FamilyTree、FileSystemSim、FitnessTracker、FlashcardDeck、FleetManager、ForthMachine、GameOfLife、GameStore、GenericLeaderboard、GeneticAlgorithm、GeneticSequencer、GradeBook、GradeReport、GraphAlgorithms、GraphSearch、HMTypeInference、HRSystem、HospitalWard、HotelReservation、HuffmanCode、HuffmanCoding、InsuranceClaims、IntervalCalendar、Inventory、InventoryManager、InventoryReport、JobScheduler、KaraokeNight、KingdomSim、LambdaCalc、LibraryCatalog、LibrarySystem、LispInterp、LogAnalytics、LogCorrelator、Mandelbrot、MarkdownConverter、MarkovText、Mastermind、MathParser、MatrixCalc、MaxFlow、MazeSolver、MiniGit、MiniRpg、MiniSQL、MiniTypeChecker、MiniVcs、MorseCode、MortgageCalc、MovieRecommender、MuseumCollection、MusicEngine、MusicFestival、MusicLibrary、MusicTheory、NationalParkTracker、NetCidr、NetworkMonitor、NeuralNet、NumberTheory、NutritionTracker、OrderReport、Othello、PackageDelivery、PackageInstaller、ParallelCrawler、ParkingGarage、PaymentProcessor、PayrollReport、PerfReview、PersonalFinance、PetShelter、PetriNet、PharmacySystem、PlantCare、PlaylistManager、PokerHands、PolyCalc、PolynomialAlgebra、ProjectTracker、PropCheck、PropLogic、PropertyManager、RankedChoice、RationalCalc、RecipeBook、RecipeManager、RecipeVault、RegexEngine、RestaurantOrders、RideSharePool、RuleEngine、ScaleAnalyzer、ShapeProcessor、ShipmentTracker、ShoppingCart、SmartHome、SnippetLibrary、SocialNetwork、SortAlgorithms、SortingShowcase、SpaceMission、SpellCheck、SpreadsheetCalc、SprintPlanner、StatsApp、StockPortfolio、StudentGradeBook、Sudoku、SudokuSolver、SupplyChain、SymbolicMath、TaskPlanner、TerrainGenerator、TextAnalytics、TextAnalyzer、TextDiff、TextTransformPipeline、TicTacToe、TimeSeries、TimesheetTracker、TodoManager、ToolDemo、TournamentStandings、TournamentTracker、TradeMatchingEngine、TrainDispatch、TransitPlanner、Trie、UnionFind、VendingMachine、VirtualMachine、VirtualShell、VotingMethods、WeatherReport、WordLadder、WordSearch) | ≥ 5 |
| 4 | 機能網羅性 | 下記のチェックリストが大規模サンプル内で実証されている | 完了 | すべての項目 ✓ |
| 5 | 既知の使い勝手バグ | 実装済みだが到達不能/壊れた機能として未解決のもの | 0 | 0 |
| 6 | ドキュメントの対等性 | docs/guide と docs/ja/guide の数 + すべてのコードブロックがコンパイル可能 |
15 / 15 | 対等性 + すべてのブロックを検証 |
| 7 | 診断メッセージ | 英語と日本語の E00xx コード |
90 | よくあるエラーごとに専用コード |
SBT_OPTS にプロジェクト既定を下回るヒープ値を設定しないでください。 .jvmopts は既定を
-Xmx10g に固定しています(run/ サンプル群の増加に伴い 4g から引き上げ済み。CHANGELOG の
0.10.18 を参照)。これを下回るヒープを SBT_OPTS に設定すると——以前の悪い例だった
-Xmx2g に限らず、-Xmx4G も実際に踏まれています——スイートの途中で
OutOfMemoryError を起こします(#691 参照)。SBT_OPTS を他のフラグのために設定する
場合も、ヒープは -Xmx10G 以上を維持してください。
-Duser.language=en は重要です。エラーメッセージは二言語で JVM の既定ロケールから解決される
ため、メッセージ文字列を検査するテストは日本語ロケールでは通り、英語ロケールで走るリリース CI
で落ちます。エラーコードを検査してください。
sbt 2 の挙動が2つ、これをローカルで踏み外しやすくしています。どちらも静かに失敗します。
testは差分実行です。testQuickに委譲されるため、ソース無変更での2回目はNo tests to runと表示して終了コード 0 を返します——見た目は完全に成功です。 全件実行はtestFullです。-Dは新規サーバにしか届きません。 sbt サーバは実行間で常駐するため、enで起動済みの サーバに-Duser.language=jaを渡しても何も変わりません。java.util.Locale.getDefault()は 古いロケールを返し続けます。先にsbt shutdownしてください。
この2つが重なると、素直に sbt -Duser.language=en test と sbt -Duser.language=ja test を
続けて実行しても、「1つのロケールを1回テストしただけ」で2回 green に見えます。
CI は影響を受けません。差分実行の状態は target/ にあり、setup-java の cache: 'sbt' は
そこをキャッシュしないため、CI は毎回コールドスタートになります。
cancelled の1件は -Donion.dist.path で切られている配布物 smoke テストです。
実用的品質は、行1〜7がすべて合格したときに達成されます。 これにより、「実用的品質に到達する」という漠然とした目標を検証可能な状態に変換します。
行4 — 機能網羅性チェックリスト¶
機能は、大規模サンプル(run/)の少なくとも1つで動作したときに網羅されたとカウントされます。マイクロテストだけでは不十分です。
- records(単純)とデータを持つ enum
- 単純 enum
- コンストラクタとメソッドを持つクラス
- インターフェース + 多態ディスパッチ(FleetManager)
- トップレベルの
def(ブロック本体と式本体) - 再帰(末尾位置も含む)
- コレクションパイプライン: map / filter / fold / reduce / sortedBy / groupBy / find / distinct / partition / zip / flatten
-
select/ パターンマッチング -
if/else if式 -
while、範囲に対するforeach、Map に対するforeach(k, v) - null チェック付き nullable 型
- val に格納されたクロージャ
- 文字列補間
#{} - try / catch
- 大規模サンプルで非自明に使われるジェネリクス(
StatsApp—SafeBox[T]、Pair[A,B]、汎用countMatches) - 大規模サンプルで使われる拡張メソッド(
StatsApp、ShapeProcessor、TextAnalyzer、TodoManager)
行5 — 現在の未解決使い勝手バグ(追跡中)¶
未解決なし。
以前追跡していて解決済みのもの:
- プリミティブ型の拡張メソッド — 修正済み。
extension Int { def double(): Int = self * 2 }と(5).double()が動作します。プリミティブ受信側の拡張メソッドはボックス化されたクラス名で登録され、呼び出し時にターゲットをアンボックスしてから静的メソッドを呼び出します。 - クラスメソッドから呼ばれるトップレベル関数 — 修正済み。トップレベルの
val/varと関数は合成トップレベルクラスの static メンバーとして出力され、クラスメソッド内の裸識別子/修飾なし呼び出しはこれらの static メンバーにフォールバックします。 - 定数ナローイングがコンストラクタ引数位置に届かない。
val b: Byte = 100はナローイング されますが、Short成分に対するnew R(..., -3)はE0021(「constructor applicable for R(..., Int) is not found」)になり、(-3 as Short)が必要でした。コンストラクタでは修正済み (#374)。同じ抜け穴が通常のメソッド/関数の オーバーロード解決(Short引数に対するtakesShort(-3)がE0005になる)にもあることが 同時に見つかり、あわせて修正しました — どちらもConstantNarrowingヘルパーを共有します。