ADR-35: カレンダー実体の宣言——予約公開語を持つ premise と軸位置の規約
判断: calendar: メンバーに与える実体(TSE・JPCal 等)の宣言と参照を次のとおり確定する
(draft §1.19 の候補設計=レビュー承認済み(2026-07-07)の ADR 化。F10 の宣言構文と F53 の型規約を
ここで確定し、F52/F54 の裁定を取り込む)。
-
実体は premise そのもの=予約公開語
nonWorking(仮称・F51)を持つ premise。専用構文は 設けない(新構文ゼロ)。「ストリーム束縛+source:/asof:」を束ねる構文は premise 定義(§3.2)と 層またぎ規則(ADR-26)で既にあり、カレンダー実体に固有なのは「どの束縛が非稼働集合か」の指名 だけだからである。premise TSE { calendar-system: Gregorian # weekday の解決に要る(satSun の定義) tz: "Asia/Tokyo" # 非稼働「日」がどの市民日かを確定(内側固定・ADR-33 判断 10) source: "jpx.co.jp/trading-calendar" asof: 2026-01-05 satSun = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun) holidays = [2026-01-01, 2026-01-12, …] covering: 2026..2026 nonWorking = satSun | holidays # 予約公開語(仮称)=実体の「正体」 } - 型要件は正体判定(ADR-19 の延長)。
calendar:に立てられるのは「公開語nonWorking(時間ストリーム型・引数なしの束縛)を持つ premise」だけで、持たない premise を置くと 静的エラー。暦法 premise とカレンダー premise は同じ premise 型であり、正体=公開語の相で区別する (calendar-system:との対称。ADR-16 の取り違え検出が premise 型の中の正体の違いへそのまま延長 される。逆向き——calendar-system:位置にカレンダー実体を置く誤り——も予約公開語の側で検出 する:nonWorkingを持つ premise はcalendar-system:位置に立てない。「窓語の不在」では判定 できない——暦法からの派生premise JPCal = Gregorian with { tz: …; nonWorking = … }は窓語を継承 するからで、この派生形自体は実体の自然な最短定義として合法である)。正体判定(nonWorkingの 存在・型・引数なし・下記の整列)は実体としての初回使用時——calendar:の解決・軸位置の 読み替え(判断 4)——に走る(ADR-36 の「在圏 premise の実体化ごと」と同じ層)。 正体判定は次の二点も要求する:nonWorkingは実体の tz の市民日グリッドに整列(ADR-36 の整列で day 整列)。これが「標準導出は 実体を日粒度で読む」の操作的定義であり、ADR-36 の検査と標準導出(判断 3)が矛盾なく噛み合う 根拠になる。粒度は型に含めない(F52 の裁定・2026-07-07)は維持する——半日休の非稼働時間帯・ 営業時間のような細粒度の点は、同じ実体の中の別の時間ストリーム束縛として射程内(nonWorkingだけが day 整列の予約語)。細粒度軸(bizHour級)の予約語と導出形は宿題(F67)。- 実体は
tz:を宣言する(必須)。ADR-33 判断 10 の「内側固定」の執行点は宣言時——tz:を持たない実体の日付テーブルは利用側の tz で錨打ちされ、整列検査(ADR-36)が両辺同 tz で 素通しになり F54 の防御が骨抜きになるからである(公式休日の黙った打ち直しを宣言時に封じる)。
-
bizDayの標準導出は言語が一律に規定する。在圏calendar:の実体を C としてbizDay = everyDay \ C.nonWorking相当の導出糖衣(遅延解決・§4.8 と同じ規則)。裸名
everyDayは利用側の在圏 premise で解決され (利用側の暦法・tz の日々から引く)、C.nonWorkingは C にピンされる(機構 A の修飾参照・ ADR-17)。各実体が個別に bizDay を公開する方式は採らない——導出を実体側に置くと定義がばらけ、 取り違えの検出面(本判断 2 の正体判定)が消えるからである。実体のtz:と利用側のtz:が 食い違う導出は、粒度整合の検査(ADR-36)が安全側エラーで止める(F54)。標準導出はnonWorkingの評価註釈を伝播する——covering:の外に掛かる評価は「範囲外」の出自を帯びる (ADR-15・I6。出自を落とすと祝日データの尽きた先で bizDay がeveryDay \ satSunへ黙って退化 する——この活性化は F61 の宿題で、標準導出の安全性が直結する分だけ優先度が上がる)。 -
軸位置の premise 名(F53 の規約): 軸位置——段引数
on:/unit:、前文・後置のメンバーaxis:——に premise 名 P が立ったら、(a) P がカレンダー実体であることを正体判定で要求し (実体でない premise 名は静的エラー)、(b) 「その段(またはそのスコープ)だけcalendar:を P に 上書きして標準導出bizDayを読む」と定める:roll(Preceding, on: TSE) ≡ roll(Preceding, on: bizDay) # calendar: TSE の文脈で軸位置の名前は「premise 相対に有効点ストリームへ解決される」(ADR-26・F7)——premise 名は ストリームではないから、この一行の読み替え規約が型を埋める。読み替えの先が判断 3 の標準導出 そのものなので、
on: TSEとcalendar:上書きの等価が定義から立つ(一物二義にならない)。 細則:calendar:の在圏ではbizDayは言語予約の導出名——同じスコープでのbizDayの手動束縛は 静的エラー(on: bizDayとon: TSEの等価を破り、同じ字面が二つの軸を指す取り違え面になる ため。ADR-16)。calendar:の非在圏では従来どおり自由な束縛名(既存の手動束縛の例・テストは すべてこちら側で無風)。独自軸が要るなら別名で立てる。この予約により判断 4 の等価は無条件に立つ。- 軸位置の名前の解決: 束縛(窓語・導出ストリーム)として解決できる名前は通常解決、premise 名と してだけ解決できる名前は読み替え。両方に解決できる名前は曖昧=静的エラー(ADR-17 の曖昧性 検出と同じ面——黙ってどちらかを選ばない)。
- 読み替えの波及範囲はその軸の解決だけ。段内の他の名前解決・他メンバーには及ばない
(
calendar: Cの下でaxis: Pを畳むことも最内優先の通常規則——軸だけ P 由来になる)。 - クロス tz の利用は軸位置糖衣の射程外——利用側 tz ≠ 実体 tz なら読み替え先の標準導出が
ADR-36 の検査で止まる(それが F54 の正しい挙動)。明示の導出形
everyDay \ (TSE.nonWorking |> snapTo(day))で書けるのは「chronos 上の重なりを利用側の 日界で読む」整合であって、「同じ日付ラベル」の整合ではない(ADR-36 帰結・F69)。どちらを 意図しているかを書き手に選ばせるのが検査の目的である。
図解(2026-07-13 追補・判断 2/4 の解決経路——判断内容の変更なし。spec §3.9 と同図):
flowchart TD X["軸位置の名前 X(on: / unit: / axis:)"] X --> B{"束縛(ストリーム)として解決できる?"} B -- "はい" --> C{"premise 名としても解決できる?"} C -- "はい" --> AMB["曖昧=静的エラー(黙って選ばない)"] C -- "いいえ" --> S["通常解決——導出ストリームが軸"] B -- "いいえ" --> P{"premise 名として解決できる?"} P -- "いいえ" --> E1["未解決=静的エラー"] P -- "はい" --> ID["正体判定: nonWorking(day 整列・引数なし)+ tz: 宣言(判断 2)"] ID -- "不合格" --> E2["静的エラー(カレンダー実体ではない)"] ID -- "合格" --> DER["読み替え: calendar: X の文脈で標準導出 bizDay を読む(判断 3/4)<br/>bizDay = everyDay \ C.nonWorking——everyDay は利用側在圏・nonWorking は C にピン"] -
版差・組織ローカルの上書きは既存の
with(§3.7)。公式実体を base にpremise MyCompany = TSE with { source: "intra.example.com/holidays" # 出所も上書き(下記・必須寄り) nonWorking = TSE.nonWorking | companyHolidays }右辺の base 参照は修飾ピン(裸名
nonWorkingは定義中の語の自己参照になるため)。派生もnonWorkingを公開するから正体判定はそのまま通る。nonWorkingを上書きする派生はsource:も 上書きする(宣言必須寄り)——黙って継承すると社内改変データが公式出所(JPX)を名乗る、まさに 出所 premise の宿題(90-open-questions)が防ごうとした混同になるため(ADR-26 の「テーブルを含む premise は source: 必須寄り」の統治を、中身を変えた派生へ延長する整理)。 -
ADR-01(カスケード)との整理: 足し戻し・反転の上書き合成は
nonWorkingの右辺で表す (§4.5 の宣言順・左結合。中国の調休はnonWorking = (satSun | holidays) \ workdaysSpecial)。 実体が束ねるのは合成の結果であり、「濾過の残余」(ADR-01 の却下案)への退行ではない—— 濾過は標準導出の最終段(everyDay \ …)にだけ現れ、そこへ至る合成が ADR-01 のカスケードを担う。 ADR-20(I8)との整理: 標準導出は変換の合成に付いた名(導出ストリーム・ADR-26/F7)であって 生成子ではない——ADR-20 が却下した「カレンダー依存の生成子の第一級化」とは別物である。 カレンダー依存が結合子(差\)から式に入るのは ADR-26 の既定路線であり、本 ADR は その代表形に名を与えただけ(I8 の「カレンダー依存はフィルタ・点変換以降」の列挙には 結合子も含めて読む——字面の補正は帰結で行う)。 -
socket とは直交:
holidaysの右辺はテーブルリテラル(ADR-26)でも将来の外部供給宣言external(kind:, source:)でも良い。実体宣言は持ち込み口の形に関知しない。 - 統治は要求駆動で従来どおり: 実体 premise 自身は
calendar:を要求しない(§3.3 の静的エラーは 「解決できないのに使う」とき)。実体内の束縛が bizDay 系の軸を使えば自己のcalendar:を要求し、 自己・相互の循環(Q.nonWorkingがon: R・R.nonWorkingがon: Q)は静的エラー。実体のtz:は内側に固定する(データ入り premise の規則・ADR-33 判断 10。利用側の前文は実体内の 束縛の tz を動かさない。宣言必須=判断 2 が執行点)。 member 解決規則(「解決済み値にピン」の明文化): 修飾ピン(C.word)と実体の読み替え (判断 3/4)で評価される定義の前文メンバーは定義側優先——C(と base 連鎖)が宣言する メンバーは C の値で固定し、宣言しないメンバーだけ利用側の在圏で解決する。ADR-17 の「base の 解決済み値にピン」が含意していた規則の明文化であり、tz:の内側固定はこの特例、wkst:の 遅延解決(stdlib が宣言しないメンバー)は利用側フォールバックの特例として、同じ一行に畳まれる。
背景: ADR-26 が型(「非稼働日ストリーム+出所・版」の束)だけ確定し、宣言構文は宿題だった(F10)。
40-examples 01 §1.7 で「holidays を作った後、それをカレンダーとして登録する接続が書けない」ことが
確認され、draft §1.19 で候補設計を起草・レビュー(2026-07-07)で方向承認。残っていた前提のうち
F55(TZ の定義)は ADR-33 で確定し、F53(軸位置の型規約)を本 ADR の判断 4 で埋めた。F51
(nonWorking の名)は仮称のまま確定を急がない(方法論どおり。covering: が仮称→RC2 確定を
経たのと同じ扱い。純命名=一括置換で意味論不変)。
却下した案:
- 専用宣言
calendar TSE { … }(キーワード新設)。型が字面で立つ利点はあるが、束の中身(束縛・ source/asof・名前解決)は premise と完全に同じもの。二重の宣言形は ADR-26 が専用テーブル構文を 却下したのと同じ「構文の節約」に反する。正体判定で型は立つので字面の印は不要。 calendar:に裸のストリームを渡す(calendar: satSun | holidays)。出所・版が実体から剥がれ ADR-26 の型確定(束である)に反する。名を持たない実体は組織間の共有・上書き(TSE を皆で参照する)を 壊す。nonworking:を前文メンバーに昇格し利用側 premise に直書き。メンバー(文脈値)とストリーム束縛の 層が混ざり、かつ実体が名を持てず前項と同じ共有の問題。- F53 の別案=軸位置の premise 名を P の内側文脈で導出する(P の暦法・tz で
everyDayも解決)。 実体側で自足する分かりやすさはあるが、利用側と別の日界で数えた軸が式に黙って混ざる取り違え 危険があり(ADR-16)、on: bizDay(everyDay は在圏解決)との等価も壊れて同じ字面が二義になる。 tz 不一致の安全は ADR-36 の整列検査が在圏解決のままで担保する。 - 各実体が bizDay を公開する案。判断 3 のとおり(定義がばらけ検出面が消える)。
帰結:
- spec §3.9(カレンダー実体)を新設し、§3.3 の軸解決の記述に判断 4 の一行を追記する。EBNF(§5.6)は 変更なし(実体宣言は既存の premise 定義そのもの・軸位置の premise 名は既存の name の意味規則)。
- glossary に「カレンダー実体」「nonWorking(仮称)」「bizDay(標準導出)」を追加。
- I8 の字面(「カレンダー依存は点変換・フィルタ以降」)に結合子を含める補正(spec §2.6・ domain-model §3——判断 6 の整理の明文化)。
nonWorkingは予約公開語: ユーザーが非実体の意図で同名の束縛を置くと実体と誤判定される 取り違えの芽があるため、正体判定に使う語として glossary に仮称印つきで登録し、命名の確定 (F51・純命名)まで維持する。- リファレンス実装:
calendar:メンバーからの標準導出・軸位置の premise 名(判断 4)・正体判定の 静的エラーを実装する(従来の「導出ストリームを手動で軸に渡す」代替はcalendar:非在圏の束縛 として引き続き合法)。member 解決規則(判断 8)の実装=定義評価の env に定義側 premise(base 連鎖 込み)のメンバーを上書き重ねする。公開語のメモ化キーは wkst だけでなく参照した文脈メンバー (tz 等)を含める(I6 の文脈キー——落とすと評価順序依存の綻びになる)。 - 残る宿題: F51(
nonWorkingの名の確定・純命名。予約公開語は正体判定に使う語なので、偶然の同名束縛と 衝突しにくい名を選ぶ観点を確定基準に含める)、F67(細粒度カレンダー軸の予約語と導出形——F52 裁定の 残り半分。新規)、F61 の優先度引き上げ(範囲外出自の活性化が標準導出の安全性に直結。判断 3)、 外部供給宣言 socket(スコープ外連動・従来どおり)、出所 premise の深いモデル(90-open-questions・ 従来どおり。判断 5 が浅い執行点を先に確定)。
改訂(2026-07-09・ADR-41 帰結=細粒度層の追加): 実体の予約公開語に対の opens・closes
(開場列・閉場列=営業時間の供給規約。仮称・任意宣言)を追加する(規定の本体は ADR-41)。
判断 2 の「細粒度は同じ実体の中の別の束縛」はこの対として確定(F67 解消)。統治の延長: (a) 判断 5
(nonWorking 上書き派生の source: 上書き必須寄り)は opens/closes の上書きにも適用、
(b) 判断 8 の循環検査は導出鎖(isOpen → bizOpen → C.nonWorking)越しの自己・相互参照まで延長、
(c) 対宣言の判定は with 派生の継承込み(片方だけの上書きは合法)。calendar: 在圏の予約名に
bizOpen・bizClose・isOpen(ADR-41 の標準導出)が加わる(手動束縛は静的エラー=判断 4 細則と
同じ面)。なお細粒度導出は実体相対(判断 3 の bizDay=利用側相対と役割が違う——対比は ADR-41
判断 3・glossary)。
改訂 2(2026-07-09・純命名の確定=F51)
- 予約公開語
nonWorkingを正式名に確定(仮称解除。基準〈偶然の同名束縛と衝突しにくい名〉を 満たすと設計者裁定——26 ファイルの実戦使用で取り違えの綻びなし)。正本は spec §5.4。