Not in what I just wrote, no. On Wed, Jan 28, 2026, 5:08 PM Ron Pressler <[email protected]> wrote:
> What is the problem you’re trying to point out? Is it “something that can > be expressed in Java could be expressed more elegantly”? > > I’m not saying this is a disqualified problem, but I’d like to understand > if there’s a problem here that can be stated without hinting at a specific > solution (such as "mechanism X and Y could be unified"), as in “processing > pure data in Java is cumbersome”, or “calling native code from Java is > tedious and error-prone”, or “it’s difficult in Java to clear, > debuggable/proflable concurrent code that scales well”, or “processing some > Java collections incurs many cache-misses that impact performance”, or > “propagating timeouts and cancellation across dependent tasks is > difficult”, or “correctly freeing OS resources in the presence of > exceptions is difficult” etc. (but with more elaboration, obviously). > > — Ron > > > On 28 Jan 2026, at 17:50, Ethan McCue <[email protected]> wrote: > > > > I am sympathetic because "service loader" was also what entered my mind > when thinking about "implementation of interface made magically > discoverable." > > > > Right now an implementation of interface provided via the service loader > > > > 1. Can have 0-N implementations provided > > 2. Has these provided interfaces specified in module info via "provides > ... with ...;" > > > > An implementation of an interface provided via a witness > > > > 1. Should only have 1 implementation for a type being "summoned" > > 2. Has these provided interfaces specified inside a class, in the > current prototype via "__witness" > > 3. Relies on the interface for which a witness is provided having a > generic parameter > > > > My gut feeling is that these mechanisms *could* be unified > > > > provides Formatter for List<String> with SomeClass; > > > > And that, if they aren't, we'd start to see things like > > > > summon(Logger<App>).log(...) > > > > But equally I find it hard to > > > > 1. Reason about how moving "witness registration" from classes to a > module info would affect things like witness resolution or "unconditional > provides." > > 2. Justify it beyond a vague feeling > > > > > > > > On Wed, Jan 28, 2026, 11:56 AM Ron Pressler <[email protected]> > wrote: > > The hardest part in designing and evolving a language is deciding which > problems are important enough to merit a solution in the language and how > their priorities compares to other problems. It’s the hardest part because > the language team are expert at coming up with solutions, but they may not > always know what problems people enoucnter in the field, how frequently > they encounter them, and how they work around them today. > > > > I’m sure there is some problem hidden here and in your previous post, > but it is not articulated well and is hidden in a poposed solution, even > though no solution is even worth exploring before understanding the > problem. And so the best way to get to a solution is for you to focus on > the problem and only on the problem. > > > > What was the problem you *personally* ran into? How bad were its > implications? How did you work around it? > > > > With the hard part done, the JDK team will then be able to assess its > severity and think whether it merits a solution in the JDK, if so, where > (language, libraries, or VM), and how to prioritise it against other > problems worth tackling. Then they’ll be able to propose a solution, and > that’s would be the time to try it out and discuss it. > > > > — Ron > > > > > > > > > On 28 Jan 2026, at 00:28, Steffen Yount <[email protected]> > wrote: > > > > > > The recent thread "Java Language Enhancement: Disallow access to > static members via object references" highlights a long-standing tension in > Java's handling of static members. While that thread seeks to further > decouple instance state from static logic, I would like to propose moving > in the opposite direction: "doubling down" on Java’s compile-time and > link-time static polymorphism. > > > > > > By beefing up java.util.ServiceLoader facilities and integrating its > discovery mechanism directly into the language via Static Service Traits, > we can facilitate the "Witness Object" paradigm discussed by Brian Goetz's > "growing the java language" presentation and the algebraic "well-known > interface" model for custom numeric types (like Float16) proposed in Joe > Darcy's "Paths to Support Additional Numeric Types on the Java Platform" > presentation. > > > > > > == Static Service Traits for Java == > > > > > > I propose a system of Static Service Traits. I use the term "Trait" > advisedly: this feature adopts a rigorous Coherence Model (inspired by > systems like Rust) to ensure that service resolution is not merely a > dynamic search, but a type-safe, deterministic binding of static > capabilities to types. > > > 1. The service Contextual Keyword > > > We introduce service as a contextual modifier for interface > declarations. Marking an interface as a service identifies it as a "service > type" with a contract for static capabilities and a high-performance > service provider registry. > > > > > > 2. Static Implementations and Extension Methods > > > • Static Implementations: > > > • In Interface Headers: interface MyTrait implements > ServiceX<T>. Methods are fulfilled as static. > > > • In Class Headers: class MyClass implements static > Numeric<Float16>. Methods are implemented as static on the class. Existing > signature rules prevent a method from being both a static and an instance > implementation simultaneously. > > > • Static Extension Methods: Desugared at the call site. > myInstance.method() becomes MyClass.method(myInstance). Notably, if > myInstance is null, it desugars to MyClass.method(null) without an > immediate NullPointerException. > > > • Ergonomic Aliases: To simplify signatures, we introduce private > nested static type aliases This and Super (e.g., static This add(This a, > This b)). > > > > > > 3. Operational Mechanics & Link-Time Integration > > > A ServiceLoader Controller is integrated into the JVM’s class-loading > pipeline. During class definition, the Controller eagerly extracts all > relevant metadata to populate the Static Service Provider Registry, > including: > > > • Header-level static implements and implements declarations. > > > • Service binding descriptors from module-info.class. > > > • META-INF/services/ provider-configuration files. > > > Hierarchical Precedence Resolution: To ensure deterministic binding, > the Controller resolves call sites to their most specific service provider > via a waterfall dispatch model: > > > • Tier 1: Type Specialization: Most specific generic match wins, > applying the same scrutiny and rules currently used for existing static > overloaded method resolution. > > > • Tier 2: Physical Locality: Provider in the same file > (.jar/.class) as the caller wins. > > > • Tier 3: Loader Proximity: Nearest ClassLoader in the delegation > path wins. > > > • Tier 4: Modular Topology: Internal > Explicit > java.base > > Transitive > Automatic. > > > • Tier 5: Sequential Order: Final tie-breaker via Classpath order. > > > > > > 4. Coherence, The Orphan Rule, and Quarantining > > > To achieve the type-safety of a trait system, we enforce an adapted > Orphan Rule: A module (or package on the classpath) must own either the > service interface or the target type to define an implementation. > > > • Coherence Enforcement: Violations in modular code trigger a > LinkageError. > > > • Behavioral Continuity: Violations in classpath code trigger a > load-time warning and the provider is quarantined from the Static Registry. > To ensure continuity, quarantined providers remain accessible via existing > java.util.ServiceLoader API calls, protecting legacy iteration-based > discovery while ensuring the integrity of the new link-time dispatch. > > > 5. Performance and AOT Considerations > > > This model transforms ServiceLoader into a link-time resolver. JIT > compilers can treat service calls as direct invokestatic instructions, > enabling aggressive optimization. This is highly compatible with Project > Leyden and GraalVM, as precedence can be "baked" into the binary during AOT > compilation. > > > Conclusion > > > By transitioning ServiceLoader to a link-time resolver, we provide a > type-safe, high-performance path for algebraic types and witness-based > generics. This allows Java to "grow" through libraries—fulfilling the goals > of both Darcy and Goetz—while maintaining the performance and stability > characteristics of the modern JVM. > > > > > > > > > Thoughts? > > > >
