3.0 roadmap
On this page
PurposeCompatibility policyCommitted semantic changesExplicitly preserved scopeUndecided items and decision gatesDelivery sequenceMigration guidance3.0 release criteriaこのページの目次
目的互換性の方針確定した意味論の変更明示的に維持する範囲未決定項目の判断条件実装の順序移行の指針リリース条件目的
3.0は、安定した2.xで安全に変更できない一部の実行時の意味論を修正するための互換性の境界です。jqの全機能の実装が目的ではありません。対応する言語をより予測可能にし、移植可能なフィルターに有益な範囲でjq 1.7へ近づけ、軽量なPure Perlの導入モデルを維持します。
現在の動作と判断状態は2.xの意味論の差分が基準です。この計画だけで未決定の項目を確約へ変えません。
互換性の方針
- 2.xのCLI・Library API仕様は維持します。この計画の意味論の修正は3.0で行い、2.xへ遡って適用しません。
- 公開APIの
newとrun_queryは維持します。変更対象はクエリ言語の意味論であり、エントリーポイントの形ではありません。 - 「v3で変更」の比較基準はjq 1.7です。厳密な診断文言や未対応のjq機能は保証しません。
- 既存の拡張は、別途置換と移行の提案がなければ維持します。
- 意図的な非互換には、新しい結果と移行手順の両方を確認するテストが必要です。
確定した意味論の変更
以下は3.0の互換性変更として承認された項目です。1つの大規模な構文解析の書き直しではなく、個別にレビューできる変更として実装します。
包含
contains(value)を配列・オブジェクトに対するjq形式の再帰的な包含にします。- 未決定の
contains_subset(value)は判断が済むまで2.xの動作を維持し、新しいcontainsと完全に同じ別名だと説明しません。
null、代替値、パス
//でfalseとnullの両方を代替値の対象にします。- 欠損したオブジェクトのフィールドと、その先の探索でnullを返します。
- オブジェクトへの数値添字をnullではなくエラーにします。
その他の不正なパスのエラー方針は未決定です。
算術と比較
- 算術演算の真偽値を拒否します。
- 等値比較ではJSONの型を区別し、数値に見える文字列を数値と等しいとしません。
- jq互換の値順序に基づいて配列を辞書式に比較します。
数値文字列の算術と正規表現のスカラー変換は未決定です。確定項目の副作用で変更しません。
代入と更新
- 更新代入(
|=)は更新したルート値を返します。 - jqと同じ入力の意味論で、欠損した更新先を作成できるようにします。
複数結果の代入は別の設計が必要で、未決定です。
明示的に維持する範囲
- 配列に要素ごとに適用する
floor、ceil、round、fromjsonと値を保持する関連関数。 - 配列のパス射影。
- 便利な補助関数と統計関数。
- 不揃いな行を最短行へ切り詰める
transpose。 - モジュール・importとjqのストリーミング解析モードを含めないこと。
- Pure Perlの実装とPerl 5.14以上。
反復の接尾構文、通常の代入、型間の順序、欠損値の比較は監査したjqのケースと一致しています。これらは回帰防止の対象であり、新しい3.0作業ではありません。
未決定項目の判断条件
未決定の動作を3.0へ含めるには、以下の提案が必要です。
- jq 1.7とJQ::Lite 2.xの動作例。
- 既存フィルターへの既知の互換性の影響。
- 提案する結果とエラー方針。
- 移行手順。
- 外部依存を必要としない回帰テスト。
対象は数値文字列の算術、正規表現の型変換、不正なパス、混合型の反復、複数結果の代入、未対応構文、制御フロー、contains_subsetの扱いです。未解決の項目は3.0でも2.xの動作を維持します。
実装の順序
- 基準を固定する。 2.xの差分一覧と回帰テストを維持します。
- 共通の意味論を整備する。 内部の
JQ::Lite::Valueと比較処理、続いてパス結果の処理を、公開動作を変えずに導入します。 - 変更を個別に実装する。 包含、代替値・パス、算術・比較、更新代入を別々にレビューします。
- 移行手順を公開する。 結果や失敗が変わるフィルターについて変更前後の例と代替を示します。
- リリース候補を検証する。 対応するPerl全体でテストし、確定した互換性ケースをjq 1.7と比較します。
移行の指針
2.xと3.xを1つのコードで扱う場合は、3.0を必須にできるまで変更対象の境界ケースへの依存を避けてください。更新代入の結果などは、両方で動くフィルターを末尾に足すだけでは正規化できず、バージョン別の処理が必要です。
| 2.xの動作への依存 | 3.0への安全な移行方法 |
|---|---|
| containsで配列要素・入れ子オブジェクトの完全一致を期待 | 更新前に等値条件を明示する |
false // fallbackでfalseを維持したい |
falseがデータならnull判定を明示する |
| 欠損パスで結果なしを期待 | 暗黙の除外でなくemptyや選択を明示する |
| 真偽値の算術 | 意図する数値へ明示的に変換する |
| 数値文字列と数値の等値 | 両側をtonumberまたはtostringで明示的に揃える |
| 更新代入で更新した末端値だけを期待 | 2.xは元の式を維持し、3.0を必須にした後でパス射影を加えるか、バージョン別のアプリ処理で末端値を取得する |
確定した変更ごとに実行可能な例をリリースノートへ掲載します。欠損フィールドでrun_queryが結果なしを返す前提のコードも見直してください。3.0ではJSON nullが1つ返ります。
リリース条件
- 「v3で変更」のすべてを実装するか、延期理由を明示する。
- 各変更にjq 1.7との比較テストと直接の回帰テストがある。
- 維持・未決定の項目も引き続きテストで保護する。
- CLI・Library APIの契約テストが変更なしで成功する。
- 出力・エラーの意図的な変更すべてに移行手順がある。
- 対応するPerlの範囲で配布物全体のテストが成功する。
Purpose
JQ::Lite 3.0 is the compatibility boundary for correcting selected runtime semantics that cannot change safely in the stable 2.x series. Its goal is not to implement every jq feature. It is to make the supported language more predictable, move deliberately toward jq 1.7 where that benefits portable filters, and preserve the lightweight, pure-Perl deployment model.
The current behaviour and the decision status of every known difference are
recorded in the 2.x semantic differences inventory.
That inventory is the source of truth for scope: this roadmap does not silently
turn an undecided item into a commitment.
Compatibility policy
- The 2.x CLI and Library API contracts remain unchanged. Semantic corrections listed here are 3.0 changes and must not be backported to 2.x.
- The documented public Library API (
newandrun_query) remains supported. Version 3 changes query-language semantics, not the shape of those entry points. - jq 1.7 is the comparison baseline for changes marked change in v3. Exact jq diagnostic text and unsupported jq facilities are not compatibility promises.
- Existing JQ::Lite extensions remain available unless a separate proposal documents their replacement and migration path.
- Every intentional incompatibility requires focused tests for both the new result and the migration guidance described below.
Committed semantic changes
The following inventory items are approved for the 3.0 compatibility break. They should be implemented as independently reviewable changes rather than as one parser rewrite.
Containment
- Make
contains(value)use jq-style recursive containment for arrays and objects. - Keep 2.x
contains_subset(value)unchanged until its undecided status is resolved. It must not be presented as an exact alias for the newcontains.
Null, fallback, and paths
- Treat both
falseandnullas absent for the//alternative operator. - Emit
nullfor a missing object field and for continued traversal through a missing field. - Reject a numeric index applied to an object instead of returning
null.
The error policy for other invalid paths remains undecided and is not implied by these changes.
Arithmetic and comparison
- Reject boolean operands in arithmetic expressions.
- Keep JSON scalar types distinct for equality, so a numeric-looking string is not equal to a number.
- Compare arrays lexicographically using jq-compatible value ordering.
Numeric-string arithmetic and regex scalar coercion remain undecided. Their current behaviour must not change as a side effect of the committed work.
Assignment and update
- Make update assignment (
|=) emit the updated root value. - Allow update assignment to create a missing target using the same input semantics as jq.
Multi-result assignment remains undecided and requires a separate design.
Explicitly preserved scope
The following choices continue in 3.0 unless separately reconsidered:
- vectorised
floor,ceil,round,fromjson, and related lossless helpers; - array path projection;
- JQ::Lite convenience and statistical functions;
- truncating jagged
transposebehaviour; - the absence of modules/imports and jq's streaming parser mode; and
- the pure-Perl implementation and Perl 5.14 minimum.
Iterator suffixes, plain assignment, cross-type ordering, and missing-value comparison already match the audited jq cases and are regression guards, not 3.0 work items.
Undecided items and decision gates
An undecided behaviour may enter 3.0 only after a focused proposal includes:
- examples of jq 1.7 and JQ::Lite 2.x behaviour;
- known compatibility impact on existing filters;
- the proposed result and error policy;
- migration guidance; and
- dependency-free regression tests.
This gate applies to numeric-string arithmetic, regex scalar coercion, invalid
path errors, mixed iterator pipelines, multi-result assignment, unsupported
parser syntax, control flow, and the future role of contains_subset.
Unresolved items retain their 2.x behaviour in 3.0.
Delivery sequence
- Freeze the baseline. Keep the 2.x inventory and regression tests intact.
- Build shared semantics. Use the internal
JQ::Lite::Valuetype and comparison primitives, then introduce path-result primitives, without changing public behaviour. - Land isolated changes. Implement containment, fallback/path, arithmetic/comparison, and update-assignment changes in separate reviews.
- Publish migration notes. Provide before/after examples and replacements for filters whose output or failure mode changes.
- Validate the release candidate. Run the full Perl test suite on all supported Perl versions and differential tests against jq 1.7 for every committed compatibility case.
Migration guidance
Applications that need one code path across 2.x and 3.x should avoid relying on the changed edge cases until they can require 3.0. Some changed semantics, including the result of update assignment, cannot be normalized by appending a filter that works in both major versions; those cases require version-aware application logic. In particular:
| 2.x-dependent filter | 3.0-safe migration approach |
|---|---|
contains(...) expecting exact array elements or nested object equality |
express exact equality explicitly before upgrading |
false // fallback expecting false |
use an explicit null test when false is data |
| a missing path as an empty output stream | use empty/selection explicitly rather than relying on implicit dropping |
| arithmetic with booleans | convert the boolean to the intended number explicitly |
| equality between numeric strings and numbers | normalize both sides explicitly with tonumber or tostring |
| `path | = filter` expecting only the updated leaf |
Release notes must include concrete, executable examples for each committed
change. Library consumers should also review code that assumes run_query
returns no value for a missing field; in 3.0 that query returns one JSON null.
3.0 release criteria
JQ::Lite 3.0 is ready only when:
- every change in v3 inventory row is implemented or explicitly deferred with a documented reason;
- every changed behaviour has jq 1.7 differential coverage and a direct JQ::Lite regression test;
- all preserved and still-undecided inventory rows remain covered;
- CLI and Library API contract suites pass unchanged;
- migration notes cover every intentional output or error change; and
- the complete distribution test suite passes on the supported Perl range.