ADR-51: 単独時刻リテラルと標準糖衣 at——日集合への壁時計時刻の付与
判断: 字句に単独時刻リテラル Thh:mm(:ss(.f+)?)?(日付部を持たない壁時計時刻)を追加し、
stdlib(Gregorian 公開語)に糖衣 at(a) : Stream -> Stream(a は単独時刻リテラル)を置く。
展開は壁時計正準形の機械的差し込み:
at(a) = s => (everyInstant |> strideBy(1d, from: a)) |> filter(t => coincides(s, day, t))
(発端=還流第 12 便 B-1・収蔵 13: 供給側の配信系全定義とレシピカタログ 31 本規模が経過算術形
〈snapTo(day) |> shift(+H, unit: hour)〉で書かれ、F76 の取り違え面と horizon-clip 警告
〈発火点数分〉の運用報告。候補設計 draft §1.32=4 視点並列検証〈条件付き支持 4/4〉・設計者裁定
2026-08-21〈案 C〉を経た ADR 化)。
- 動機の較正: 「その日の H 時」は壁時計概念で、窓単位 shift は経過時間意味論(F76——DST
切替日にずれる。06 §6.1 の実測)。壁時計正準形(tick+coincides)は書けるが 2 段で、末尾
1 段の経過形に利便で負けていた——正準形を最短形にする(F1 標準糖衣の系。ADR-41 却下案が
「糖衣
dailyAt(09:00)級が将来この字面を回復する余地は残す」と留保した席の実現)。 - 単独時刻リテラルの意味論: 値は日内時刻。
strideBy(1d, from:)の位置でのみ時点に 具現する——epoch 錨日 1970-01-01(在圏 tz)で錨打ちした壁時計 tick の起点になる。 1970-01-01 錨の根拠: (a) 現行 tzdb 全ゾーン悉皆で 1969-12-30〜1970-01-04 に DST 遷移なし (錨打ちが隙間/重複に落ちる tz は無い)(b) 第 1 tick=錨自身なので帯 [紀元, 錨) の欠落が ゼロ(1970-01-02 案は評価域初日の点が黙って落ちる実測により棄却——候補設計検証)。錨打ちは 日時リテラルと同じ厳格規約(万一の非一意は明示エラー)。クロス tz 実行下限の防御は錨日選びで なく F107 型(windowFloorOf)の領分。 - 他の位置は静的エラー(誘導つき): 点位置(stride の from:・比較の錨等)は「日付つきの
日時リテラルで錨を明示する」誘導。strideBy でも市民 1d 以外の幅は静的エラー(位相が黙って
epoch 日に固定される罠の防止=ADR-31「錨必須」の精神)。等値
==は日内時刻の一致。 - T 接頭形限定: 裸
hh:mmは現行合法式(三値cond ? 10:30=数値・:・数値)の意味を 変える互換破壊のため採らない(実測で確認)。T\d\d:まで見えたらこの字句の領域で、malformed は誘導つき字句エラー(黙って識別子に落とさない)。時刻部の域検査は日時リテラルと同一 (うるう秒は表現しない=ADR-33)。用語: 従来「時刻リテラル」と呼ぶことのあった時刻付き 日付リテラルとは区別する(glossary の言い換えと対)。 - DST は展開先の規定を継承: at は糖衣(展開=機械的差し込み・ADR-23/spec §4.8)ゆえ、 隙間日は F81(ADR-31 改訂 2)の「隙間明けの最初の瞬間へ繰り下げ」・重複日は「最初の出現」—— 独立の規約を持たない。明示エラー化の検討は候補設計検証で却下(糖衣原理の破れ・同位相 anchor grid との出力乖離=ADR-36 同一視の虚偽化・DST 圏で「毎日 02:30」が年 1 回死ぬ表現力 退行、の三重)。「名指しは厳格・導出は規約」(09-dst §9.3)の確立規範どおり。
- 警告面の帰結: 展開形は単位窓列を実体化しない(tick は評価範囲内のみ生成・coincides は 値述語)——経過算術形の horizon-clip(実体化域照合・ADR-37 判断 8)の経路が存在しない。 乗り換えで消えるのは末尾形の分で、マーカー準備側 snapTo の端の数点は残る(無害・既知動作)。
- 隣接需要は直交合成で閉じる: 「前日 23:00」=
shift(-1, unit: day) |> at(T23:00)(日の調整は日の層・時刻付与は at の層)。sub-hour(T07:30)は F81 の壁時計オフセット 保存で規定済み。 - 名は
at(glossary・reference・stdlib の全数で衝突ゼロ確認)。dailyAtは生成子誤読 (年 5 回の入力に「毎日」)・atTimeは T 接頭と二重表現で不採。anchor 引数形(候補設計 案 Bat(2026-01-01T17:00))は不採を明記——単発時点への能動的誤読と、チップ・雛形経由で 魔法の日付が定義文面に露出する害(「定義が読める」価値の毀損)。
経緯: 還流第 12 便 B-1(収蔵 13・2026-08-21)→回答書で利用側糖衣 1 本の実測→需要記録→裁定 「候補設計着手」→draft §1.32(案 A 文書のみ/B anchor 引数/C 時刻リテラル)→4 視点並列検証 (条件付き支持 4/4——DST 明示エラー案の撤回・錨 1970-01-01 への訂正・T 接頭限定と互換保持の 実測・eq 分岐の急所)→設計者裁定「案 C」→実装(字句+値+strideBy 受け皿+stdlib 糖衣 1 行・ テスト 13 本〈互換保持の回帰込み〉・Playground 再ビルド)。
追記(2026-08-26・還流第 15 便=収蔵 16 の実装知見 5 件を受けて。裁定=設計者・同日):
- 標準糖衣 at に名指し検査 2 本を追加——展開形は入力
sを(点の集合でなく)述語として 読み直すため、入力が運んでいた窓・覆域註釈のかかった点・endless の由来が出力へ引き継が れない(第 15 便 (a)(b)(e) の共通根・当方 impl で全件再現)。うち「利用者が黙って誤結果を得る」 2 形を展開前に塞ぐ:- (a) 窓付き入力は誘導つき静的エラー——1 段挟むだけで ADR-49 判断 6 の窓ガードが素通りし
通し数え/選択子の I4 型エラーに化けるため。正道は「窓は at の後で切る」
(
… |> at(Thh:mm) |> within(…)——外延同値を実測で確認・第 15 便の一致表)。 - (c) 引数は単独時刻リテラルに限る静的検査——判断 8 が不採を明記した anchor 引数形
(日時リテラル)に加え裸の日付リテラルも型が通ってしまい、前方専用の錨より前の点が
黙って空になっていた(第 15 便の新規発見)。誘導は「日の調整は日の層で
(
shift(±k, unit: day) |> at(Thh:mm))」=判断 7 の直交合成。 - 検査は標準語彙の名の防御(calendar-system 側で解決された
atに掛かる)——利用側 premise の同名再定義には掛からない。糖衣原理(ADR-23=展開は機械的差し込み)の例外では なく、展開前の引数・入力の適格性検査(strideBy の「市民 1d 専用」検査〈判断 3〉と同じ層)。
- (a) 窓付き入力は誘導つき静的エラー——1 段挟むだけで ADR-49 判断 6 の窓ガードが素通りし
通し数え/選択子の I4 型エラーに化けるため。正道は「窓は at の後で切る」
(
- 判断 6 の括弧書きの訂正——「(tick は評価範囲内のみ生成・coincides は値述語)」の前半は
参照実装の事実と合っていなかった(strideBy の市民 1d tick は epoch 錨から計算範囲
〈to+400 日〉まで生成される——第 15 便 (d) の実測・impl で確認)。判断 6 の主文
「展開形は単位窓列を実体化しない——実体化域照合(ADR-37 判断 8)の経路が存在しない」は
そのまま真で、horizon-clip が出ないことの論拠はこちら。括弧書きは規範でなく理由の説明であり、
tick 生成域の絞り込み(評価範囲近傍からの生成・範囲外シグナル構築の軽量化)は実装最適化の
余地として 1.0 後の課題(第 15 便 (d) が支配項=
OutOfCoverageSignal構築の profile 実測とError.stackTraceLimit局所化の是正例を提供済み)。 - (e)(覆域外の点が at 段で落ちる)と (b)(endless 由来の警告偽陽性・segmentBy(labels:) の 静的エラー)は規約の内——「覆域外を落として註釈」は filter の規約(ADR-37 判断 6)どおりで、 糖衣は展開先の意味を継承する(判断 5 の DST と同じ原理・at の内部 filter を規約の外に置く 特別扱いはしない)。endless の素通しも filter の正しい保守近似(ADR-52 判断 7 の take 修正は 「出力が静的に ≤ n」という take 固有の性質によるもので、filter に同種の性質はない——述語の 意味解析なしに出力の有限性は立たない)。ともに reference/at.md の落とし穴へ実測込みで文書化。