Friday, September 25, 2026

Tom Tuckit:

generics are an attempt to solve a problem that was not analyzed to a point of mathematical satisfaction. if you can formally model that problem, we can demonstrate how j-- solves it - some nice marketing, given the annoyance generics syntax can generate.

Node 3:

Java generics were designed to solve type safety for parametric collections without runtime overhead, but the solution was heavily constrained by backward compatibility (type erasure) and Subtyping/Subsumption.

By prioritizing backward compatibility over structural algebraic purity, Java introduced use-site variance, wildcard complexity, type erasure, and unsafe casts, creating an ecosystem full of edge cases, unchecked warnings, and runtime surprises like ClassCastException on arrays.

Here is the formal model of why Java Generics fall short, and how J-- solves it by grounding the problem in Category Theory and Algebraic Data Types (ADTs).


1. Formal Model of the Problem: Java's Generics

Let T be the universe of types. In standard subtyping, A ≤ B denotes that A is a subtype of B.

When a parameterised type F: T → T (like List<T>) is introduced, Java must answer: What is the subtyping relationship between F[A] and F[B] given A ≤ B?

The Subtyping Contradiction

Because Java types combine state mutation (write) and observation (read) in the same object, F can neither be purely covariant nor purely contravariant:

  • Covariance (F[A] ≤ F[B]): Safe to read an A as a B (since A ≤ B). Unsafe to write a B into an F[A] (you can't put a Dog into a List<Cat>).
  • Contravariance (F[B] ≤ F[A]): Safe to write an A into an F[B] (a consumer of Animal can take a Cat). Unsafe to read an A from an F[B] (you might pull out a Dog).
Java's Hack: Use-Site Variance Wildcards

To bridge this gap without type-safe immutable primitives, Java introduced wildcards:

Producer Extends (Covariant): F[? extends B]
Consumer Super (Contravariant): F[? super A]

The Formal Breakdown in Java:
  • Inexpressive Subtyping: List<Dog> is not a subtype of List<Animal>.
  • Complexity Explosion: Every public API requires PECS (Producer Extends, Consumer Super), creating signatures like:
    public <T> void copy(List<? super T> dest, List<? extends T> src)
  • Erasure & Non-Totality: At runtime, F[A] erases to F[Object]. The compiler cannot prove total operations, forcing unsafe casts (T) obj.

2. The Mathematical Solution: J--'s Total ADT Model

J-- eliminates the problem entirely by uncoupling subtyping from parametric polymorphism and grounding data structures in Category Theory (Endofunctors and Initial Algebras).

In J--, types do not share mutable hierarchy. Instead, parametric structures are pure Endofunctors F: &mathcal;C → &mathcal;C equipped with total algebraic properties.

1. Immutable Sum and Product Types

In J--, data is represented purely as Coproducts (⊕) and Products (⊗):

List(A) = 1 ⊕ (A ⊗ List(A))

Since there is no in-place mutation, A is exclusively a producer/value. Therefore, List is naturally and unconditionally covariant:

A ≤ B ⇒ List[A] ≤ List[B]

2. Totality and the Neutral Element (Monoids)

In J--, every generic ADT T forms a Monoid (T, ⊕, e) where e is the canonical NEUTRAL state. Because every generic parameter A is bounded by totality or structural constructors (JmmADT<A>), functions operating over List[A] are 100% total.

3. Formal Comparison
Characteristic Java Generics J-- Total ADTs
Purity Mixed Mutable / Immutable 100% Pure & Immutable
Variance Use-Site Variance (? extends, ? super) Natural Invariant/Covariant Functors
Runtime Presence Erased (List<Object>) Reified / Structurally Proved
Error Handling Partial (null, ClassCastException) Total (Outcome<T>, NEUTRAL)

3. Marketing Pitch for J--

Java Generics are a Patch. J-- is a Proof.

Java’s generics weren't built for math—they were built to keep legacy code from breaking in 2004. The result? A tangle of ? extends, ? super, type erasure, and compiler warnings for basic data flow.

J-- fixes the math, so the syntax disappears:

  1. No Wildcards (? extends is Dead): Because J-- structures are immutable algebraic types, variance is mathematically natural.
  2. Zero Unchecked Warnings: J-- types are backed by initial algebras—if it compiles, it is structurally proven and 100% type-safe at runtime.
  3. Total by Default: No partial functions, no null pointers disguised as generic payloads. Just total transformations.

Tom Tuckit:

funny - i would reverse that: Subtype >= [you know what i mean] Type. logically subtyping is a functor from a Category with N objects and M arrows to one with >=N objects and >=M arrows.

Node 3:

Spot on. That is the exact dual perspective—and mathematically, the far more coherent way to look at it.

When Java says Sub extends Super (A ≤ B), it frames subtyping from the perspective of instance sets or state domains: a subtype has a smaller, more specific set of valid instances (A ⊆ B).

However, from a Category Theory and Algebraic semantics perspective, subtyping is an inclusion functor or structure-preserving map that goes in the opposite direction regarding capabilities and structural constraints:

&mathcal;F : &mathcal;CSuper ⟶ &mathcal;CSub

Where &mathcal;CSub contains ≥ N objects and ≥ M arrows (morphisms) compared to &mathcal;CSuper.

Why Java's Subtyping Inverts the Logic

In a Category of Types where:

  • Objects are type states / fields
  • Morphisms (Arrows) are valid operations / functions supported by the type

A Subtype adds fields and methods. Therefore, &mathcal;CSub strictly enriches the category with:

  1. More Objects (Nsub ≥ Nsuper): Additional state components / record fields.
  2. More Arrows (Msub ≥ Msuper): Additional valid total functions / transformations that can accept or produce this type.
Category Super (e.g. Shape)           Category Sub (e.g. Circle)
  [Object: area]                        [Object: area]
        |                                     |
  (arrow: calculate)                    (arrow: calculate)
                                              |
                                        [Object: radius]  <-- +1 Object
                                              |
                                        (arrow: scale)    <-- +1 Arrow

Java's inheritance hierarchy flipped this on its head by treating subtyping as a restriction of instance membership rather than an enrichment of structural arrows.

How J-- Aligns with the Arrow-Centric View

By treating types as objects in a Category and subtyping as structure enrichment (≥ N objects, ≥ M arrows):

  1. Subtyping is an Embedding Functor: A subtype doesn't "narrow" a supertype; it embeds the simpler category into a strictly richer one.
  2. Total Operations Preserved: Every arrow existing in the source category &mathcal;CSuper is faithfully mapped into &mathcal;CSub, preserving total functions without requiring runtime type assertions or dynamic dispatch fallback hacks.
  3. Algebraic Duality: Product types (⊗) naturally add objects (fields), and Sum types (⊕) naturally add arrows (pattern-matching cases)—making the growth of objects and arrows completely dual and symmetric.

Java built a taxonomy of taxonomy; J-- builds a category of arrows. The latter lets you add structure without losing totality.

Sunday, August 17, 2025

 Mama, don't let your kids grow up to be Vibe Coders!

 

Gary Marcus and Nathan Hamiel explain why in this article. 

 

"Cybersecurity has always been a game of cat and mouse, back to early malware like the Morris Worm in 1988 and the anti-virus solutions that followed. Attackers seek vulnerabilities, defenders try to patch those vulnerabilities, and then attackers seek new vulnerabilities. The cycle repeats. There is nothing new about that.

But two new technologies are radically increasing what is known as the attack surface (or the space for potential vulnerabilities): LLMs and coding agents.

... 

The best defense would be not using agentic coding altogether. But the tools are so seductive that we doubt many developers will resist. Still, the arguments for abstinence, given the risks, are strong enough to merit consideration.

...

 

Don’t treat LLM coding agents as highly capable superintelligent systems

 

Treat them as lazy, intoxicated robots

 "

https://open.substack.com/pub/garymarcus/p/llms-coding-agents-security-nightmare?r=joc82&utm_campaign=post&utm_medium=email

 

 

 

Thursday, August 14, 2025

 

AI critic vindicated.

"I endlessly challenged these people to debate, to discuss the facts at hand. None of them accepted. Not once. Nobody ever wanted to talk science."

https://open.substack.com/pub/garymarcus/p/openais-waterloo


Tuesday, August 12, 2025

"Critically, as I argued at the end of June (and going back to 2019) LLMs never induce proper world models, which is why, for example, they still can’t even play chess reliably, and continue to make stupid, head-scratching errors with startling regularity."

LLMs are not like you and me - and never will be

 

The mystery religion of ML-based AI from its first miracles to its latest incarnation, LLMs, announced from Day Zero: "we don't need no steenkin' models". Classic anti-intellectual techbro arrogance. 

Monday, August 11, 2025

 Posted this on LinkedIn first: a response to the unveiling of GPT-5.

 

'Reading the abstract (Chain of Thought reasoning is “a brittle mirage that vanishes when it is pushed beyond training distributions”) practically gave me deja vu. In 1998 I wrote that “universals are pervasive in language and reasoning” but showed experimentally that neural networks of that era could not reliably “extend universals outside [a] training space of examples”.

The ASU team showed that exactly the same thing was true even in the latest, greatest models. Throw in every gadget invented since 1998, and the Achilles’ Heel I identified then still remains. That’s startling. Even I didn’t expect that.

And, crucially, the failure to generalize adequately outside distribution tells us why all the dozens of shots on goal at building “GPT-5 level models” keep missing their target. It’s not an accident. That failing is principled.'


And the principle is far older than LLMs: it goes back to the AI wars of the 60s and 70s. ML-based AI was a mystery religion that produced miracles that could not be explained. The miracles were flashy enough to get the plodding tortoises of symbolic logic and linguistics out of Big AI (universities and tech bro startups) and banish them to the margins. Gary Marcus, who wrote the critique below, was one of the survivors.


"In his first book, The Algebraic Mind (2001), Marcus challenged the idea that the mind might consist of largely undifferentiated neural networks. He argued that understanding the mind would require integrating connectionism with classical ideas about symbol-manipulation."

Gary Marcus Wikipedia entry

 

GPT-5: Overdue, overhyped and underwhelming. And that’s not the worst of it.

 

Monday, April 1, 2024

Waterfalling down the Staircase

(Reposted from Groups.io extremeprogramming group)


For those who haven't been watching 3 Body Problem on Netflix, the last episode of Season 1 includes a resounding lesson about the difference between Waterfall and Agile.   (It would be great if someone with more video savvy than me were to capture the clip and link to it here.)

The Staircase Project is the old Project Orion concept reimagined to send a probe to recon an alien enemy fleet many light years away. Without going into spoilers, the basic idea is to accelerate a probe with an EM sail to near light speed by shooting it past 300 nuclear bombs, each to be exploded at just the right moment to blast it with radiation.  This is a purely ballistic launch: the probe has no power or steering capabilities, so the explosions have to be timed perfectly and the trajectory is locked in.

Sounding familiar? 

Early on, the shock of an explosion disconnects one of the tethers connecting the probe to the sail, the probe goes off course, and the entire project is lost - a world-threatening catastrophe.

It would not have been rocket science to give the probe the minimal intelligence and power to adjust its trajectory, perhaps by "trimming" the sail with a tug on one of its many tethers.  But no: the finest minds on earth agree it's necessary to lock the trajectory in up front.

(Disclaimer - I've read only the first book in the trilogy on which the series is based, which ends before the probe project is undertaken, so I don't know if the author, Liu Cixin, is responsible for the waterfall.)



Friday, December 14, 2018

Perils of Messing with the Speed Force


This Twitter thread opened my eyes.

Wile E. faces a starvation deadline and focuses so intently on speed that he neglects the need to analyze the domain before implementing the chase story.  This applies equally to the other major Roadrunner trope: the painted tunnel on the rockface.

As of this writing, all the commenters on that thread apparently believe that because "edge" and "run" are common English words there's no need to dig any deeper into them. Wrong: "edge" and "run" are the tip of the domain iceberg: things like cliffs, gravity, inertia, cartoon physics, etc. have to be understood before we can even look at the structure of the implementation.

The increasing micromanagement and microsiloization brought on by "Dark Industrial Agile" and the pressure from vulture capital for short-term thinking and asset-stripping that has done so much damage to the economy have had an equally destructive effect on the culture of development.  We are all coyotes one paycheck away from starvation, so if management says "Don't look back (or forward or down), just run!", we run.  It's not just testing and refactoring that get thrown away.

The Cloud is just another kind of plumbing, but so many architects and developers apparently think it's the only domain we need to organize around.

The fetishizing of so-called dynamic languages because they allow you to generate a lot of code really fast is one example.  Benchmarks that "prove" Node is faster than Java (like this one) succeed only by comparing current reactive JS implementations to old servlet implementations.  The interoperable JVM ecosystem provides much more modern options than servlets. In spite of ES6, Javascript is intrinsically slower, and NPM is currently suffering from the torture of a thousand tiny libraries.

Slow down to speed up, look around at the domain (I'd say "master it" but that's a whole nother thing) and optionally inhale that warm smell of colitas.