Notes | Permuplate
Consistent All the Way Down
The filter and fn overloads dropped ctx from the front. The path traversal API hadn't. Every call still looked like `(pathCtx, lib) -> lib.rooms()` — the unused first argument sitting there as a re...
What the Tests Found
The session started with test coverage and ended with two things that shouldn't
ctx Is Now Optional
Three things shipped for vol2 today: 3+ source pattern execution, the chain-form `not()`/`exists()`, and ctx-optional across every builder method. The third one took most of the session.
The Outer Facts Problem
The question started simply: should `not()` and `exists()` have lambda scope? The answer required a more fundamental one first — what should a scope actually be?
Naming the Gate
There's a moment in design work where you realise the name you've been using for something is technically correct but conceptually wrong — it describes when something happens rather than what it do...
JEXL completion: building an IntelliJ language from scratch
Every `${...}` expression in a Permuplate template has been opaque since the
Cleaning house before shipping
The previous session ended with a question I'd been avoiding: are we actually improving the project each iteration, or just adding complexity for its own sake? I looked at the data — batch 10's tes...
The inference pass — six more DSL improvements
The previous entry ended with twenty features across two passes. I wasn't ready to call that done.
Twenty features, two passes, one annotation processor
The last session ended with 277 tests and a claim that the DSL was feature-complete.
The Bug Found Writing the Example
Four annotations had no runnable example — `@PermuteAnnotation`,
Using the Tool on Itself
I published the DSL article yesterday and immediately wanted to push further.
The DSL That Generated Itself
Type-safe fluent DSLs in Java require arity families. You need `Predicate1`
Permuplate — Getting the Example Right, Then the Tests
The website example went through three attempts before it was correct. I'm documenting them in order because the path matters.
Permuplate — Building the Tools to Build the DSL
droolsvol2 compiles. That's been the blocker since we identified the migration path a couple of days ago — ~14 files still referencing `drools-core` symbols that vol2 is removing. Someone finished ...
Permuplate — Rename Redirect for Every Element Type
The previous entry noted that rename redirect worked for classes but not for methods or fields. Shift+F6 on `join3()` inside `Join3.java`: IntelliJ renames the generated method directly. Next build...
Permuplate — The Plugin, Complete; Drools, More Complex Than Expected
The previous entry left two items open: #8 (rename from a generated file should
Permuplate — Cleaning house and finding the gap
The last session ended with three vol2 bugs logged in IDEAS.md — a naming typo, a wrong return type on `path5()`, and a broken varargs pattern in `params()`. I wanted them gone before starting the ...
Permuplate — Named Rules, Vol2 Bugs, and an Open Question
The plan going into this session was simple: finish the remaining DSL phases, confirm everything aligned with the vol2 reference, then start the real Drools migration. We got through the first two....
Permuplate — OOPath: Walking the Object Graph
OOPath is XPath for Java object graphs. A `Library` fact traverses into `rooms()`, then each room into `books()`, filtering at each step. The result — a `Tuple3` — joins back into…
The First/Second Split
Blog 007 explained the deferral: the First/Second split required G3's extends clause auto-expansion, and G3's expansion required `T+number` naming to detect siblings. Alpha naming — `A, B, C, D` — ...
Phase 1.5: Making Joins Type-Safe
Blog 007 ended honestly: the type system broke down after the first `.join()`. Every subsequent `.filter()` lambda received `Object`-typed parameters — `((Person) a).age() >= 18` instead of `a.age(...
Building the Drools DSL: When the Rubber Meets the Road
There's a specific kind of anxiety that comes when you've built a tool and it's time to use it on the thing it was built for. All the unit tests pass. The generated code looks right in isolation. But…
Overloads, Extends Clauses, and a Bug That Hid in Plain Sight
The Drools RuleBuilder DSL has a beautiful property: you can join facts not just one at a time, but in bulk. `Join1First.join(Join2Second)` takes a pre-built two-fact structure and advances you to ...
Teaching Classes to Grow: Type Parameters and Return Types
The gap analysis was blunt: Permuplate could generate interfaces with expanding parameter lists, but they were all type-erased. Every generated interface had `Object` parameters — no generics. For ...
Validation, IDE Support, and the Expression Language
One of Permuplate's design choices — the annotation string as a template expression — creates an interesting problem for the developer experience.
When APT Hits a Wall
Java's Annotation Processing Tool (APT) is powerful but has one hard constraint that doesn't show up in most documentation: it can create new source files, but it cannot modify existing ones.
Transforming the Template
Once Claude and I had basic cloning working — parse template, copy class, rename it — the question was what actual transformation means in this context.
The Boilerplate Problem
There's a file in the Drools codebase I've been staring at for years. It's the RuleBuilder — the fluent API that lets you build rule conditions in a type-safe, composable way. Each step in the chai...