deprecation: a deprecated parameter or label #46

Closed
opened 2026-10-05 21:07:14 +00:00 by orion · 7 comments
Collaborator

Context

A parameter cannot carry the deprecated clause; a renamed label is a new overload today.

Source

Acceptance criteria

  • Design the form in DEPRECATION.md
  • The checker warns at a use
  • torb lint --fix --rule deprecated moves it

Dependencies

None known.

Moved from the planning lists of the docs; the design record stays the specification.

## Context A parameter cannot carry the `deprecated` clause; a renamed label is a new overload today. ## Source - [DEPRECATION.md section 6](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/design/DEPRECATION.md#L166) ## Acceptance criteria - [ ] Design the form in DEPRECATION.md - [ ] The checker warns at a use - [ ] `torb lint --fix --rule deprecated` moves it ## Dependencies None known. _Moved from the planning lists of the docs; the design record stays the specification._
Author
Collaborator

[loop:torbscript] intake: in scope (author orion, label loop). DEPRECATION.md section 6 names the gap; the form of a deprecated parameter or label is new language surface, so refine will likely need an owner decision (design first, then checker and lint fix). No collision with CONCEPT "Open Questions" found at intake. next: refine (ready buffer is 6, so not before it drops below 2).

[loop:torbscript] intake: in scope (author orion, label loop). DEPRECATION.md section 6 names the gap; the form of a deprecated parameter or label is new language surface, so refine will likely need an owner decision (design first, then checker and lint fix). No collision with CONCEPT "Open Questions" found at intake. next: refine (ready buffer is 6, so not before it drops below 2).
Author
Collaborator

[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z

[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261022 until 2026-10-23T01:30:00Z

[loop:torbscript] claim refine by session:loop-torbscript-20261022 until 2026-10-23T01:30:00Z
Author
Collaborator

[loop:torbscript] decided by the loop: design of a deprecated parameter or label. No owner question: it is an internal language-surface choice that DEPRECATION.md section 3 already fixes the pattern for (clause with reason, replacement:, since:), and CONCEPT "Functions" says there is no overloading by parameter type, so one signature per name.

  • Premise corrected. A renamed label is not "a new overload today": a function has one signature, so renaming a parameter breaks every call that names it. The old parameter has to stay in the signature for one version, next to the new one. That is the case to deprecate.
  • Form. The same deprecated(...) clause, placed in front of the parameter inside the parameter list: fn connect(host: String, deprecated("it is called timeout now", replacement: "timeout", since: "0.4") wait: Int = 30, timeout: Int = 30). Reason first, replacement: and since: string literals, exactly as in section 3. The formatter puts the clause on its own line above the parameter and then breaks the list one parameter per line (rule 5 stays true in spirit). A parameter is the "label" here: its name is the label at the call, so one clause covers both words.
  • Rules. (1) The deprecated parameter must have a default, so a caller that stops passing it still compiles. (2) replacement: names another parameter of the same function with the same type; an unknown name or a type mismatch is an error at the clause, as in rule 2. (3) Passing both the deprecated parameter and its replacement in one call is an error (the call would say the same thing twice). (4) Variadic, var, lazy and receiver-closure parameters cannot be deprecated in this step (their meaning comes from the parameter, a relabel cannot stand in).
  • Warning. A call that passes the argument by label, or by position, is a use: warning "connect(wait:) is deprecated since 0.4: " with the note naming the replacement. Same exceptions as section 3 (the declaring file, a deprecated declaration, no pattern). --deny deprecated covers it for free.
  • Lint fix. torb lint --fix --rule deprecated rewrites the label wait: to timeout: where the argument is labeled. No fix for a positional use (moving it would reorder arguments) and none when the replacement is already passed.
  • Not in this step. torb doc JSON/page entry and the language server tag for parameters: DEPRECATION.md section 5 gets a sentence that they follow, no code here. A deprecated label of a tuple or a case field is not covered (a tuple label is documentation only, CONCEPT).
[loop:torbscript] decided by the loop: design of a deprecated parameter or label. No owner question: it is an internal language-surface choice that DEPRECATION.md section 3 already fixes the pattern for (clause with reason, `replacement:`, `since:`), and CONCEPT "Functions" says there is no overloading by parameter type, so one signature per name. - **Premise corrected.** A renamed label is not "a new overload today": a function has one signature, so renaming a parameter breaks every call that names it. The old parameter has to stay in the signature for one version, next to the new one. That is the case to deprecate. - **Form.** The same `deprecated(...)` clause, placed in front of the parameter inside the parameter list: `fn connect(host: String, deprecated("it is called timeout now", replacement: "timeout", since: "0.4") wait: Int = 30, timeout: Int = 30)`. Reason first, `replacement:` and `since:` string literals, exactly as in section 3. The formatter puts the clause on its own line above the parameter and then breaks the list one parameter per line (rule 5 stays true in spirit). A parameter is the "label" here: its name is the label at the call, so one clause covers both words. - **Rules.** (1) The deprecated parameter must have a default, so a caller that stops passing it still compiles. (2) `replacement:` names another parameter of the same function with the same type; an unknown name or a type mismatch is an error at the clause, as in rule 2. (3) Passing both the deprecated parameter and its replacement in one call is an error (the call would say the same thing twice). (4) Variadic, `var`, `lazy` and receiver-closure parameters cannot be deprecated in this step (their meaning comes from the parameter, a relabel cannot stand in). - **Warning.** A call that passes the argument by label, or by position, is a use: warning "`connect(wait:)` is deprecated since 0.4: <reason>" with the note naming the replacement. Same exceptions as section 3 (the declaring file, a deprecated declaration, no pattern). `--deny deprecated` covers it for free. - **Lint fix.** `torb lint --fix --rule deprecated` rewrites the label `wait:` to `timeout:` where the argument is labeled. No fix for a positional use (moving it would reorder arguments) and none when the replacement is already passed. - **Not in this step.** `torb doc` JSON/page entry and the language server tag for parameters: DEPRECATION.md section 5 gets a sentence that they follow, no code here. A deprecated label of a tuple or a case field is not covered (a tuple label is documentation only, CONCEPT).
Author
Collaborator

[loop:torbscript] refine: ready. Goal: a parameter can carry the deprecated(...) clause; the checker warns at a use and torb lint --fix --rule deprecated renames the label to the replacement (design decided in the comment above).

Implements: DEPRECATION.md section 6, "A deprecated parameter or label" (to be moved into section 3/5 by this PR).

Acceptance criteria (testable, as checker/lint/parser tests)

  • DEPRECATION.md: section 3 gains the parameter form and its rules (default required, replacement: is another parameter of the same type, both passed is an error, excluded parameter kinds), section 5 states the lint fix and that torb doc/torb lsp follow; the open entry in section 6 is replaced by what stays open.
  • Parser: deprecated("why", replacement: "p", since: "0.4") name: T = d in a parameter list parses; the formatter prints the clause above the parameter; torb format --check is stable on the result. A parameter named deprecated still parses.
  • Checker errors with a message: no default, unknown or mistyped replacement:, both parameters passed in one call, clause on a variadic/var/lazy parameter.
  • Checker warning at a call that passes the deprecated parameter (by label and by position), none in the declaring file or in a deprecated declaration, one 3 files, no problems, N warnings count; torb check --deny deprecated turns it into a problem.
  • torb lint --fix --rule deprecated rewrites wait: 5 to timeout: 5; no fix for a positional use or when the replacement is already passed; the finding stays.
  • Tests for each point above next to the existing deprecation tests; gates a (and b where CLAUDE.md asks) green in forge CI.

Seed touch: no. It is a syntax addition (parser, formatter), but the compiler's own source does not use the new form, so there is no migration commit and no seed refresh (the two-commit rule applies only when the compiler source adopts it).

Size: one PR, two Conventional Commits: (1) feat(checker): deprecated parameter (design record, parser, formatter, checker rules and warning, tests); (2) feat(lint): rename the label of a deprecated parameter (fix, tests, regenerated skills/ if docs change). No split, no new issue (and gate.on is false, nothing needed).

Tokens (RE worker, approx.): ~45k.
next: implement

[loop:torbscript] refine: ready. Goal: a parameter can carry the `deprecated(...)` clause; the checker warns at a use and `torb lint --fix --rule deprecated` renames the label to the replacement (design decided in the comment above). **Implements:** DEPRECATION.md section 6, "A deprecated parameter or label" (to be moved into section 3/5 by this PR). **Acceptance criteria (testable, as checker/lint/parser tests)** - [ ] DEPRECATION.md: section 3 gains the parameter form and its rules (default required, `replacement:` is another parameter of the same type, both passed is an error, excluded parameter kinds), section 5 states the lint fix and that `torb doc`/`torb lsp` follow; the open entry in section 6 is replaced by what stays open. - [ ] Parser: `deprecated("why", replacement: "p", since: "0.4") name: T = d` in a parameter list parses; the formatter prints the clause above the parameter; `torb format --check` is stable on the result. A parameter named `deprecated` still parses. - [ ] Checker errors with a message: no default, unknown or mistyped `replacement:`, both parameters passed in one call, clause on a variadic/`var`/`lazy` parameter. - [ ] Checker warning at a call that passes the deprecated parameter (by label and by position), none in the declaring file or in a deprecated declaration, one `3 files, no problems, N warnings` count; `torb check --deny deprecated` turns it into a problem. - [ ] `torb lint --fix --rule deprecated` rewrites `wait: 5` to `timeout: 5`; no fix for a positional use or when the replacement is already passed; the finding stays. - [ ] Tests for each point above next to the existing deprecation tests; gates `a` (and `b` where CLAUDE.md asks) green in forge CI. **Seed touch: no.** It is a syntax addition (parser, formatter), but the compiler's own source does not use the new form, so there is no migration commit and no seed refresh (the two-commit rule applies only when the compiler source adopts it). **Size:** one PR, two Conventional Commits: (1) `feat(checker): deprecated parameter` (design record, parser, formatter, checker rules and warning, tests); (2) `feat(lint): rename the label of a deprecated parameter` (fix, tests, regenerated `skills/` if docs change). No split, no new issue (and `gate.on` is false, nothing needed). Tokens (RE worker, approx.): ~45k. next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T04:17:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T04:17:00Z
Author
Collaborator

[loop:torbscript] implement: PR #399 is open with two commits (feat(checker): deprecated parameter, feat(lint): rename the label of a deprecated parameter), CI green on 624f143f (gates, bootstrap linux-x64, tier A, commit messages). Built as decided: clause on its own line in front of the parameter, the four rules, warning by label or position with the replacement note, --deny deprecated, lint fix renames the label. torb doc and the language-server tag for parameters are recorded as following (DEPRECATION.md sections 5 and 6). Local checks: deprecation tests 45/45, format tests 76/76, docs check --no-snippets and docs skill --check clean (the docs snippets run in CI). Seed touch: no. Tokens: not metered inside this subagent run, so none reported. next: review

[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/399 is open with two commits (`feat(checker): deprecated parameter`, `feat(lint): rename the label of a deprecated parameter`), CI green on 624f143f (gates, bootstrap linux-x64, tier A, commit messages). Built as decided: clause on its own line in front of the parameter, the four rules, warning by label or position with the replacement note, `--deny deprecated`, lint fix renames the label. `torb doc` and the language-server tag for parameters are recorded as following (DEPRECATION.md sections 5 and 6). Local checks: deprecation tests 45/45, format tests 76/76, `docs check --no-snippets` and `docs skill --check` clean (the docs snippets run in CI). Seed touch: no. Tokens: not metered inside this subagent run, so none reported. next: review
argus closed this issue 2026-10-22 23:30:56 +00:00
Sign in to join this conversation.
No labels
loop
ready
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#46
No description provided.