Skip to content

Proposal: iterate residues through allmods(T) instead of extending iterate on the type - #38

Draft
pankgeorg wants to merge 1 commit into
scheinerman:masterfrom
pankgeorg:fewer-invalidations
Draft

pankgeorg wants to merge 1 commit into
scheinerman:masterfrom
pankgeorg:fewer-invalidations

Conversation

@pankgeorg

Copy link
Copy Markdown

Proposal (draft). Loading Mods in a session whose sysimage contains ModelingToolkit invalidates ~4,000 compiled method instances (SnoopCompileCore.@snoop_invalidations, Julia 1.13); 654 of them come from iterate(::Type{Mod{m}}) / iterate(::Type{GaussMod{m}}). Base defines no iterate method on types, so every call site inferred as iterate(::Type) carries an edge that the first such method breaks (#37).

This replaces iterating the type with allmods(Mod{m}) / allmods(GaussMod{m}), a small iterator object owning its methods (same order; eltype is now Mod{m}). README, docs and tests updated. It is API-breaking (for x in Mod{5} no longer works), so it would need a major bump; happy to keep the old methods behind a deprecation instead if you prefer, at the cost of keeping the invalidation.

The remaining ~3,650 come from -(a::GaussMod{N}) through a Tuple{typeof(-), Number} edge; that is inherent to any Number subtype and is left alone. Not run here: the test suite.

🤖 Generated with Claude Code

…he type

Loading Mods in a session whose sysimage contains ModelingToolkit invalidated
4,032 compiled method instances (measured with SnoopCompileCore on Julia 1.13):
654 of them from `iterate(::Type{GaussMod{m}})`. Base has no `iterate` method
on `Type` arguments, so every call site that inference saw as `iterate(::Type)`
was compiled against an empty method set and carries an edge that the first
`iterate(::Type{...})` method breaks.

`allmods(Mod{m})` / `allmods(GaussMod{m})` return a small iterator object that
owns its `iterate`, `length` and `eltype` methods, so defining them cannot
intersect any existing call site. The element order is unchanged; `eltype` is
now the residue type (a generator would give `Any`). Iterating the type itself
is removed rather than deprecated: keeping the old methods would keep the
invalidations.

Not changed: the unary `-(a::GaussMod{N})` (3,656 of the 4,032) is reached
through a `Tuple{typeof(-), Number}` method-table edge recorded by
`Broadcast.combine_eltypes`, which any new unary minus on a `Number` subtype
hits; there is no signature a `Number` subtype can use that avoids it. The
`promote_rule` methods (75) are the sanctioned extension point and are left
as they are.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant