In the 3.0.0 argument-migration program (#2757), ... becomes a pure
keyword-only separator: the generated ARG_HANDLE blocks own it to
recover legacy calls, and functions without recovery enforce
check_dots_empty(). Functions that forward their dots somewhere
else conflict with that design — and they already have the classic
dots problems today:
- typos and stale arguments vanish silently — worse, three live
functions forward dots into a callee that ignores them entirely, so
everything passed there vanishes (see traps below);
- no
check_dots_empty() is possible, and the migration machinery
cannot distinguish "argument for the callee" from "legacy positional
argument to recover";
- the set of accepted names is invisible in the signature and docs.
Proposal (per maintainer direction): each forwarding function gets
a dedicated options argument with its own logic — a validated named
list (constructor helpers where a family warrants them, in the spirit
of the existing options = arpack_defaults() pattern), unknown-name
errors instead of silent swallowing, and ... reserved for the
separator + recovery like everywhere else.
Affected functions (live API; complete inventory)
Layout family — forwards to a chosen layout function (21):
layout_nicely(), add_layout_(), layout_components(),
tk_reshape(), and the 17 deferred-spec wrappers
as_bipartite(), as_star(), as_tree(), in_circle(), nicely(),
on_grid(), on_sphere(), randomly(), with_dh(), with_drl(),
with_fr(), with_gem(), with_graphopt(), with_kk(),
with_lgl(), with_mds(), with_sugiyama().
Natural shape: layout_options(...) or mirroring the target's
formals in the wrapper.
Constructor-spec sugar — forwards into make_/sample_ (8):
chung_lu(), degseq(), tree(), directed_graph(),
undirected_graph(), from_literal(), from_data_frame(),
from_edgelist().
Isomorphism family — dots depend on method (6):
isomorphic(), subgraph_isomorphic(), count_isomorphisms(),
count_subgraph_isomorphisms(), isomorphisms(),
subgraph_isomorphisms().
Strongest case for "options with its own logic": the valid option set
is a function of the chosen method (vf2 / bliss / lad).
Foreign I/O — dots depend on format (2):
read_graph(), write_graph() (per-format readers/writers).
Same shape as the isomorphism family.
Statistics / conversion / misc (6):
component_distribution(), degree_distribution(),
fit_power_law() (only its "R.mle" branch forwards),
scan_stat() (→ local_scan()), print_all() (→ print options),
as.matrix.igraph() (→ as_adjacency_matrix()/as_edgelist()).
Plotting S3 (8): plot.igraph(), rglplot.igraph(), plot.sir(),
plot.communities(), plot.cohesiveBlocks(), plot_hierarchy(),
plot_dendrogram.communities(), plot_dendrogram.igraphHRG().
S3 methods must keep ... for the generic contract; the question is
whether they additionally gain an options/params argument so the
graphical parameters stop hiding in dots.
30 deprecated shims also forward dots; per policy they are never
touched and simply follow (or outlive) their targets.
Traps found while inventorying (bugs today)
chung_lu() forwards ... into sample_chung_lu(), which has
... before its own keyword args and ignores it — anything a
user passes there vanishes silently.
minimum.spanning.tree() → mst() and
graph.cohesion() → cohesion.igraph() swallow dots the same way.
make_graph()'s numeric branch does
do.call(old_graph, list(edges, ...)), so unnamed extra dots can
positionally bind the internal n/directed parameters.
Explicitly out of scope (dots are the payload, not options)
- Variadic-data functions where dots are the data (30):
make_graph(), graph_from_literal(), edge()/vertex()/path(),
add_edges()/add_vertices() (attributes), set_vertex_attrs(),
disjoint_union(), the union()/intersection()/difference()
families (dots-only dispatch), layout_() modifiers,
igraph_options(), with_vertex_()/with_edge_()/with_graph_()
(NSE), c()/[ methods on vs/es.
- User-callback forwarders where dots belong to
FUN:
local_scan(), head_print(), indent_print().
- The 17 functions already enforcing
check_dots_empty(), and pure
separators — already correct.
Questions for maintainers
Related: #2757 (program), #2780 (@param ... docs), #2788 (renames),
#2789 (defaults). No existing issue covered this space, hence no
Closes lines.
In the 3.0.0 argument-migration program (#2757),
...becomes a purekeyword-only separator: the generated ARG_HANDLE blocks own it to
recover legacy calls, and functions without recovery enforce
check_dots_empty(). Functions that forward their dots somewhereelse conflict with that design — and they already have the classic
dots problems today:
functions forward dots into a callee that ignores them entirely, so
everything passed there vanishes (see traps below);
check_dots_empty()is possible, and the migration machinerycannot distinguish "argument for the callee" from "legacy positional
argument to recover";
Proposal (per maintainer direction): each forwarding function gets
a dedicated
optionsargument with its own logic — a validated namedlist (constructor helpers where a family warrants them, in the spirit
of the existing
options = arpack_defaults()pattern), unknown-nameerrors instead of silent swallowing, and
...reserved for theseparator + recovery like everywhere else.
Affected functions (live API; complete inventory)
Layout family — forwards to a chosen layout function (21):
layout_nicely(),add_layout_(),layout_components(),tk_reshape(), and the 17 deferred-spec wrappersas_bipartite(),as_star(),as_tree(),in_circle(),nicely(),on_grid(),on_sphere(),randomly(),with_dh(),with_drl(),with_fr(),with_gem(),with_graphopt(),with_kk(),with_lgl(),with_mds(),with_sugiyama().Natural shape:
layout_options(...)or mirroring the target'sformals in the wrapper.
Constructor-spec sugar — forwards into make_/sample_ (8):
chung_lu(),degseq(),tree(),directed_graph(),undirected_graph(),from_literal(),from_data_frame(),from_edgelist().Isomorphism family — dots depend on
method(6):isomorphic(),subgraph_isomorphic(),count_isomorphisms(),count_subgraph_isomorphisms(),isomorphisms(),subgraph_isomorphisms().Strongest case for "options with its own logic": the valid option set
is a function of the chosen method (vf2 / bliss / lad).
Foreign I/O — dots depend on
format(2):read_graph(),write_graph()(per-format readers/writers).Same shape as the isomorphism family.
Statistics / conversion / misc (6):
component_distribution(),degree_distribution(),fit_power_law()(only its"R.mle"branch forwards),scan_stat()(→local_scan()),print_all()(→ print options),as.matrix.igraph()(→as_adjacency_matrix()/as_edgelist()).Plotting S3 (8):
plot.igraph(),rglplot.igraph(),plot.sir(),plot.communities(),plot.cohesiveBlocks(),plot_hierarchy(),plot_dendrogram.communities(),plot_dendrogram.igraphHRG().S3 methods must keep
...for the generic contract; the question iswhether they additionally gain an options/params argument so the
graphical parameters stop hiding in dots.
30 deprecated shims also forward dots; per policy they are never
touched and simply follow (or outlive) their targets.
Traps found while inventorying (bugs today)
chung_lu()forwards...intosample_chung_lu(), which has...before its own keyword args and ignores it — anything auser passes there vanishes silently.
minimum.spanning.tree()→mst()andgraph.cohesion()→cohesion.igraph()swallow dots the same way.make_graph()'s numeric branch doesdo.call(old_graph, list(edges, ...)), so unnamed extra dots canpositionally bind the internal
n/directedparameters.Explicitly out of scope (dots are the payload, not options)
make_graph(),graph_from_literal(),edge()/vertex()/path(),add_edges()/add_vertices()(attributes),set_vertex_attrs(),disjoint_union(), theunion()/intersection()/difference()families (dots-only dispatch),
layout_()modifiers,igraph_options(),with_vertex_()/with_edge_()/with_graph_()(NSE),
c()/[methods on vs/es.FUN:local_scan(),head_print(),indent_print().check_dots_empty(), and pureseparators — already correct.
Questions for maintainers
options = list()everywhere, or per-familyconstructor helpers (
layout_options(), per-method isomorphismoptions, per-format I/O options) with validation?
with_fr()etc.): options list,or mirror the target function's formals outright?
params/optionsargument alongside the contractual...?machinery with a soft deprecation ("passing layout parameters
through
...is deprecated, useoptions ="), so old codekeeps working through 3.x?
redesign (they are user-visible bugs regardless)?
Related: #2757 (program), #2780 (
@param ...docs), #2788 (renames),#2789 (defaults). No existing issue covered this space, hence no
Closeslines.