Skip to content

docs: zoning rules for arguments around the ellipsis#2757

Open
krlmlr wants to merge 2 commits into
mainfrom
claude/optional-args-ellipsis-8oje1a
Open

docs: zoning rules for arguments around the ellipsis#2757
krlmlr wants to merge 2 commits into
mainfrom
claude/optional-args-ellipsis-8oje1a

Conversation

@krlmlr

@krlmlr krlmlr commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Central PR: moving optional arguments past the ellipsis, repo-wide

Coordination point for applying the argument-migration pattern
(#2684, #2686, #2743) across all exported functions with optional arguments.
After #2779 landed the registry-split logic on main, this PR is docs-only:
the design rationale in CONTRIBUTING.md
(section Argument Order and the Ellipsis),
with pointers from AGENTS.md, tools/README.md,
and tools/migrations/README.md.

The zoning rules (summary)

Head (before ..., positional):

  1. All required arguments, data first.
    This includes functions with three or more required arguments:
    a required argument after ... would be keyword-only but still required,
    which hides it from the signature and worsens error messages.
  2. At most a few defining optional arguments — those that say what
    is computed, not how:
    the objects operated on (v in degree()),
    model parameters (power, m in sample_pa()),
    or a variant-selecting enum (type in as_adjacency_matrix()).

Tail (after ..., keyword-only): everything else, roughly ordered as
interpretation modifiers (mode, directed, weights, loops) →
output shape (normalized, names, sparse) →
algorithm/tuning (algorithm, options, callbacks) →
deprecated arguments last.

Deliberate deviation from the tidyverse design guide:
dots-after-required
puts ... immediately after the required arguments.
We allow a small head of defining optional arguments because idiomatic
positional calls (degree(g, 1:3), sample_pa(100, 1.5)) are pervasive in
20 years of scripts, books, and teaching material; deprecating the idiomatic
form would create warning noise without a safety benefit.
The safety value of keyword-only arguments lies in the long tail of options.

Invariants of the sweep:

  • No behavior changes: defaults stay untouched, no renames in this wave
    (renames remain expressible in the registry via the bare-symbol convention
    and can be layered per function family later).
  • Old positional/abbreviated calls keep working through the generated
    ARG_HANDLE recovery, with a single lifecycle::deprecate_soft("3.0.0", …).
  • Deprecated functions are not touched.

Topic PRs (226 functions, 21 PRs)

Each topic PR is a single commit on main (the split logic landed via #2779).

PR topic functions
#2759 structural-properties (incl. components, paths) 37
#2760 games 36
#2761 make 23
#2762 layout 17
#2766 conversion (incl. adjacency, incidence) 11
#2763 centrality 10
#2768 topology / isomorphism 10
#2765 community 9
#2767 flow (incl. cohesive blocks) 9
#2770 interface / iterators 8
#2771 hrg + embedding 7
#2777 plotting / tkplot / par 7
#2764 centralization 6
#2769 cliques 6
#2772 motifs + graphlets 6
#2776 similarity / efficiency / assortativity 6
#2778 misc (foreign, sir, coloring, …) 5
#2758 trees / decomposition 4
#2773 operators / rewire 4
#2775 walks + cycles 3
#2774 bipartite + degseq 2

Not in this sweep (and why)

  • simplify(), as_undirected(), contract() — already migrated in refactor: snake_case attr-comb options & arguments, soft-deprecate dotted names #2742.
  • Deprecated functions (erdos.renyi.game(), sample_bipartite(), …) — never changed.
  • Replacement functions (E<-, vertex_attr<-, …) — value handling is special.
  • Shape-API contract functions (shapes(), shape_noclip()) — positional calls are the contract.
  • sample_correlated_gnp_pair() (p ~ permutation), lattice() (dimvector ~ dim) —
    head/recoverable prefix clashes the fix(migrations): guard against head/recoverable prefix clashes #2743 guard rightly rejects; need manual treatment.
  • ~20 functions whose optional arguments are all defining (nothing to move).
  • The trailing-pass-through-dots family (mst(), read_graph(), isomorphic(),
    local_scan(), power.law.fit(), layout_nicely(), …) — their ... forwards
    to other functions, which the recovery machinery cannot disambiguate;
    needs a dedicated design.

This was referenced Jul 26, 2026
Document which arguments go before and after `...`
in CONTRIBUTING.md (section "Argument Order and the Ellipsis"),
with pointers from AGENTS.md, tools/README.md,
and tools/migrations/README.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016M32izVHZPfxAqemAe4BrX
@krlmlr
krlmlr force-pushed the claude/optional-args-ellipsis-8oje1a branch from b94d795 to d58a8f1 Compare July 26, 2026 16:23
@krlmlr krlmlr changed the title feat: per-topic migration registries and ellipsis zoning rules docs: zoning rules for arguments around the ellipsis Jul 26, 2026
A signature with every argument behind the ellipsis
makes the function keyword-only altogether;
keep at least the primary argument positional,
or drop the ellipsis entirely.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016M32izVHZPfxAqemAe4BrX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants